got new alg working :) added recursed bit to context.

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6780]
This commit is contained in:
parrt 2010-03-27 12:24:58 -08:00
parent 2a9fb1bba6
commit e9fd3d8b8c
2 changed files with 32 additions and 3 deletions

View File

@ -55,6 +55,8 @@ public class NFAContext {
*/ */
public NFAState returnState; public NFAState returnState;
public boolean recursed;
/** Computing the hashCode is very expensive and closureBusy() /** Computing the hashCode is very expensive and closureBusy()
* uses it to track when it's seen a state|ctx before to avoid * 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 * infinite loops. As we add new contexts, record the hash code

View File

@ -81,6 +81,8 @@ public class PredictionDFAFactory {
*/ */
Set<NFAConfig> closureBusy; Set<NFAConfig> closureBusy;
//org.antlr.v4.misc.BitSet visited = new org.antlr.v4.misc.BitSet();
Resolver resolver; Resolver resolver;
public static boolean debug = false; public static boolean debug = false;
@ -316,6 +318,9 @@ public class PredictionDFAFactory {
// p itself is always in closure // p itself is always in closure
configs.add(proposedNFAConfig); configs.add(proposedNFAConfig);
// if ( s instanceof RuleStartState ) {
// visited.add(s.rule.index);
// }
if ( s instanceof RuleStopState ) { if ( s instanceof RuleStopState ) {
ruleStopStateClosure(s, altNum, context, semanticContext, collectPredicates, configs); ruleStopStateClosure(s, altNum, context, semanticContext, collectPredicates, configs);
} }
@ -331,14 +336,26 @@ public class PredictionDFAFactory {
boolean collectPredicates, boolean collectPredicates,
List<NFAConfig> configs) List<NFAConfig> 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; Rule invokingRule = null;
if ( context!= NFAContext.EMPTY) { if ( context != NFAContext.EMPTY) {
// if stack not empty, get invoking rule from top of stack // if stack not empty, get invoking rule from top of stack
invokingRule = context.returnState.rule; 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 // follow all static FOLLOW links
int n = s.getNumberOfTransitions(); int n = s.getNumberOfTransitions();
for (int i=0; i<n; i++) { for (int i=0; i<n; i++) {
@ -362,6 +379,7 @@ public class PredictionDFAFactory {
return; return;
} }
void commonClosure(NFAState s, int altNum, NFAContext context, void commonClosure(NFAState s, int altNum, NFAContext context,
SemanticContext semanticContext, boolean collectPredicates, SemanticContext semanticContext, boolean collectPredicates,
List<NFAConfig> configs) List<NFAConfig> configs)
@ -372,12 +390,21 @@ public class PredictionDFAFactory {
if ( t instanceof RuleTransition) { if ( t instanceof RuleTransition) {
NFAState retState = ((RuleTransition)t).followState; NFAState retState = ((RuleTransition)t).followState;
NFAContext newContext = context; 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, // first create a new context and push onto call tree,
// recording the fact that we are invoking a rule and // recording the fact that we are invoking a rule and
// from which state. // from which state.
System.out.println("nonrecursive invoke of "+t.target+" ret to "+retState+" ctx="+context);
newContext = new NFAContext(context, retState); 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 // traverse epsilon edge to new rule
closure(t.target, altNum, newContext, semanticContext, collectPredicates, configs); closure(t.target, altNum, newContext, semanticContext, collectPredicates, configs);
} }