protected bool Closure(ICharStream input, LexerATNConfig config, ATNConfigSet configs, bool currentAltReachedAcceptState, bool speculative, bool treatEofAsEpsilon)
{
if (debug)
{
Console.WriteLine("closure(" + config.ToString(recog, true) + ")");
}
if (config.state is RuleStopState)
{
if (debug)
{
if (recog != null)
{
Console.WriteLine("closure at " + recog.RuleNames[config.state.ruleIndex] + " rule stop " + config);
}
else {
Console.WriteLine("closure at rule stop " + config);
}
}
if (config.context == null || config.context.HasEmptyPath)
{
if (config.context == null || config.context.IsEmpty)
{
configs.Add(config);
return true;
}
else {
configs.Add(new LexerATNConfig(config, config.state, PredictionContext.EMPTY));
currentAltReachedAcceptState = true;
}
}
if (config.context != null && !config.context.IsEmpty)
{
for (int i = 0; i < config.context.Size; i++)
{
if (config.context.GetReturnState(i) != PredictionContext.EMPTY_RETURN_STATE)
{
PredictionContext newContext = config.context.GetParent(i); // "pop" return state
ATNState returnState = atn.states[config.context.GetReturnState(i)];
LexerATNConfig c = new LexerATNConfig(config, returnState, newContext);
currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
}
}
}
return currentAltReachedAcceptState;
}
// optimization
if (!config.state.OnlyHasEpsilonTransitions)
{
if (!currentAltReachedAcceptState || !config.hasPassedThroughNonGreedyDecision())
{
configs.Add(config);
}
}
ATNState p = config.state;
for (int i = 0; i < p.NumberOfTransitions; i++)
{
Transition t = p.Transition(i);
LexerATNConfig c = GetEpsilonTarget(input, config, t, configs, speculative, treatEofAsEpsilon);
if (c != null)
{
currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative, treatEofAsEpsilon);
}
}
return currentAltReachedAcceptState;
}