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:
Terence Parr 2012-07-24 18:45:23 -07:00
parent 2495ce6b20
commit 3cec976f7e
3 changed files with 48 additions and 5 deletions

View File

@ -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 ) {

View File

@ -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

View File

@ -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());
}