/// <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
/// <code>config</code>
/// , all other (potentially reachable) states for
/// this rule would have a lower priority.
/// </remarks>
/// <returns>
///
/// <code>true</code>
/// if an accept state is reached, otherwise
/// <code>false</code>
/// .
/// </returns>
protected internal virtual bool Closure(ICharStream input, ATNConfig config, ATNConfigSet
configs, bool speculative)
{
if (config.State is RuleStopState)
{
PredictionContext context = config.Context;
if (context.IsEmpty)
{
configs.AddItem(config);
return(true);
}
else
{
if (context.HasEmpty)
{
configs.AddItem(config.Transform(config.State, PredictionContext.EmptyFull));
return(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 = ATNConfig.Create(returnState, config.Alt, newContext);
if (Closure(input, c, configs, speculative))
{
return(true);
}
}
return(false);
}
// optimization
if (!config.State.OnlyHasEpsilonTransitions)
{
configs.AddItem(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);
if (c != null)
{
if (Closure(input, c, configs, speculative))
{
return(true);
}
}
}
return(false);
}