public virtual ATN CreateATN()
{
_CreateATN(g.rules.Values);
Debug.Assert(atn.maxTokenType == g.GetMaxTokenType());
AddRuleFollowLinks();
AddEOFTransitionToStartRules();
ATNOptimizer.Optimize(g, atn);
foreach (System.Tuple <Rule, ATNState, ATNState> pair in preventEpsilonClosureBlocks)
{
LL1Analyzer analyzer = new LL1Analyzer(atn);
ATNState blkStart = pair.Item2;
ATNState blkStop = pair.Item3;
IntervalSet lookahead = analyzer.Look(blkStart, blkStop, PredictionContext.EmptyLocal);
if (lookahead.Contains(Antlr4.Runtime.TokenConstants.Epsilon))
{
ErrorType errorType = pair.Item1 is LeftRecursiveRule ? ErrorType.EPSILON_LR_FOLLOW : ErrorType.EPSILON_CLOSURE;
g.tool.errMgr.GrammarError(errorType, g.fileName, ((GrammarAST)pair.Item1.ast.GetChild(0)).Token, pair.Item1.name);
}
}
foreach (System.Tuple <Rule, ATNState, ATNState> pair in preventEpsilonOptionalBlocks)
{
int bypassCount = 0;
for (int i = 0; i < pair.Item2.NumberOfTransitions; i++)
{
ATNState startState = pair.Item2.Transition(i).target;
if (startState == pair.Item3)
{
bypassCount++;
continue;
}
LL1Analyzer analyzer = new LL1Analyzer(atn);
if (analyzer.Look(startState, pair.Item3, PredictionContext.EmptyLocal).Contains(Antlr4.Runtime.TokenConstants.Epsilon))
{
g.tool.errMgr.GrammarError(ErrorType.EPSILON_OPTIONAL, g.fileName, ((GrammarAST)pair.Item1.ast.GetChild(0)).Token, pair.Item1.name);
goto continueOptionalCheck;
}
}
if (bypassCount != 1)
{
throw new InvalidOperationException("Expected optional block with exactly 1 bypass alternative.");
}
continueOptionalCheck:
;
}
return(atn);
}