/// <summary>
/// Since the alternatives within any lexer decision are ordered by
/// preference, this method stops pursuing the closure as soon as an accept
/// state is reached.
/// </summary>
/// <remarks>
/// Since the alternatives within any lexer decision are ordered by
/// preference, this method stops pursuing the closure as soon as an accept
/// state is reached. After the first accept state is reached by depth-first
/// search from
/// <paramref name="config"/>
/// , all other (potentially reachable) states for
/// this rule would have a lower priority.
/// </remarks>
/// <returns>
///
/// <see langword="true"/>
/// if an accept state is reached, otherwise
/// <see langword="false"/>
/// .
/// </returns>
protected internal virtual bool Closure(ICharStream input, ATNConfig config, ATNConfigSet configs, bool currentAltReachedAcceptState, bool speculative, bool treatEofAsEpsilon)
{
if (config.State is RuleStopState)
{
PredictionContext context = config.Context;
if (context.IsEmpty)
{
configs.Add(config);
return(true);
}
else
{
if (context.HasEmpty)
{
configs.Add(config.Transform(config.State, PredictionContext.EmptyFull, true));
currentAltReachedAcceptState = true;
}
}
for (int i = 0; i < context.Size; i++)
{
int returnStateNumber = context.GetReturnState(i);
if (returnStateNumber == PredictionContext.EmptyFullStateKey)
{
continue;
}
PredictionContext newContext = context.GetParent(i);
// "pop" return state
ATNState returnState = atn.states[returnStateNumber];
ATNConfig c = config.Transform(returnState, newContext, false);
currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
}
return(currentAltReachedAcceptState);
}
// optimization
if (!config.State.OnlyHasEpsilonTransitions)
{
if (!currentAltReachedAcceptState || !config.PassedThroughNonGreedyDecision)
{
configs.Add(config);
}
}
ATNState p = config.State;
for (int i_1 = 0; i_1 < p.NumberOfOptimizedTransitions; i_1++)
{
Transition t = p.GetOptimizedTransition(i_1);
ATNConfig c = GetEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon);
if (c != null)
{
currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
}
}
return(currentAltReachedAcceptState);
}