/** * Make sure that action is last element in outer alt; here action, * a2, z, and zz are bad, but a3 is ok: * (RULE A (BLOCK (ALT {action} 'a'))) * (RULE B (BLOCK (ALT (BLOCK (ALT {a2} 'x') (ALT 'y')) {a3}))) * (RULE C (BLOCK (ALT 'd' {z}) (ALT 'e' {zz}))) */ protected virtual void CheckElementIsOuterMostInSingleAlt(GrammarAST tree) { CommonTree alt = (CommonTree)tree.Parent; CommonTree blk = (CommonTree)alt.Parent; bool outerMostAlt = blk.Parent.Type == RULE; ITree rule = tree.GetAncestor(RULE); string fileName = tree.Token.InputStream.SourceName; if (!outerMostAlt || blk.ChildCount > 1) { ErrorType e = ErrorType.LEXER_COMMAND_PLACEMENT_ISSUE; g.tool.errMgr.GrammarError(e, fileName, tree.Token, rule.GetChild(0).Text); } }
public override void BlockOption(GrammarAST ID, GrammarAST valueAST) { CheckOptions((GrammarAST)ID.GetAncestor(BLOCK), ID.Token, valueAST); }
protected virtual GrammarAST TranslateLeftFactoredElement(GrammarAST element, string factoredRule, bool variant, DecisionFactorMode mode, bool includeFactoredElement) { if (mode == DecisionFactorMode.PARTIAL_UNFACTORED && includeFactoredElement) { throw new ArgumentException("Cannot include the factored element in unfactored alternatives."); } if (mode == DecisionFactorMode.COMBINED_FACTOR) { throw new InvalidOperationException("Cannot return a combined answer."); } Debug.Assert(!mode.IncludeFactoredAlts() || !mode.IncludeUnfactoredAlts()); switch (element.Type) { case ANTLRParser.ASSIGN: case ANTLRParser.PLUS_ASSIGN: { /* label=a * * ==> * * factoredElement label=a_factored */ GrammarAST translatedChildElement = TranslateLeftFactoredElement((GrammarAST)element.GetChild(1), factoredRule, variant, mode, includeFactoredElement); if (translatedChildElement == null) { return(null); } RuleAST ruleAST = (RuleAST)element.GetAncestor(ANTLRParser.RULE); #if false LOGGER.log(Level.WARNING, "Could not left factor ''{0}'' out of decision in rule ''{1}'': labeled rule references are not yet supported.", new object[] { factoredRule, ruleAST.GetChild(0).Text }); #endif return(null); //if (!translatedChildElement.IsNil) //{ // GrammarAST root = (GrammarAST)adaptor.Nil(); // object factoredElement = translatedChildElement; // if (outerRule) // { // adaptor.AddChild(root, factoredElement); // } // string action = string.Format("_localctx.{0} = (ContextType)_localctx.getParent().getChild(_localctx.getParent().getChildCount() - 1);", element.GetChild(0).Text); // adaptor.AddChild(root, new ActionAST(adaptor.CreateToken(ANTLRParser.ACTION, action))); // return root; //} //else //{ // GrammarAST root = (GrammarAST)adaptor.Nil(); // object factoredElement = adaptor.DeleteChild(translatedChildElement, 0); // if (outerRule) // { // adaptor.AddChild(root, factoredElement); // } // adaptor.AddChild(root, element); // adaptor.ReplaceChildren(element, 1, 1, translatedChildElement); // return root; //} } case ANTLRParser.RULE_REF: { if (factoredRule.Equals(element.Token.Text)) { if (!mode.IncludeFactoredAlts()) { return(null); } if (includeFactoredElement) { // this element is already left factored return(element); } GrammarAST root1 = (GrammarAST)adaptor.Nil(); root1.AddChild((ITree)adaptor.Create(TokenConstants.Epsilon, "EPSILON")); root1.DeleteChild(0); return(root1); } Rule targetRule; if (!_rules.TryGetValue(element.Token.Text, out targetRule)) { return(null); } RuleVariants ruleVariants = CreateLeftFactoredRuleVariant(targetRule, factoredRule); switch (ruleVariants) { case RuleVariants.NONE: if (!mode.IncludeUnfactoredAlts()) { return(null); } // just call the original rule (leave the element unchanged) return(element); case RuleVariants.FULLY_FACTORED: if (!mode.IncludeFactoredAlts()) { return(null); } break; case RuleVariants.PARTIALLY_FACTORED: break; default: throw new InvalidOperationException(); } string marker = mode.IncludeFactoredAlts() ? ATNSimulator.RuleLfVariantMarker : ATNSimulator.RuleNolfVariantMarker; element.SetText(element.Text + marker + factoredRule); GrammarAST root = (GrammarAST)adaptor.Nil(); if (includeFactoredElement) { Debug.Assert(mode.IncludeFactoredAlts()); RuleRefAST factoredRuleRef = new RuleRefAST(adaptor.CreateToken(ANTLRParser.RULE_REF, factoredRule)); factoredRuleRef.SetOption(SUPPRESS_ACCESSOR, (GrammarAST)adaptor.Create(ANTLRParser.ID, "true")); Rule factoredRuleDef = _rules[factoredRule]; if (factoredRuleDef is LeftRecursiveRule) { factoredRuleRef.SetOption(LeftRecursiveRuleTransformer.PRECEDENCE_OPTION_NAME, (GrammarAST)adaptor.Create(ANTLRParser.INT, "0")); } if (factoredRuleDef.args != null && factoredRuleDef.args.Size() > 0) { throw new NotImplementedException("Cannot left-factor rules with arguments yet."); } adaptor.AddChild(root, factoredRuleRef); } adaptor.AddChild(root, element); return(root); } case ANTLRParser.BLOCK: { GrammarAST cloned = element.DupTree(); if (!TranslateLeftFactoredDecision(cloned, factoredRule, variant, mode, includeFactoredElement)) { return(null); } if (cloned.ChildCount != 1) { return(null); } GrammarAST root = (GrammarAST)adaptor.Nil(); for (int i = 0; i < cloned.GetChild(0).ChildCount; i++) { adaptor.AddChild(root, cloned.GetChild(0).GetChild(i)); } return(root); } case ANTLRParser.POSITIVE_CLOSURE: { /* a+ * * => * * factoredElement a_factored a* */ GrammarAST originalChildElement = (GrammarAST)element.GetChild(0); GrammarAST translatedElement = TranslateLeftFactoredElement(originalChildElement.DupTree(), factoredRule, variant, mode, includeFactoredElement); if (translatedElement == null) { return(null); } GrammarAST closure = new StarBlockAST(ANTLRParser.CLOSURE, adaptor.CreateToken(ANTLRParser.CLOSURE, "CLOSURE"), null); adaptor.AddChild(closure, originalChildElement); GrammarAST root = (GrammarAST)adaptor.Nil(); if (mode.IncludeFactoredAlts()) { if (includeFactoredElement) { object factoredElement = adaptor.DeleteChild(translatedElement, 0); adaptor.AddChild(root, factoredElement); } } adaptor.AddChild(root, translatedElement); adaptor.AddChild(root, closure); return(root); } case ANTLRParser.CLOSURE: case ANTLRParser.OPTIONAL: // not yet supported if (mode.IncludeUnfactoredAlts()) { return(element); } return(null); case ANTLRParser.DOT: // ref to imported grammar, not yet supported if (mode.IncludeUnfactoredAlts()) { return(element); } return(null); case ANTLRParser.ACTION: case ANTLRParser.SEMPRED: if (mode.IncludeUnfactoredAlts()) { return(element); } return(null); case ANTLRParser.WILDCARD: case ANTLRParser.STRING_LITERAL: case ANTLRParser.TOKEN_REF: case ANTLRParser.NOT: // terminals if (mode.IncludeUnfactoredAlts()) { return(element); } return(null); case ANTLRParser.EPSILON: // empty tree if (mode.IncludeUnfactoredAlts()) { return(element); } return(null); default: // unknown return(null); } }
public override void RuleOption(GrammarAST ID, GrammarAST valueAST) { CheckOptions((GrammarAST)ID.GetAncestor(RULE), ID.Token, valueAST); }
public virtual void TranslateLeftFactoredRules() { // translate all rules marked for auto left factoring foreach (Rule r in _rules.Values) { if (Grammar.IsTokenName(r.name)) { continue; } ActionAST leftFactoredRules; if (!r.namedActions.TryGetValue(LEFTFACTOR, out leftFactoredRules) || leftFactoredRules == null) { continue; } string leftFactoredRuleAction = leftFactoredRules.ToString(); leftFactoredRuleAction = leftFactoredRuleAction.Substring(1, leftFactoredRuleAction.Length - 2); string[] rules = leftFactoredRuleAction.Split(','); for (int i = 0; i < rules.Length; i++) { rules[i] = rules[i].Trim(); } if (rules.Length == 0) { continue; } #if false LOGGER.log(Level.FINE, "Left factoring {0} out of alts in grammar rule {1}", new object[] { Arrays.toString(rules), r.name }); #endif ISet <GrammarAST> translatedBlocks = new HashSet <GrammarAST>(); IList <GrammarAST> blocks = r.ast.GetNodesWithType(ANTLRParser.BLOCK); foreach (GrammarAST block in blocks) { for (GrammarAST current = (GrammarAST)block.Parent; current != null; current = (GrammarAST)current.GetAncestor(ANTLRParser.BLOCK)) { if (translatedBlocks.Contains(current)) { // an enclosing decision was already factored goto continueBlockLoop; } } if (rules.Length != 1) { throw new NotImplementedException("Chained left factoring is not yet implemented."); } if (!TranslateLeftFactoredDecision(block, rules[0], false, DecisionFactorMode.COMBINED_FACTOR, true)) { // couldn't translate the decision continue; } translatedBlocks.Add(block); continueBlockLoop: ; } } }