@NotNull public Handle _ruleRef(@NotNull GrammarAST node) { Rule r = g.getRule(node.getText()); if (r == null) { g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "Rule " + node.getText() + " undefined"); return null; } RuleStartState start = atn.ruleToStartState[r.index]; ATNState left = newState(node); ATNState right = newState(node); int precedence = 0; if (((GrammarASTWithOptions) node) .getOptionString(LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME) != null) { precedence = Integer.parseInt( ((GrammarASTWithOptions) node) .getOptionString(LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME)); } RuleTransition call = new RuleTransition(start, r.index, precedence, right); left.addTransition(call); node.atnState = left; return new Handle(left, right); }
/** Build an atom with all possible values in its label */ @NotNull public Handle wildcard(GrammarAST node) { ATNState left = newState(node); ATNState right = newState(node); left.addTransition(new WildcardTransition(right)); node.atnState = left; return new Handle(left, right); }
/** * 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); }
/** From label A build Graph o-A->o */ public Handle tokenRef(TerminalAST node) { ATNState left = newState(node); ATNState right = newState(node); int ttype = g.getTokenType(node.getText()); left.addTransition(new AtomTransition(right, ttype)); node.atnState = left; return new Handle(left, right); }
/** * Build what amounts to an epsilon transition with an action. The action goes into ATN though it * is ignored during prediction if actionIndex < 0. Only forced are executed during prediction. */ public Handle action(ActionAST action) { // System.out.println("action: "+action); ATNState left = newState(action); ATNState right = newState(action); ActionTransition a = new ActionTransition(right, currentRule.index); left.addTransition(a); action.atnState = left; return new Handle(left, right); }
/** [Aa\t \u1234a-z\]\-] char sets */ @Override public Handle charSetLiteral(GrammarAST charSetAST) { ATNState left = newState(charSetAST); ATNState right = newState(charSetAST); IntervalSet set = getSetFromCharSetLiteral(charSetAST); left.addTransition(new SetTransition(right, set)); charSetAST.atnState = left; return new Handle(left, right); }
/** * From set build single edge graph {@code o->o-set->o}. To conform to what an alt block looks * like, must have extra state on left. This also handles {@code ~A}, converted to {@code ~{A}} * set. */ @NotNull @Override public Handle set( @NotNull GrammarAST associatedAST, @NotNull 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) { left.addTransition(new NotSetTransition(right, set)); } else { left.addTransition(new SetTransition(right, set)); } associatedAST.atnState = left; return new Handle(left, right); }
/** * Build what amounts to an epsilon transition with a semantic predicate action. The pred is a * pointer into the AST of the SEMPRED token. */ public Handle sempred(PredAST pred) { // System.out.println("sempred: "+ pred); ATNState left = newState(pred); ATNState right = newState(pred); boolean isCtxDependent = UseDefAnalyzer.actionIsContextDependent(pred); PredicateTransition p = new PredicateTransition(right, currentRule.index, g.sempreds.get(pred), isCtxDependent); left.addTransition(p); pred.atnState = left; return new Handle(left, right); }
@Override public Handle tokenRef(TerminalAST node) { // Ref to EOF in lexer yields char transition on -1 if (node.getText().equals("EOF")) { ATNState left = newState(node); ATNState right = newState(node); left.addTransition(new AtomTransition(right, IntStream.EOF)); return new Handle(left, right); } return _ruleRef(node); }
@Override public Handle range(GrammarAST a, GrammarAST b) { ATNState left = newState(a); ATNState right = newState(b); int t1 = CharSupport.getCharValueFromGrammarCharLiteral(a.getText()); int t2 = CharSupport.getCharValueFromGrammarCharLiteral(b.getText()); left.addTransition(new RangeTransition(right, t1, t2)); a.atnState = left; b.atnState = left; return new Handle(left, right); }
@Override public Handle set(GrammarAST associatedAST, List<GrammarAST> alts, boolean invert) { ATNState left = newState(associatedAST); ATNState right = newState(associatedAST); IntervalSet set = new IntervalSet(); for (GrammarAST t : alts) { if (t.getType() == ANTLRParser.RANGE) { int a = CharSupport.getCharValueFromGrammarCharLiteral(t.getChild(0).getText()); int b = CharSupport.getCharValueFromGrammarCharLiteral(t.getChild(1).getText()); set.add(a, b); } else if (t.getType() == ANTLRParser.LEXER_CHAR_SET) { set.addAll(getSetFromCharSetLiteral(t)); } else if (t.getType() == ANTLRParser.STRING_LITERAL) { int c = CharSupport.getCharValueFromGrammarCharLiteral(t.getText()); if (c != -1) { set.add(c); } else { g.tool.errMgr.grammarError( ErrorType.INVALID_LITERAL_IN_LEXER_SET, g.fileName, t.getToken(), t.getText()); } } else if (t.getType() == ANTLRParser.TOKEN_REF) { g.tool.errMgr.grammarError( ErrorType.UNSUPPORTED_REFERENCE_IN_LEXER_SET, g.fileName, t.getToken(), t.getText()); } } if (invert) { left.addTransition(new NotSetTransition(right, set)); } else { Transition transition; if (set.getIntervals().size() == 1) { Interval interval = set.getIntervals().get(0); transition = new RangeTransition(right, interval.a, interval.b); } else { transition = new SetTransition(right, set); } left.addTransition(transition); } associatedAST.atnState = left; return new Handle(left, right); }
protected Handle action(GrammarAST node, LexerAction lexerAction) { ATNState left = newState(node); ATNState right = newState(node); boolean isCtxDependent = false; int lexerActionIndex = getLexerActionIndex(lexerAction); ActionTransition a = new ActionTransition(right, currentRule.index, lexerActionIndex, isCtxDependent); left.addTransition(a); node.atnState = left; Handle h = new Handle(left, right); return h; }
/** * Add an EOF transition to any rule end ATNState that points to nothing (i.e., for all those * rules not invoked by another rule). These are start symbols then. * * <p>Return the number of grammar entry points; i.e., how many rules are not invoked by another * rule (they can only be invoked from outside). These are the start rules. */ public int addEOFTransitionToStartRules() { int n = 0; ATNState eofTarget = newState(null); // one unique EOF target for all rules for (Rule r : g.rules.values()) { ATNState stop = atn.ruleToStopState[r.index]; if (stop.getNumberOfTransitions() > 0) continue; n++; Transition t = new AtomTransition(eofTarget, Token.EOF); stop.addTransition(t); } return n; }
public Handle _ruleRef(GrammarAST node) { Rule r = g.getRule(node.getText()); if (r == null) { g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "Rule " + node.getText() + " undefined"); return null; } RuleStartState start = atn.ruleToStartState[r.index]; ATNState left = newState(node); ATNState right = newState(node); RuleTransition call = new RuleTransition(start, r.index, right); left.addTransition(call); node.atnState = left; return new Handle(left, right); }
/** * For a lexer, a string is a sequence of char to match. That is, "fog" is treated as 'f' 'o' 'g' * not as a single transition in the DFA. Machine== o-'f'->o-'o'->o-'g'->o and has n+1 * states for n characters. */ @Override public Handle stringLiteral(TerminalAST stringLiteralAST) { String chars = stringLiteralAST.getText(); chars = CharSupport.getStringFromGrammarStringLiteral(chars); int n = chars.length(); ATNState left = newState(stringLiteralAST); ATNState prev = left; ATNState right = null; for (int i = 0; i < n; i++) { right = newState(stringLiteralAST); prev.addTransition(new AtomTransition(right, chars.charAt(i))); prev = right; } stringLiteralAST.atnState = left; return new Handle(left, right); }
/** * Build what amounts to an epsilon transition with a semantic predicate action. The {@code pred} * is a pointer into the AST of the {@link ANTLRParser#SEMPRED} token. */ @Override public Handle sempred(PredAST pred) { // System.out.println("sempred: "+ pred); ATNState left = newState(pred); ATNState right = newState(pred); AbstractPredicateTransition p; if (pred.getOptionString(LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME) != null) { int precedence = Integer.parseInt( pred.getOptionString(LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME)); p = new PrecedencePredicateTransition(right, precedence); } else { boolean isCtxDependent = UseDefAnalyzer.actionIsContextDependent(pred); p = new PredicateTransition(right, currentRule.index, g.sempreds.get(pred), isCtxDependent); } left.addTransition(p); pred.atnState = left; return new Handle(left, right); }
protected void epsilon(ATNState a, @NotNull ATNState b, boolean prepend) { if (a != null) { int index = prepend ? 0 : a.getNumberOfTransitions(); a.addTransition(index, new EpsilonTransition(b)); } }
void epsilon(ATNState a, @NotNull ATNState b) { if (a != null) a.addTransition(new EpsilonTransition(b)); }