public virtual bool Check(Rule enclosingRule, ATNState s, ISet<ATNState> visitedStates)
{
if (s is RuleStopState)
return true;
if (visitedStates.Contains(s))
return false;
visitedStates.Add(s);
//System.out.println("visit "+s);
int n = s.NumberOfTransitions;
bool stateReachesStopState = false;
for (int i = 0; i < n; i++)
{
Transition t = s.Transition(i);
if (t is RuleTransition)
{
RuleTransition rt = (RuleTransition)t;
Rule r = g.GetRule(rt.ruleIndex);
if (rulesVisitedPerRuleCheck.Contains((RuleStartState)t.target))
{
AddRulesToCycle(enclosingRule, r);
}
else
{
// must visit if not already visited; mark target, pop when done
rulesVisitedPerRuleCheck.Add((RuleStartState)t.target);
// send new visitedStates set per rule invocation
bool nullable = Check(r, t.target, new HashSet<ATNState>());
// we're back from visiting that rule
rulesVisitedPerRuleCheck.Remove((RuleStartState)t.target);
if (nullable)
{
stateReachesStopState |= Check(enclosingRule, rt.followState, visitedStates);
}
}
}
else if (t.IsEpsilon)
{
stateReachesStopState |= Check(enclosingRule, t.target, visitedStates);
}
// else ignore non-epsilon transitions
}
return stateReachesStopState;
}