// within same rule, we've hit same state; quit looping
return false;
}
visitedStates.add(s);
boolean stateReachesAcceptState = false;
Transition t0 = s.transition[0];
if ( t0 instanceof RuleClosureTransition ) {
RuleClosureTransition refTrans = (RuleClosureTransition)t0;
Rule refRuleDef = refTrans.rule;
//String targetRuleName = ((NFAState)t0.target).getEnclosingRule();
if ( visitedDuringRecursionCheck.contains(refRuleDef) ) {
// record left-recursive rule, but don't go back in
grammar.leftRecursiveRules.add(refRuleDef);
/*
System.out.println("already visited "+refRuleDef+", calling from "+
s.enclosingRule);
*/
addRulesToCycle(refRuleDef,
s.enclosingRule,
listOfRecursiveCycles);
}
else {
// must visit if not already visited; send new visitedStates set
visitedDuringRecursionCheck.add(refRuleDef);
boolean callReachedAcceptState =
traceStatesLookingForLeftRecursion((NFAState)t0.target,
new HashSet<NFAState>(),
listOfRecursiveCycles);
// we're back from visiting that rule
visitedDuringRecursionCheck.remove(refRuleDef);
// must keep going in this rule then
if ( callReachedAcceptState ) {
NFAState followingState =
((RuleClosureTransition) t0).followState;
stateReachesAcceptState |=
traceStatesLookingForLeftRecursion(followingState,
visitedStates,
listOfRecursiveCycles);
}
}
}
else if ( t0.label.isEpsilon() || t0.label.isSemanticPredicate() ) {
stateReachesAcceptState |=
traceStatesLookingForLeftRecursion((NFAState)t0.target, visitedStates, listOfRecursiveCycles);
}
// else it has a labeled edge
// now do the other transition if it exists
Transition t1 = s.transition[1];
if ( t1!=null ) {
stateReachesAcceptState |=
traceStatesLookingForLeftRecursion((NFAState)t1.target,
visitedStates,
listOfRecursiveCycles);