forked from jasder/antlr
Don't pursue the closure if there is just one state or it's predicting unique alt. Fixed up computeReachSet() to do this. Dropped from 6s to 4.5s for TestJavaLR -SLL on java.* with 45M max footprint.
This commit is contained in:
parent
2495ce6b20
commit
3cec976f7e
|
@ -562,7 +562,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
D.configs.conflictingAlts = getConflictingAlts(reach, false);
|
||||
if ( D.configs.conflictingAlts!=null ) {
|
||||
if ( greedy ) {
|
||||
int k = input.index() - startIndex + 1; // how much input we used
|
||||
// int k = input.index() - startIndex + 1; // how much input we used
|
||||
// System.out.println("used k="+k);
|
||||
if ( outerContext == ParserRuleContext.EMPTY || // in grammar start rule
|
||||
!D.configs.dipsIntoOuterContext || SLL )
|
||||
|
@ -735,10 +735,13 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
protected ATNConfigSet computeReachSet(ATNConfigSet closure, int t,
|
||||
boolean greedy,
|
||||
boolean loopsSimulateTailRecursion,
|
||||
boolean fullCtx) {
|
||||
boolean fullCtx)
|
||||
{
|
||||
if ( debug ) System.out.println("in computeReachSet, starting closure: " + closure);
|
||||
ATNConfigSet reach = new ATNConfigSet(fullCtx);
|
||||
Set<ATNConfig> closureBusy = new HashSet<ATNConfig>();
|
||||
ATNConfigSet intermediate = new ATNConfigSet();
|
||||
// First figure out where we can reach on input t
|
||||
for (ATNConfig c : closure) {
|
||||
if ( debug ) System.out.println("testing "+getTokenName(t)+" at "+c.toString());
|
||||
int n = c.state.getNumberOfTransitions();
|
||||
|
@ -746,10 +749,30 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
Transition trans = c.state.transition(ti);
|
||||
ATNState target = getReachableTarget(trans, t);
|
||||
if ( target!=null ) {
|
||||
closure(new ATNConfig(c, target), reach, closureBusy, false, greedy, loopsSimulateTailRecursion);
|
||||
intermediate.add(new ATNConfig(c, target), contextCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now figure out where the closure can take us, but only if we'll
|
||||
// need to continue looking for more input.
|
||||
if ( intermediate.size()==1 || ParserATNSimulator.getUniqueAlt(intermediate)==1 ) {
|
||||
// Don't pursue the closure if there is just one state.
|
||||
// It can only have one alternative; just add to result
|
||||
// Also don't pursue the closure if there is unique alternative
|
||||
// among the configurations.
|
||||
reach.add(intermediate.get(0));
|
||||
}
|
||||
else if ( ParserATNSimulator.getUniqueAlt(intermediate)==1 ) {
|
||||
// Also don't pursue the closure if there is unique alternative
|
||||
// among the configurations.
|
||||
reach.addAll(intermediate);
|
||||
}
|
||||
else {
|
||||
for (ATNConfig c : intermediate) {
|
||||
closure(c, reach, closureBusy, false, greedy, loopsSimulateTailRecursion);
|
||||
}
|
||||
}
|
||||
|
||||
if ( reach.size()==0 ) return null;
|
||||
return reach;
|
||||
}
|
||||
|
@ -1401,7 +1424,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
|
|||
configs, outerContext);
|
||||
}
|
||||
|
||||
public int getUniqueAlt(@NotNull Collection<ATNConfig> configs) {
|
||||
public static int getUniqueAlt(@NotNull Collection<ATNConfig> configs) {
|
||||
int alt = ATN.INVALID_ALT_NUMBER;
|
||||
for (ATNConfig c : configs) {
|
||||
if ( alt == ATN.INVALID_ALT_NUMBER ) {
|
||||
|
|
|
@ -335,6 +335,9 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
|
|||
|
||||
PredictionContext M =
|
||||
new ArrayPredictionContext(mergedParents, mergedInvokingStates);
|
||||
if ( contextCache==null ) {
|
||||
System.err.println("foooooo");
|
||||
}
|
||||
M = contextCache.add(M);
|
||||
|
||||
// if we created same array as a or b, return that instead
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import org.antlr.runtime.debug.BlankDebugEventListener;
|
||||
import org.antlr.v4.runtime.ANTLRFileStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.DiagnosticErrorListener;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.atn.LexerATNSimulator;
|
||||
import org.antlr.v4.runtime.atn.ParserATNSimulator;
|
||||
|
||||
|
@ -14,6 +17,10 @@ class TestJava {
|
|||
public static boolean profile = false;
|
||||
public static JavaLexer lexer;
|
||||
public static JavaParser parser = null;
|
||||
public static boolean showTree = false;
|
||||
public static boolean printTree = false;
|
||||
public static boolean SLL = false;
|
||||
public static boolean diag = false;
|
||||
|
||||
public static void main(String[] args) {
|
||||
doAll(args);
|
||||
|
@ -28,6 +35,10 @@ class TestJava {
|
|||
if (args.length > 0 ) {
|
||||
// for each directory/file specified on the command line
|
||||
for(int i=0; i< args.length;i++) {
|
||||
if ( args[i].equals("-tree") ) showTree = true;
|
||||
else if ( args[i].equals("-ptree") ) printTree = true;
|
||||
else if ( args[i].equals("-SLL") ) SLL = true;
|
||||
else if ( args[i].equals("-diag") ) diag = true;
|
||||
doFile(new File(args[i])); // parse it
|
||||
}
|
||||
}
|
||||
|
@ -114,8 +125,14 @@ class TestJava {
|
|||
// parser.getInterpreter().setContextSensitive(true);
|
||||
}
|
||||
parser.setTokenStream(tokens);
|
||||
|
||||
if ( diag ) parser.addErrorListener(new DiagnosticErrorListener());
|
||||
if ( SLL ) parser.getInterpreter().SLL = true;
|
||||
// start parsing at the compilationUnit rule
|
||||
parser.compilationUnit();
|
||||
ParserRuleContext<Token> tree = parser.compilationUnit();
|
||||
if ( showTree ) tree.inspect(parser);
|
||||
if ( printTree ) System.out.println(tree.toStringTree(parser));
|
||||
|
||||
//System.err.println("finished "+f);
|
||||
// System.out.println("cache size = "+DefaultErrorStrategy.cache.size());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue