/** * Given ^(TOKEN_REF ^(OPTIONS ^(ELEMENT_OPTIONS (= assoc right)))) set option assoc=right in * TOKEN_REF. */ public static void setNodeOptions(GrammarAST node, GrammarAST options) { GrammarASTWithOptions t = (GrammarASTWithOptions) node; if (t.getChildCount() == 0) return; for (Object o : options.getChildren()) { GrammarAST c = (GrammarAST) o; if (c.getType() == ANTLRParser.ASSIGN) { t.setOption(c.getChild(0).getText(), (GrammarAST) c.getChild(1)); } else { t.setOption(c.getText(), null); // no arg such as ID<VarNodeType> } } }
public void translateLeftRecursiveRules() { String language = g.getOptionString("language"); // translate all recursive rules List<String> leftRecursiveRuleNames = new ArrayList<String>(); for (Rule r : rules) { if (!Grammar.isTokenName(r.name)) { if (LeftRecursiveRuleAnalyzer.hasImmediateRecursiveRuleRefs(r.ast, r.name)) { g.originalTokenStream = g.tokenStream; boolean fitsPattern = translateLeftRecursiveRule(ast, (LeftRecursiveRule) r, language); if (fitsPattern) leftRecursiveRuleNames.add(r.name); } } } // update all refs to recursive rules to have [0] argument for (GrammarAST r : ast.getNodesWithType(ANTLRParser.RULE_REF)) { if (r.getParent().getType() == ANTLRParser.RULE) continue; // must be rule def if (((GrammarASTWithOptions) r).getOptionString(PRECEDENCE_OPTION_NAME) != null) continue; // already has arg; must be in rewritten rule if (leftRecursiveRuleNames.contains(r.getText())) { // found ref to recursive rule not already rewritten with arg ((GrammarASTWithOptions) r) .setOption( PRECEDENCE_OPTION_NAME, (GrammarAST) new GrammarASTAdaptor().create(ANTLRParser.INT, "0")); } } }