public ATN createATN() { _createATN(g.rules.values()); atn.maxTokenType = g.getMaxTokenType(); addRuleFollowLinks(); addEOFTransitionToStartRules(); return atn; }
public ParserATNFactory(@NotNull Grammar g) { if (g == null) { throw new NullPointerException("g"); } this.g = g; ATNType atnType = g instanceof LexerGrammar ? ATNType.LEXER : ATNType.PARSER; int maxTokenType = g.getMaxTokenType(); this.atn = new ATN(atnType, maxTokenType); }
@NotNull @Override public ATN createATN() { _createATN(g.rules.values()); assert atn.maxTokenType == g.getMaxTokenType(); addRuleFollowLinks(); addEOFTransitionToStartRules(); ATNOptimizer.optimize(g, atn); for (Triple<Rule, ATNState, ATNState> pair : preventEpsilonClosureBlocks) { LL1Analyzer analyzer = new LL1Analyzer(atn); if (analyzer.LOOK(pair.b, pair.c, null).contains(org.antlr.v4.runtime.Token.EPSILON)) { ErrorType errorType = pair.a instanceof LeftRecursiveRule ? ErrorType.EPSILON_LR_FOLLOW : ErrorType.EPSILON_CLOSURE; g.tool.errMgr.grammarError( errorType, g.fileName, ((GrammarAST) pair.a.ast.getChild(0)).getToken(), pair.a.name); } } optionalCheck: for (Triple<Rule, ATNState, ATNState> pair : preventEpsilonOptionalBlocks) { int bypassCount = 0; for (int i = 0; i < pair.b.getNumberOfTransitions(); i++) { ATNState startState = pair.b.transition(i).target; if (startState == pair.c) { bypassCount++; continue; } LL1Analyzer analyzer = new LL1Analyzer(atn); if (analyzer.LOOK(startState, pair.c, null).contains(org.antlr.v4.runtime.Token.EPSILON)) { g.tool.errMgr.grammarError( ErrorType.EPSILON_OPTIONAL, g.fileName, ((GrammarAST) pair.a.ast.getChild(0)).getToken(), pair.a.name); continue optionalCheck; } } if (bypassCount != 1) { throw new UnsupportedOperationException( "Expected optional block with exactly 1 bypass alternative."); } } return atn; }
/** * From set build single edge graph o->o-set->o. To conform to what an alt block looks like, must * have extra state on left. This handles ~A also, converted to ~{A} set. */ public Handle set(GrammarAST associatedAST, List<GrammarAST> terminals, boolean invert) { ATNState left = newState(associatedAST); ATNState right = newState(associatedAST); IntervalSet set = new IntervalSet(); for (GrammarAST t : terminals) { int ttype = g.getTokenType(t.getText()); set.add(ttype); } if (invert) { IntervalSet notSet = set.complement(Token.MIN_TOKEN_TYPE, g.getMaxTokenType()); left.addTransition(new NotSetTransition(right, set, notSet)); } else { left.addTransition(new SetTransition(right, set)); } associatedAST.atnState = left; return new Handle(left, right); }