/*
* Copyright (c) 2014 Sam Harwell, Tunnel Vision Laboratories LLC
* All rights reserved.
*
* The source code of this document is proprietary work, and is not licensed for
* distribution. For information about licensing, contact Sam Harwell at:
* sam@tunnelvisionlabs.com
*/
package org.antlr.works.editor.grammar.debugger;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import org.antlr.netbeans.editor.text.DocumentSnapshot;
import org.antlr.netbeans.editor.text.VersionedDocumentUtilities;
import org.antlr.netbeans.parsing.spi.ParserDataOptions;
import org.antlr.netbeans.parsing.spi.ParserTaskManager;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNDeserializer;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.ParseTreeListener;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.netbeans.api.editor.EditorRegistry;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.Lookup;
import org.openide.util.NbBundle.Messages;
import org.openide.util.WeakListeners;
import org.openide.windows.TopComponent;
/**
* Top component which displays something.
*/
@ConvertAsProperties(
dtd = "-//org.antlr.works.editor.grammar.debugger//ParserDebuggerController//EN",
autostore = false
)
@TopComponent.Description(
preferredID = "ParserDebuggerControllerTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE",
persistenceType = TopComponent.PERSISTENCE_ALWAYS
)
@TopComponent.Registration(mode = "rightSlidingSide", openAtStartup = false)
@ActionID(category = "Window", id = "org.antlr.works.editor.grammar.debugger.ParserDebuggerControllerTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(
displayName = "#CTL_ParserDebuggerControllerAction",
preferredID = "ParserDebuggerControllerTopComponent"
)
@Messages({
"CTL_ParserDebuggerControllerAction=Parser Debugger Controller",
"CTL_ParserDebuggerControllerTopComponent=Parser",
"HINT_ParserDebuggerControllerTopComponent=This is a parser debugger controller window"
})
public final class ParserDebuggerControllerTopComponent extends TopComponent {
private final PropertyChangeListener editorRegistryListener = new EditorRegistryListener();
public ParserDebuggerControllerTopComponent() {
initComponents();
setName(Bundle.CTL_ParserDebuggerControllerTopComponent());
setToolTipText(Bundle.HINT_ParserDebuggerControllerTopComponent());
jSplitPane1.setDividerLocation(0.8);
EditorRegistry.addPropertyChangeListener(WeakListeners.propertyChange(editorRegistryListener, EditorRegistry.class));
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jSplitPane1 = new javax.swing.JSplitPane();
javax.swing.JTabbedPane jTabbedPane1 = new javax.swing.JTabbedPane();
javax.swing.JPanel jPanel2 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
tblRules = new javax.swing.JTable();
javax.swing.JPanel jPanel7 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane5 = new javax.swing.JScrollPane();
tblDecisions = new javax.swing.JTable();
javax.swing.JPanel jPanel3 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane2 = new javax.swing.JScrollPane();
tblLookahead = new javax.swing.JTable();
javax.swing.JPanel jPanel5 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane3 = new javax.swing.JScrollPane();
tblConflicts = new javax.swing.JTable();
javax.swing.JPanel jPanel4 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane6 = new javax.swing.JScrollPane();
tblStatistics = new javax.swing.JTable();
jPanel1 = new javax.swing.JPanel();
setLayout(new java.awt.GridLayout(1, 0));
jSplitPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 1, 1, 1));
jSplitPane1.setDividerLocation(120);
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
jSplitPane1.setResizeWeight(1.0);
jSplitPane1.setContinuousLayout(true);
tblRules.setAutoCreateRowSorter(true);
tblRules.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null},
{null, null},
{null, null},
{null, null}
},
new String [] {
"Rule", "Instances"
}
) {
boolean[] canEdit = new boolean [] {
false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane1.setViewportView(tblRules);
if (tblRules.getColumnModel().getColumnCount() > 0) {
tblRules.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblRules.columnModel.title0")); // NOI18N
tblRules.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblRules.columnModel.title1")); // NOI18N
}
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 381, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.jPanel2.TabConstraints.tabTitle"), jPanel2); // NOI18N
tblDecisions.setAutoCreateRowSorter(true);
tblDecisions.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null},
{null, null, null},
{null, null, null},
{null, null, null}
},
new String [] {
"Decision", "Rule", "Count"
}
) {
boolean[] canEdit = new boolean [] {
false, false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane5.setViewportView(tblDecisions);
if (tblDecisions.getColumnModel().getColumnCount() > 0) {
tblDecisions.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title0")); // NOI18N
tblDecisions.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title1")); // NOI18N
tblDecisions.getColumnModel().getColumn(2).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title3")); // NOI18N
}
javax.swing.GroupLayout jPanel7Layout = new javax.swing.GroupLayout(jPanel7);
jPanel7.setLayout(jPanel7Layout);
jPanel7Layout.setHorizontalGroup(
jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel7Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 381, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jPanel7Layout.setVerticalGroup(
jPanel7Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel7Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.jPanel7.TabConstraints.tabTitle"), jPanel7); // NOI18N
tblLookahead.setAutoCreateRowSorter(true);
tblLookahead.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null, null, null, null},
{null, null, null, null, null, null},
{null, null, null, null, null, null},
{null, null, null, null, null, null}
},
new String [] {
"Decision", "Rule", "Avg k", "Min k", "Max k", "Cost"
}
) {
boolean[] canEdit = new boolean [] {
false, false, false, false, false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane2.setViewportView(tblLookahead);
if (tblLookahead.getColumnModel().getColumnCount() > 0) {
tblLookahead.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title0")); // NOI18N
tblLookahead.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title1")); // NOI18N
tblLookahead.getColumnModel().getColumn(2).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title3")); // NOI18N
tblLookahead.getColumnModel().getColumn(3).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title4")); // NOI18N
tblLookahead.getColumnModel().getColumn(4).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title5")); // NOI18N
}
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 381, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.jPanel3.TabConstraints.tabTitle"), jPanel3); // NOI18N
tblConflicts.setAutoCreateRowSorter(true);
tblConflicts.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null, null, null, null},
{null, null, null, null, null, null},
{null, null, null, null, null, null},
{null, null, null, null, null, null}
},
new String [] {
"Decision", "Rule", "Count", "SLL Conflict", "Ambiguities", "Context Sensitivities"
}
) {
boolean[] canEdit = new boolean [] {
false, false, false, false, false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane3.setViewportView(tblConflicts);
if (tblConflicts.getColumnModel().getColumnCount() > 0) {
tblConflicts.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title0")); // NOI18N
tblConflicts.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblLookahead.columnModel.title1")); // NOI18N
tblConflicts.getColumnModel().getColumn(2).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblConflicts.columnModel.title2")); // NOI18N
tblConflicts.getColumnModel().getColumn(3).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblConflicts.columnModel.title6")); // NOI18N
tblConflicts.getColumnModel().getColumn(4).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblConflicts.columnModel.title3")); // NOI18N
tblConflicts.getColumnModel().getColumn(5).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblConflicts.columnModel.title8")); // NOI18N
}
javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
jPanel5.setLayout(jPanel5Layout);
jPanel5Layout.setHorizontalGroup(
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel5Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 381, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jPanel5Layout.setVerticalGroup(
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel5Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.jPanel5.TabConstraints.tabTitle"), jPanel5); // NOI18N
tblStatistics.setAutoCreateRowSorter(true);
tblStatistics.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null},
{null, null},
{null, null},
{null, null}
},
new String [] {
"Statistic", "Value"
}
) {
boolean[] canEdit = new boolean [] {
false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane6.setViewportView(tblStatistics);
if (tblStatistics.getColumnModel().getColumnCount() > 0) {
tblStatistics.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblStatistics.columnModel.title0")); // NOI18N
tblStatistics.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.tblStatistics.columnModel.title1")); // NOI18N
}
javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
jPanel4.setLayout(jPanel4Layout);
jPanel4Layout.setHorizontalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane6, javax.swing.GroupLayout.DEFAULT_SIZE, 381, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jPanel4Layout.setVerticalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel4Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane6, javax.swing.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(ParserDebuggerControllerTopComponent.class, "ParserDebuggerControllerTopComponent.jPanel4.TabConstraints.tabTitle"), jPanel4); // NOI18N
jSplitPane1.setTopComponent(jTabbedPane1);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 386, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 180, Short.MAX_VALUE)
);
jSplitPane1.setRightComponent(jPanel1);
add(jSplitPane1);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel jPanel1;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JTable tblConflicts;
private javax.swing.JTable tblDecisions;
private javax.swing.JTable tblLookahead;
private javax.swing.JTable tblRules;
private javax.swing.JTable tblStatistics;
// End of variables declaration//GEN-END:variables
@Override
public void componentOpened() {
// TODO add custom code on component opening
}
@Override
public void componentClosed() {
// TODO add custom code on component closing
}
void writeProperties(java.util.Properties p) {
// better to version settings since initial version as advocated at
// http://wiki.apidesign.org/wiki/PropertyFiles
p.setProperty("version", "1.0");
// TODO store your settings
}
void readProperties(java.util.Properties p) {
String version = p.getProperty("version");
// TODO read your settings according to their version
}
private class EditorRegistryListener implements PropertyChangeListener {
private JTextComponent currentComponent;
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (EditorRegistry.FOCUS_GAINED_PROPERTY.equals(evt.getPropertyName())) {
JTextComponent component = EditorRegistry.focusedComponent();
if (component == currentComponent) {
return;
}
Document document = component.getDocument();
ParserInterpreterData parserInterpreterData = (ParserInterpreterData)document.getProperty(ParserDebuggerEditorKit.PROP_PARSER_INTERP_DATA);
if (parserInterpreterData == null) {
return;
}
ATN atn = new ATNDeserializer().deserialize(parserInterpreterData.serializedAtn.toCharArray());
ParserTaskManager taskManager = Lookup.getDefault().lookup(ParserTaskManager.class);
DocumentSnapshot snapshot = VersionedDocumentUtilities.getVersionedDocument(document).getCurrentSnapshot();
FileParseResult fileParseResult = ParserDebuggerParserDataDefinitions.tryGetData(taskManager, snapshot, ParserDebuggerParserDataDefinitions.FILE_PARSE_RESULT, EnumSet.of(ParserDataOptions.SYNCHRONOUS));
ParserRuleContext parseTree = ParserDebuggerParserDataDefinitions.tryGetData(taskManager, snapshot, ParserDebuggerParserDataDefinitions.REFERENCE_PARSE_TREE, EnumSet.of(ParserDataOptions.SYNCHRONOUS));
currentComponent = component;
final List<RuleDetail> ruleDetails = new ArrayList<>();
if (parseTree != null) {
final long[] ruleCounts = new long[parserInterpreterData.ruleNames.size()];
ParseTreeWalker.DEFAULT.walk(new ParseTreeListener() {
@Override
public void visitTerminal(TerminalNode node) {
}
@Override
public void visitErrorNode(ErrorNode node) {
}
@Override
public void enterEveryRule(ParserRuleContext ctx) {
ruleCounts[ctx.getRuleIndex()]++;
}
@Override
public void exitEveryRule(ParserRuleContext ctx) {
}
}, parseTree);
for (int i = 0; i < ruleCounts.length; i++) {
ruleDetails.add(new RuleDetail(parserInterpreterData.ruleNames.get(i), ruleCounts[i]));
}
}
tblRules.setModel(new AbstractTableModel() {
@Override
public int getRowCount() {
return ruleDetails.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Rule";
case 1:
return "Instances";
default:
throw new IllegalArgumentException("column");
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return String.class;
case 1:
return Long.class;
default:
throw new IllegalArgumentException("columnIndex");
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return ruleDetails.get(rowIndex).getRuleName();
case 1:
return ruleDetails.get(rowIndex).getInstances();
default:
throw new IllegalArgumentException("columnIndex");
}
}
});
final List<DecisionStatistic> decisionStatistics = new ArrayList<>();
if (fileParseResult != null) {
for (int i = 0; i < fileParseResult.decisionInvocations.length; i++) {
int ruleIndex = atn.decisionToState.get(i).ruleIndex;
String ruleName = parserInterpreterData.ruleNames.get(ruleIndex);
decisionStatistics.add(new DecisionStatistic(i, ruleName, fileParseResult.decisionInvocations[i]));
}
}
tblDecisions.setModel(new AbstractTableModel() {
@Override
public int getRowCount() {
return decisionStatistics.size();
}
@Override
public int getColumnCount() {
return 3;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Decision";
case 1:
return "Rule";
case 2:
return "Count";
default:
throw new IllegalArgumentException("column");
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return Integer.class;
case 1:
return String.class;
case 2:
return Long.class;
default:
throw new IllegalArgumentException("columnIndex");
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return decisionStatistics.get(rowIndex).getDecision();
case 1:
return decisionStatistics.get(rowIndex).getRuleName();
case 2:
return decisionStatistics.get(rowIndex).getCount();
default:
throw new IllegalArgumentException("columnIndex");
}
}
});
final List<LookaheadStatistic> lookaheadStatistics = new ArrayList<>();
if (fileParseResult != null) {
for (int i = 0; i < fileParseResult.decisionInvocations.length; i++) {
int ruleIndex = atn.decisionToState.get(i).ruleIndex;
String ruleName = parserInterpreterData.ruleNames.get(ruleIndex);
double averageLookaheadSll;
if (fileParseResult.decisionInvocations[i] > 0) {
averageLookaheadSll = (double)fileParseResult.totalLookaheadSll[i] / (double)fileParseResult.decisionInvocations[i];
} else {
averageLookaheadSll = -1;
}
double averageLookaheadLl;
if (fileParseResult.fullContextFallback[i] > 0) {
averageLookaheadLl = (double)fileParseResult.totalLookaheadLl[i] / (double)fileParseResult.fullContextFallback[i];
} else {
averageLookaheadLl = -1;
}
long minLookaheadSll = fileParseResult.minLookaheadSll[i];
long maxLookaheadSll = fileParseResult.maxLookaheadSll[i];
long minLookaheadLl = fileParseResult.minLookaheadLl[i];
long maxLookaheadLl = fileParseResult.maxLookaheadLl[i];
long totalTransitions = fileParseResult.parserTotalTransitions[i];
lookaheadStatistics.add(new LookaheadStatistic(i, ruleName, averageLookaheadSll, averageLookaheadLl, minLookaheadSll, maxLookaheadSll, minLookaheadLl, maxLookaheadLl, totalTransitions));
}
}
tblLookahead.setModel(new AbstractTableModel() {
@Override
public int getRowCount() {
return lookaheadStatistics.size();
}
@Override
public int getColumnCount() {
return 9;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Decision";
case 1:
return "Rule";
case 2:
return "Avg k (SLL)";
case 3:
return "Avg k (LL)";
case 4:
return "Min k (SLL)";
case 5:
return "Max k (SLL)";
case 6:
return "Min k (LL)";
case 7:
return "Max k (LL)";
case 8:
return "Cost";
default:
throw new IllegalArgumentException("column");
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return Integer.class;
case 1:
return String.class;
case 2:
return Double.class;
case 3:
return Double.class;
case 4:
return Long.class;
case 5:
return Long.class;
case 6:
return Long.class;
case 7:
return Long.class;
case 8:
return Long.class;
default:
throw new IllegalArgumentException("columnIndex");
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return lookaheadStatistics.get(rowIndex).getDecision();
case 1:
return lookaheadStatistics.get(rowIndex).getRuleName();
case 2:
return inRangeValue(lookaheadStatistics.get(rowIndex).getAverageLookaheadSll());
case 3:
return inRangeValue(lookaheadStatistics.get(rowIndex).getAverageLookaheadLl());
case 4:
return inRangeValue(lookaheadStatistics.get(rowIndex).getMinLookaheadSll());
case 5:
return inRangeValue(lookaheadStatistics.get(rowIndex).getMaxLookaheadSll());
case 6:
return inRangeValue(lookaheadStatistics.get(rowIndex).getMinLookaheadLl());
case 7:
return inRangeValue(lookaheadStatistics.get(rowIndex).getMaxLookaheadLl());
case 8:
return lookaheadStatistics.get(rowIndex).getTotalTransitions();
default:
throw new IllegalArgumentException("columnIndex");
}
}
private Double inRangeValue(double value) {
if (value < 0) {
return null;
}
return value;
}
private Long inRangeValue(long value) {
if (value == Long.MIN_VALUE || value == Long.MAX_VALUE) {
return null;
}
return value;
}
});
final List<ConflictStatistic> conflictStatistics = new ArrayList<>();
if (fileParseResult != null) {
for (int i = 0; i < fileParseResult.decisionInvocations.length; i++) {
int ruleIndex = atn.decisionToState.get(i).ruleIndex;
String ruleName = parserInterpreterData.ruleNames.get(ruleIndex);
long count = fileParseResult.decisionInvocations[i];
long conflicts = fileParseResult.fullContextFallback[i];
long ambiguities = fileParseResult.ambiguousResult[i];
long contextSensitivities = fileParseResult.nonSll[i];
conflictStatistics.add(new ConflictStatistic(i, ruleName, count, conflicts, ambiguities, contextSensitivities));
}
}
tblConflicts.setModel(new AbstractTableModel() {
@Override
public int getRowCount() {
return conflictStatistics.size();
}
@Override
public int getColumnCount() {
return 6;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Decision";
case 1:
return "Rule";
case 2:
return "Count";
case 3:
return "Conflicts";
case 4:
return "Ambiguities";
case 5:
return "Context Sensitivities";
default:
throw new IllegalArgumentException("column");
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return Integer.class;
case 1:
return String.class;
case 2:
case 3:
case 4:
case 5:
return Long.class;
default:
throw new IllegalArgumentException("columnIndex");
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return conflictStatistics.get(rowIndex).getDecision();
case 1:
return conflictStatistics.get(rowIndex).getRuleName();
case 2:
return conflictStatistics.get(rowIndex).getCount();
case 3:
return conflictStatistics.get(rowIndex).getConflicts();
case 4:
return conflictStatistics.get(rowIndex).getAmbiguities();
case 5:
return conflictStatistics.get(rowIndex).getContextSensitivities();
default:
throw new IllegalArgumentException("columnIndex");
}
}
});
final List<ParserStatistic> statistics = new ArrayList<>();
// number of tokens consumed
statistics.add(new ParserStatistic("Tokens", fileParseResult.tokenCount));
// number of rule contexts created
final long[] ruleCount = new long[1];
ParseTreeListener ruleCountListener = new ParseTreeListener() {
@Override
public void visitTerminal(TerminalNode node) {
}
@Override
public void visitErrorNode(ErrorNode node) {
}
@Override
public void enterEveryRule(ParserRuleContext ctx) {
ruleCount[0]++;
}
@Override
public void exitEveryRule(ParserRuleContext ctx) {
}
};
ParseTreeWalker.DEFAULT.walk(ruleCountListener, parseTree);
statistics.add(new ParserStatistic("Rule Invocations", ruleCount[0]));
// number of syntax errors reported
statistics.add(new ParserStatistic("Syntax Errors", fileParseResult.getSyntaxErrors().size()));
tblStatistics.setModel(new AbstractTableModel() {
@Override
public int getRowCount() {
return statistics.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Statistic";
case 1:
return "Value";
default:
throw new IllegalArgumentException("column");
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return String.class;
case 1:
return Long.class;
default:
throw new IllegalArgumentException("columnIndex");
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return statistics.get(rowIndex).getName();
case 1:
return statistics.get(rowIndex).getValue();
default:
throw new IllegalArgumentException("columnIndex");
}
}
});
}
}
}
private static class RuleDetail {
private final String ruleName;
private final long instances;
public RuleDetail(String ruleName, long instances) {
this.ruleName = ruleName;
this.instances = instances;
}
public String getRuleName() {
return ruleName;
}
public long getInstances() {
return instances;
}
}
private static class DecisionStatistic {
private final int decision;
private final String ruleName;
private final long count;
public DecisionStatistic(int decision, String ruleName, long count) {
this.decision = decision;
this.ruleName = ruleName;
this.count = count;
}
public int getDecision() {
return decision;
}
public String getRuleName() {
return ruleName;
}
public long getCount() {
return count;
}
}
private static class LookaheadStatistic {
private final int decision;
private final String ruleName;
private final double averageLookaheadSll;
private final double averageLookaheadLl;
private final long minLookaheadSll;
private final long maxLookaheadSll;
private final long minLookaheadLl;
private final long maxLookaheadLl;
private final long totalTransitions;
public LookaheadStatistic(int decision, String ruleName, double averageLookaheadSll, double averageLookaheadLl, long minLookaheadSll, long maxLookaheadSll, long minLookaheadLl, long maxLookaheadLl, long totalTransitions) {
this.decision = decision;
this.ruleName = ruleName;
this.averageLookaheadSll = averageLookaheadSll;
this.averageLookaheadLl = averageLookaheadLl;
this.minLookaheadSll = minLookaheadSll;
this.maxLookaheadSll = maxLookaheadSll;
this.minLookaheadLl = minLookaheadLl;
this.maxLookaheadLl = maxLookaheadLl;
this.totalTransitions = totalTransitions;
}
public int getDecision() {
return decision;
}
public String getRuleName() {
return ruleName;
}
public double getAverageLookaheadSll() {
return averageLookaheadSll;
}
public double getAverageLookaheadLl() {
return averageLookaheadLl;
}
public long getMinLookaheadSll() {
return minLookaheadSll;
}
public long getMaxLookaheadSll() {
return maxLookaheadSll;
}
public long getMinLookaheadLl() {
return minLookaheadLl;
}
public long getMaxLookaheadLl() {
return maxLookaheadLl;
}
public long getTotalTransitions() {
return totalTransitions;
}
}
private static class ConflictStatistic {
private final int decision;
private final String ruleName;
private final long count;
private final long conflicts;
private final long ambiguities;
private final long contextSensitivities;
public ConflictStatistic(int decision, String ruleName, long count, long conflicts, long ambiguities, long contextSensitivities) {
this.decision = decision;
this.ruleName = ruleName;
this.count = count;
this.conflicts = conflicts;
this.ambiguities = ambiguities;
this.contextSensitivities = contextSensitivities;
}
public int getDecision() {
return decision;
}
public String getRuleName() {
return ruleName;
}
public long getCount() {
return count;
}
public long getConflicts() {
return conflicts;
}
public long getAmbiguities() {
return ambiguities;
}
public long getContextSensitivities() {
return contextSensitivities;
}
}
private static class ParserStatistic {
private final String name;
private final long value;
public ParserStatistic(String name, long value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public long getValue() {
return value;
}
}
}