private static bool TestTailCall(ATN atn, RuleTransition transition, bool optimizedPath)
{
if (!optimizedPath && transition.tailCall)
{
return true;
}
if (optimizedPath && transition.optimizedTailCall)
{
return true;
}
BitSet reachable = new BitSet(atn.states.Count);
Stack<ATNState> worklist = new Stack<ATNState>();
worklist.Push(transition.followState);
while (worklist.Count > 0)
{
ATNState state = worklist.Pop();
if (reachable.Get(state.stateNumber))
{
continue;
}
if (state is RuleStopState)
{
continue;
}
if (!state.OnlyHasEpsilonTransitions)
{
return false;
}
IList<Transition> transitions = optimizedPath ? state.optimizedTransitions : state.transitions;
foreach (Transition t in transitions)
{
if (t.TransitionType != TransitionType.EPSILON)
{
return false;
}
worklist.Push(t.target);
}
}
return true;
}