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 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 bool TranslateLeftFactoredDecision(GrammarAST block, 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."); } if (!ExpandOptionalQuantifiersForBlock(block, variant)) { return(false); } IList <GrammarAST> alternatives = block.GetAllChildrenWithType(ANTLRParser.ALT); GrammarAST[] factoredAlternatives = new GrammarAST[alternatives.Count]; GrammarAST[] unfactoredAlternatives = new GrammarAST[alternatives.Count]; IntervalSet factoredIntervals = new IntervalSet(); IntervalSet unfactoredIntervals = new IntervalSet(); for (int i = 0; i < alternatives.Count; i++) { GrammarAST alternative = alternatives[i]; if (mode.IncludeUnfactoredAlts()) { GrammarAST unfactoredAlt = TranslateLeftFactoredAlternative(alternative.DupTree(), factoredRule, variant, DecisionFactorMode.PARTIAL_UNFACTORED, false); unfactoredAlternatives[i] = unfactoredAlt; if (unfactoredAlt != null) { unfactoredIntervals.Add(i); } } if (mode.IncludeFactoredAlts()) { GrammarAST factoredAlt = TranslateLeftFactoredAlternative(alternative, factoredRule, variant, mode == DecisionFactorMode.COMBINED_FACTOR ? DecisionFactorMode.PARTIAL_FACTORED : DecisionFactorMode.FULL_FACTOR, includeFactoredElement); factoredAlternatives[i] = factoredAlt; if (factoredAlt != null) { factoredIntervals.Add(alternative.ChildIndex); } } } if (factoredIntervals.IsNil && !mode.IncludeUnfactoredAlts()) { return(false); } else if (unfactoredIntervals.IsNil && !mode.IncludeFactoredAlts()) { return(false); } if (unfactoredIntervals.IsNil && factoredIntervals.Count == alternatives.Count && mode.IncludeFactoredAlts() && !includeFactoredElement) { for (int i = 0; i < factoredAlternatives.Length; i++) { GrammarAST translatedAlt = factoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.SetChild(block, i, translatedAlt); } return(true); } else if (factoredIntervals.IsNil && unfactoredIntervals.Count == alternatives.Count && mode.IncludeUnfactoredAlts()) { for (int i = 0; i < unfactoredAlternatives.Length; i++) { GrammarAST translatedAlt = unfactoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.SetChild(block, i, translatedAlt); } return(true); } if (mode == DecisionFactorMode.FULL_FACTOR) { return(false); } /* for a, b, c being arbitrary `element` trees, this block performs * this transformation: * * factoredElement a * | factoredElement b * | factoredElement c * | ... * * ==> * * factoredElement (a | b | c | ...) */ GrammarAST newChildren = (GrammarAST)adaptor.Nil(); for (int i = 0; i < alternatives.Count; i++) { if (mode.IncludeFactoredAlts() && factoredIntervals.Contains(i)) { bool combineWithPrevious = i > 0 && factoredIntervals.Contains(i - 1) && (!mode.IncludeUnfactoredAlts() || !unfactoredIntervals.Contains(i - 1)); if (combineWithPrevious) { GrammarAST translatedAlt = factoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } GrammarAST previous = (GrammarAST)newChildren.GetChild(newChildren.ChildCount - 1); #if false if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, previous.ToStringTree()); LOGGER.log(Level.FINE, translatedAlt.ToStringTree()); } #endif if (previous.ChildCount == 1 || previous.GetChild(1).Type != ANTLRParser.BLOCK) { GrammarAST newBlock = new BlockAST(adaptor.CreateToken(ANTLRParser.BLOCK, "BLOCK")); GrammarAST newAlt = new AltAST(adaptor.CreateToken(ANTLRParser.ALT, "ALT")); adaptor.AddChild(newBlock, newAlt); while (previous.ChildCount > 1) { adaptor.AddChild(newAlt, previous.DeleteChild(1)); } if (newAlt.ChildCount == 0) { adaptor.AddChild(newAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.AddChild(previous, newBlock); } if (translatedAlt.ChildCount == 1 || translatedAlt.GetChild(1).Type != ANTLRParser.BLOCK) { GrammarAST newBlock = new BlockAST(adaptor.CreateToken(ANTLRParser.BLOCK, "BLOCK")); GrammarAST newAlt = new AltAST(adaptor.CreateToken(ANTLRParser.ALT, "ALT")); adaptor.AddChild(newBlock, newAlt); while (translatedAlt.ChildCount > 1) { adaptor.AddChild(newAlt, translatedAlt.DeleteChild(1)); } if (newAlt.ChildCount == 0) { adaptor.AddChild(newAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.AddChild(translatedAlt, newBlock); } GrammarAST combinedBlock = (GrammarAST)previous.GetChild(1); adaptor.AddChild(combinedBlock, translatedAlt.GetChild(1).GetChild(0)); #if false if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, previous.ToStringTree()); } #endif } else { GrammarAST translatedAlt = factoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.AddChild(newChildren, translatedAlt); } } if (mode.IncludeUnfactoredAlts() && unfactoredIntervals.Contains(i)) { GrammarAST translatedAlt = unfactoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.AddChild(newChildren, translatedAlt); } } adaptor.ReplaceChildren(block, 0, block.ChildCount - 1, newChildren); 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); }
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 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 bool TranslateLeftFactoredDecision(GrammarAST block, 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."); } if (!ExpandOptionalQuantifiersForBlock(block, variant)) { return false; } IList<GrammarAST> alternatives = block.GetAllChildrenWithType(ANTLRParser.ALT); GrammarAST[] factoredAlternatives = new GrammarAST[alternatives.Count]; GrammarAST[] unfactoredAlternatives = new GrammarAST[alternatives.Count]; IntervalSet factoredIntervals = new IntervalSet(); IntervalSet unfactoredIntervals = new IntervalSet(); for (int i = 0; i < alternatives.Count; i++) { GrammarAST alternative = alternatives[i]; if (mode.IncludeUnfactoredAlts()) { GrammarAST unfactoredAlt = TranslateLeftFactoredAlternative(alternative.DupTree(), factoredRule, variant, DecisionFactorMode.PARTIAL_UNFACTORED, false); unfactoredAlternatives[i] = unfactoredAlt; if (unfactoredAlt != null) { unfactoredIntervals.Add(i); } } if (mode.IncludeFactoredAlts()) { GrammarAST factoredAlt = TranslateLeftFactoredAlternative(alternative, factoredRule, variant, mode == DecisionFactorMode.COMBINED_FACTOR ? DecisionFactorMode.PARTIAL_FACTORED : DecisionFactorMode.FULL_FACTOR, includeFactoredElement); factoredAlternatives[i] = factoredAlt; if (factoredAlt != null) { factoredIntervals.Add(alternative.ChildIndex); } } } if (factoredIntervals.IsNil && !mode.IncludeUnfactoredAlts()) { return false; } else if (unfactoredIntervals.IsNil && !mode.IncludeFactoredAlts()) { return false; } if (unfactoredIntervals.IsNil && factoredIntervals.Count == alternatives.Count && mode.IncludeFactoredAlts() && !includeFactoredElement) { for (int i = 0; i < factoredAlternatives.Length; i++) { GrammarAST translatedAlt = factoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.SetChild(block, i, translatedAlt); } return true; } else if (factoredIntervals.IsNil && unfactoredIntervals.Count == alternatives.Count && mode.IncludeUnfactoredAlts()) { for (int i = 0; i < unfactoredAlternatives.Length; i++) { GrammarAST translatedAlt = unfactoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.SetChild(block, i, translatedAlt); } return true; } if (mode == DecisionFactorMode.FULL_FACTOR) { return false; } /* for a, b, c being arbitrary `element` trees, this block performs * this transformation: * * factoredElement a * | factoredElement b * | factoredElement c * | ... * * ==> * * factoredElement (a | b | c | ...) */ GrammarAST newChildren = (GrammarAST)adaptor.Nil(); for (int i = 0; i < alternatives.Count; i++) { if (mode.IncludeFactoredAlts() && factoredIntervals.Contains(i)) { bool combineWithPrevious = i > 0 && factoredIntervals.Contains(i - 1) && (!mode.IncludeUnfactoredAlts() || !unfactoredIntervals.Contains(i - 1)); if (combineWithPrevious) { GrammarAST translatedAlt = factoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } GrammarAST previous = (GrammarAST)newChildren.GetChild(newChildren.ChildCount - 1); #if false if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, previous.ToStringTree()); LOGGER.log(Level.FINE, translatedAlt.ToStringTree()); } #endif if (previous.ChildCount == 1 || previous.GetChild(1).Type != ANTLRParser.BLOCK) { GrammarAST newBlock = new BlockAST(adaptor.CreateToken(ANTLRParser.BLOCK, "BLOCK")); GrammarAST newAlt = new AltAST(adaptor.CreateToken(ANTLRParser.ALT, "ALT")); adaptor.AddChild(newBlock, newAlt); while (previous.ChildCount > 1) { adaptor.AddChild(newAlt, previous.DeleteChild(1)); } if (newAlt.ChildCount == 0) { adaptor.AddChild(newAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.AddChild(previous, newBlock); } if (translatedAlt.ChildCount == 1 || translatedAlt.GetChild(1).Type != ANTLRParser.BLOCK) { GrammarAST newBlock = new BlockAST(adaptor.CreateToken(ANTLRParser.BLOCK, "BLOCK")); GrammarAST newAlt = new AltAST(adaptor.CreateToken(ANTLRParser.ALT, "ALT")); adaptor.AddChild(newBlock, newAlt); while (translatedAlt.ChildCount > 1) { adaptor.AddChild(newAlt, translatedAlt.DeleteChild(1)); } if (newAlt.ChildCount == 0) { adaptor.AddChild(newAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.AddChild(translatedAlt, newBlock); } GrammarAST combinedBlock = (GrammarAST)previous.GetChild(1); adaptor.AddChild(combinedBlock, translatedAlt.GetChild(1).GetChild(0)); #if false if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, previous.ToStringTree()); } #endif } else { GrammarAST translatedAlt = factoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.AddChild(newChildren, translatedAlt); } } if (mode.IncludeUnfactoredAlts() && unfactoredIntervals.Contains(i)) { GrammarAST translatedAlt = unfactoredAlternatives[i]; if (translatedAlt.ChildCount == 0) { adaptor.AddChild(translatedAlt, adaptor.Create(ANTLRParser.EPSILON, "EPSILON")); } adaptor.AddChild(newChildren, translatedAlt); } } adaptor.ReplaceChildren(block, 0, block.ChildCount - 1, newChildren); 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; }