forked from jasder/antlr
got new alg working :) added recursed bit to context.
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6780]
This commit is contained in:
parent
2a9fb1bba6
commit
e9fd3d8b8c
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue