private static int CombineChainedEpsilons(ATN atn)
{
int removedEdges = 0;
foreach (ATNState state in atn.states)
{
if (!state.OnlyHasEpsilonTransitions || state is RuleStopState)
{
continue;
}
IList<Transition> optimizedTransitions = null;
for (int i = 0; i < state.NumberOfOptimizedTransitions; i++)
{
Transition transition = state.GetOptimizedTransition(i);
ATNState intermediate = transition.target;
if (transition.TransitionType != TransitionType.EPSILON || ((EpsilonTransition)transition).OutermostPrecedenceReturn != -1 || intermediate.StateType != StateType.Basic || !intermediate.OnlyHasEpsilonTransitions)
{
if (optimizedTransitions != null)
{
optimizedTransitions.Add(transition);
}
goto nextTransition_continue;
}
for (int j = 0; j < intermediate.NumberOfOptimizedTransitions; j++)
{
if (intermediate.GetOptimizedTransition(j).TransitionType != TransitionType.EPSILON || ((EpsilonTransition)intermediate.GetOptimizedTransition(j)).OutermostPrecedenceReturn != -1)
{
if (optimizedTransitions != null)
{
optimizedTransitions.Add(transition);
}
goto nextTransition_continue;
}
}
removedEdges++;
if (optimizedTransitions == null)
{
optimizedTransitions = new List<Transition>();
for (int j_1 = 0; j_1 < i; j_1++)
{
optimizedTransitions.Add(state.GetOptimizedTransition(j_1));
}
}
for (int j_2 = 0; j_2 < intermediate.NumberOfOptimizedTransitions; j_2++)
{
ATNState target = intermediate.GetOptimizedTransition(j_2).target;
optimizedTransitions.Add(new EpsilonTransition(target));
}
nextTransition_continue: ;
}
if (optimizedTransitions != null)
{
if (state.IsOptimized)
{
while (state.NumberOfOptimizedTransitions > 0)
{
state.RemoveOptimizedTransition(state.NumberOfOptimizedTransitions - 1);
}
}
foreach (Transition transition in optimizedTransitions)
{
state.AddOptimizedTransition(transition);
}
}
}
return removedEdges;
}