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); }
protected virtual void ProcessLexer() { // make sure all non-fragment lexer rules must match at least one symbol foreach (Rule rule in g.rules.Values) { if (rule.IsFragment()) { continue; } LL1Analyzer analyzer = new LL1Analyzer(g.atn); IntervalSet look = analyzer.Look(g.atn.ruleToStartState[rule.index], PredictionContext.EmptyLocal); if (look.Contains(TokenConstants.Epsilon)) { g.tool.errMgr.GrammarError(ErrorType.EPSILON_TOKEN, g.fileName, ((GrammarAST)rule.ast.GetChild(0)).Token, rule.name); } } }
protected virtual void ProcessParser() { g.decisionLOOK = new List <IntervalSet[]>(g.atn.NumberOfDecisions + 1); foreach (DecisionState s in g.atn.decisionToState) { g.tool.Log("LL1", "\nDECISION " + s.decision + " in rule " + g.GetRule(s.ruleIndex).name); IntervalSet[] look; if (s.nonGreedy) { // nongreedy decisions can't be LL(1) look = new IntervalSet[s.NumberOfTransitions + 1]; } else { LL1Analyzer anal = new LL1Analyzer(g.atn); look = anal.GetDecisionLookahead(s); g.tool.Log("LL1", "look=[" + string.Join(", ", look.AsEnumerable()) + "]"); } Debug.Assert(s.decision + 1 >= g.decisionLOOK.Count); Utils.SetSize(g.decisionLOOK, s.decision + 1); g.decisionLOOK[s.decision] = look; g.tool.Log("LL1", "LL(1)? " + Disjoint(look)); } }