From e9fd3d8b8cec7cc6d7ba218604df596174f9079b Mon Sep 17 00:00:00 2001 From: parrt Date: Sat, 27 Mar 2010 12:24:58 -0800 Subject: [PATCH] got new alg working :) added recursed bit to context. [git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6780] --- .../src/org/antlr/v4/analysis/NFAContext.java | 2 ++ .../v4/analysis/PredictionDFAFactory.java | 33 +++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/tool/src/org/antlr/v4/analysis/NFAContext.java b/tool/src/org/antlr/v4/analysis/NFAContext.java index 0342421ec..f92c72aca 100644 --- a/tool/src/org/antlr/v4/analysis/NFAContext.java +++ b/tool/src/org/antlr/v4/analysis/NFAContext.java @@ -55,6 +55,8 @@ public class NFAContext { */ public NFAState returnState; + public boolean recursed; + /** Computing the hashCode is very expensive and closureBusy() * uses it to track when it's seen a state|ctx before to avoid * infinite loops. As we add new contexts, record the hash code diff --git a/tool/src/org/antlr/v4/analysis/PredictionDFAFactory.java b/tool/src/org/antlr/v4/analysis/PredictionDFAFactory.java index cd3506c8b..e4042e424 100644 --- a/tool/src/org/antlr/v4/analysis/PredictionDFAFactory.java +++ b/tool/src/org/antlr/v4/analysis/PredictionDFAFactory.java @@ -81,6 +81,8 @@ public class PredictionDFAFactory { */ Set closureBusy; + //org.antlr.v4.misc.BitSet visited = new org.antlr.v4.misc.BitSet(); + Resolver resolver; public static boolean debug = false; @@ -316,6 +318,9 @@ public class PredictionDFAFactory { // p itself is always in closure configs.add(proposedNFAConfig); +// if ( s instanceof RuleStartState ) { +// visited.add(s.rule.index); +// } if ( s instanceof RuleStopState ) { ruleStopStateClosure(s, altNum, context, semanticContext, collectPredicates, configs); } @@ -331,14 +336,26 @@ public class PredictionDFAFactory { boolean collectPredicates, List configs) { + if ( !context.recursed ) { + System.out.println("dynamic FOLLOW of "+s+" context="+context); + if ( context != NFAContext.EMPTY) { + NFAContext newContext = context.parent; // "pop" invoking state + closure(context.returnState, altNum, newContext, semanticContext, collectPredicates, configs); + } + else { + commonClosure(s, altNum, context, semanticContext, collectPredicates, configs); // do global FOLLOW + } + return; + } + Rule invokingRule = null; - if ( context!= NFAContext.EMPTY) { + if ( context != NFAContext.EMPTY) { // if stack not empty, get invoking rule from top of stack invokingRule = context.returnState.rule; } - //System.out.println("FOLLOW of "+s+" context="+context); + System.out.println("FOLLOW of "+s+" context="+context); // follow all static FOLLOW links int n = s.getNumberOfTransitions(); for (int i=0; i configs) @@ -372,12 +390,21 @@ public class PredictionDFAFactory { if ( t instanceof RuleTransition) { NFAState retState = ((RuleTransition)t).followState; NFAContext newContext = context; - if ( !context.contains(((RuleTransition)t).followState) ) { // !recursive? + //if ( !visited.member(t.target.rule.index) ) { // !recursive? + if ( s.rule != t.target.rule && + !context.contains(((RuleTransition)t).followState) ) { // !recursive? // first create a new context and push onto call tree, // recording the fact that we are invoking a rule and // from which state. + System.out.println("nonrecursive invoke of "+t.target+" ret to "+retState+" ctx="+context); newContext = new NFAContext(context, retState); } + else { + System.out.println("# recursive invoke of "+t.target+" ret to "+retState+" ctx="+context); + // don't record recursion, but record we did so we know + // what to do at end of rule. + context.recursed = true; + } // traverse epsilon edge to new rule closure(t.target, altNum, newContext, semanticContext, collectPredicates, configs); }