public PlusBlock(OutputModelFactory factory, GrammarAST plusRoot, IList<CodeBlockForAlt> alts) : base(factory, plusRoot, alts) { BlockAST blkAST = (BlockAST)plusRoot.GetChild(0); PlusBlockStartState blkStart = (PlusBlockStartState)blkAST.atnState; PlusLoopbackState loop = blkStart.loopBackState; stateNumber = blkStart.loopBackState.stateNumber; blockStartStateNumber = blkStart.stateNumber; loopBackStateNumber = loop.stateNumber; this.error = GetThrowNoViableAlt(factory, plusRoot, null); decision = loop.decision; }
public LL1PlusBlockSingleAlt(OutputModelFactory factory, GrammarAST plusRoot, IList<CodeBlockForAlt> alts) : base(factory, plusRoot, alts) { BlockAST blkAST = (BlockAST)plusRoot.GetChild(0); PlusBlockStartState blkStart = (PlusBlockStartState)blkAST.atnState; stateNumber = blkStart.loopBackState.stateNumber; blockStartStateNumber = blkStart.stateNumber; PlusBlockStartState plus = (PlusBlockStartState)blkAST.atnState; this.decision = plus.loopBackState.decision; IntervalSet[] altLookSets = factory.GetGrammar().decisionLOOK[decision]; IntervalSet loopBackLook = altLookSets[0]; loopExpr = AddCodeForLoopLookaheadTempVar(loopBackLook); }
protected override void EnterLabeledLexerElement(GrammarAST tree) { IToken label = ((GrammarAST)tree.GetChild(0)).Token; g.tool.errMgr.GrammarError(ErrorType.V3_LEXER_LABEL, g.fileName, label, label.Text); }
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; } }
protected override void ExitMode(GrammarAST tree) { if (nonFragmentRuleCount == 0) { IToken token = tree.Token; string name = "?"; if (tree.ChildCount > 0) { name = tree.GetChild(0).Text; if (string.IsNullOrEmpty(name)) { name = "?"; } token = ((GrammarAST)tree.GetChild(0)).Token; } g.tool.errMgr.GrammarError(ErrorType.MODE_WITHOUT_RULES, g.fileName, token, name, g); } }
protected virtual GrammarAST TranslateLeftFactoredAlternative(GrammarAST alternative, 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."); } else if (mode == DecisionFactorMode.COMBINED_FACTOR && !includeFactoredElement) { throw new ArgumentException("Cannot return a combined answer without the factored element."); } Debug.Assert(alternative.ChildCount > 0); if (alternative.GetChild(0).Type == ANTLRParser.EPSILON) { if (mode == DecisionFactorMode.PARTIAL_UNFACTORED) { return alternative; } return null; } GrammarAST translatedElement = TranslateLeftFactoredElement((GrammarAST)alternative.GetChild(0), factoredRule, variant, mode, includeFactoredElement); if (translatedElement == null) { return null; } alternative.ReplaceChildren(0, 0, translatedElement); if (alternative.ChildCount == 0) { adaptor.AddChild(alternative, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } Debug.Assert(alternative.ChildCount > 0); return alternative; }
protected virtual GrammarAST ExpandOptionalQuantifiersForAlt(GrammarAST alt) { if (alt.ChildCount == 0) { return null; } if (alt.GetChild(0).Type == ANTLRParser.OPTIONAL) { GrammarAST root = (GrammarAST)adaptor.Nil(); GrammarAST alt2 = alt.DupTree(); alt2.DeleteChild(0); if (alt2.ChildCount == 0) { adaptor.AddChild(alt2, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } alt.SetChild(0, alt.GetChild(0).GetChild(0)); if (alt.GetChild(0).Type == ANTLRParser.BLOCK && alt.GetChild(0).ChildCount == 1 && alt.GetChild(0).GetChild(0).Type == ANTLRParser.ALT) { GrammarAST list = (GrammarAST)adaptor.Nil(); foreach (object tree in ((GrammarAST)alt.GetChild(0).GetChild(0)).Children) { adaptor.AddChild(list, tree); } adaptor.ReplaceChildren(alt, 0, 0, list); } adaptor.AddChild(root, alt); adaptor.AddChild(root, alt2); return root; } else if (alt.GetChild(0).Type == ANTLRParser.CLOSURE) { GrammarAST root = (GrammarAST)adaptor.Nil(); GrammarAST alt2 = alt.DupTree(); alt2.DeleteChild(0); if (alt2.ChildCount == 0) { adaptor.AddChild(alt2, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } PlusBlockAST plusBlockAST = new PlusBlockAST(ANTLRParser.POSITIVE_CLOSURE, adaptor.CreateToken(ANTLRParser.POSITIVE_CLOSURE, "+"), null); for (int i = 0; i < alt.GetChild(0).ChildCount; i++) { plusBlockAST.AddChild(alt.GetChild(0).GetChild(i)); } alt.SetChild(0, plusBlockAST); adaptor.AddChild(root, alt); adaptor.AddChild(root, alt2); return root; } return alt; }
protected virtual bool ExpandOptionalQuantifiersForBlock(GrammarAST block, bool variant) { IList<GrammarAST> children = new List<GrammarAST>(); for (int i = 0; i < block.ChildCount; i++) { GrammarAST child = (GrammarAST)block.GetChild(i); if (child.Type != ANTLRParser.ALT) { children.Add(child); continue; } GrammarAST expandedAlt = ExpandOptionalQuantifiersForAlt(child); if (expandedAlt == null) { return false; } children.Add(expandedAlt); } GrammarAST newChildren = (GrammarAST)adaptor.Nil(); newChildren.AddChildren(children); block.ReplaceChildren(0, block.ChildCount - 1, newChildren); block.FreshenParentAndChildIndexesDeeply(); if (!variant && block.Parent is RuleAST) { RuleAST ruleAST = (RuleAST)block.Parent; string ruleName = ruleAST.GetChild(0).Text; Rule r = _rules[ruleName]; IList<GrammarAST> blockAlts = block.GetAllChildrenWithType(ANTLRParser.ALT); r.numberOfAlts = blockAlts.Count; r.alt = new Alternative[blockAlts.Count + 1]; for (int i = 0; i < blockAlts.Count; i++) { r.alt[i + 1] = new Alternative(r, i + 1); r.alt[i + 1].ast = (AltAST)blockAlts[i]; } } return true; }
public virtual void DefineAction(GrammarAST atAST) { if (atAST.ChildCount == 2) { string name = atAST.GetChild(0).Text; namedActions[name] = (ActionAST)atAST.GetChild(1); } else { string scope = atAST.GetChild(0).Text; string gtype = GetTypeString(); if (scope.Equals(gtype) || (scope.Equals("parser") && gtype.Equals("combined"))) { string name = atAST.GetChild(1).Text; namedActions[name] = (ActionAST)atAST.GetChild(2); } } }
// TODO: this strips the tree properly, but since text() // uses the start of stop token index and gets text from that // ineffectively ignores this routine. public virtual GrammarAST StripLeftRecursion(GrammarAST altAST) { GrammarAST lrlabel = null; GrammarAST first = (GrammarAST)altAST.GetChild(0); int leftRecurRuleIndex = 0; if (first.Type == ELEMENT_OPTIONS) { first = (GrammarAST)altAST.GetChild(1); leftRecurRuleIndex = 1; } ITree rref = first.GetChild(1); // if label=rule if ((first.Type == RULE_REF && first.Text.Equals(ruleName)) || (rref != null && rref.Type == RULE_REF && rref.Text.Equals(ruleName))) { if (first.Type == ASSIGN || first.Type == PLUS_ASSIGN) lrlabel = (GrammarAST)first.GetChild(0); // remove rule ref (first child unless options present) altAST.DeleteChild(leftRecurRuleIndex); // reset index so it prints properly (sets token range of // ALT to start to right of left recur rule we deleted) GrammarAST newFirstChild = (GrammarAST)altAST.GetChild(leftRecurRuleIndex); altAST.TokenStartIndex = newFirstChild.TokenStartIndex; } return lrlabel; }