public virtual void TranslateLeftRecursiveRules() { string language = g.GetOptionString("language"); // translate all recursive rules IList <string> leftRecursiveRuleNames = new List <string>(); foreach (Rule r in rules) { if (!Grammar.IsTokenName(r.name)) { if (LeftRecursiveRuleAnalyzer.HasImmediateRecursiveRuleRefs(r.ast, r.name)) { bool fitsPattern = TranslateLeftRecursiveRule(ast, (LeftRecursiveRule)r, language); if (fitsPattern) { leftRecursiveRuleNames.Add(r.name); } else { // Suppressed since this build has secondary support for left recursive rules that don't // match the patterns for precedence rules. // better given an error that non-conforming left-recursion exists //tool.errMgr.grammarError(ErrorType.NONCONFORMING_LR_RULE, g.fileName, ((GrammarAST)r.ast.GetChild(0)).Token, r.name); } } } } // update all refs to recursive rules to have [0] argument foreach (GrammarAST r in ast.GetNodesWithType(ANTLRParser.RULE_REF)) { if (r.Parent.Type == 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.Text)) { // found ref to recursive rule not already rewritten with arg ((GrammarASTWithOptions)r).SetOption(PRECEDENCE_OPTION_NAME, (GrammarAST) new GrammarASTAdaptor().Create(ANTLRParser.INT, "0")); } } }