protected virtual RuleVariants CreateLeftFactoredRuleVariant(Rule rule, string factoredElement)
{
RuleAST ast = (RuleAST)rule.ast.DupTree();
BlockAST block = (BlockAST)ast.GetFirstChildWithType(ANTLRParser.BLOCK);
RuleAST unfactoredAst = null;
BlockAST unfactoredBlock = null;
if (TranslateLeftFactoredDecision(block, factoredElement, true, DecisionFactorMode.FULL_FACTOR, false))
{
// all alternatives factored
}
else
{
ast = (RuleAST)rule.ast.DupTree();
block = (BlockAST)ast.GetFirstChildWithType(ANTLRParser.BLOCK);
if (!TranslateLeftFactoredDecision(block, factoredElement, true, DecisionFactorMode.PARTIAL_FACTORED, false))
{
// no left factored alts
return RuleVariants.NONE;
}
unfactoredAst = (RuleAST)rule.ast.DupTree();
unfactoredBlock = (BlockAST)unfactoredAst.GetFirstChildWithType(ANTLRParser.BLOCK);
if (!TranslateLeftFactoredDecision(unfactoredBlock, factoredElement, true, DecisionFactorMode.PARTIAL_UNFACTORED, false))
{
throw new InvalidOperationException("expected unfactored alts for partial factorization");
}
}
/*
* factored elements
*/
{
string variantName = ast.GetChild(0).Text + ATNSimulator.RuleLfVariantMarker + factoredElement;
((GrammarAST)ast.GetChild(0)).Token = adaptor.CreateToken(ast.GetChild(0).Type, variantName);
GrammarAST ruleParent = (GrammarAST)rule.ast.Parent;
ruleParent.InsertChild(rule.ast.ChildIndex + 1, ast);
ruleParent.FreshenParentAndChildIndexes(rule.ast.ChildIndex);
IList<GrammarAST> alts = block.GetAllChildrenWithType(ANTLRParser.ALT);
Rule variant = new Rule(_g, ast.GetChild(0).Text, ast, alts.Count);
_g.DefineRule(variant);
for (int i = 0; i < alts.Count; i++)
{
variant.alt[i + 1].ast = (AltAST)alts[i];
}
}
/*
* unfactored elements
*/
if (unfactoredAst != null)
{
string variantName = unfactoredAst.GetChild(0).Text + ATNSimulator.RuleNolfVariantMarker + factoredElement;
((GrammarAST)unfactoredAst.GetChild(0)).Token = adaptor.CreateToken(unfactoredAst.GetChild(0).Type, variantName);
GrammarAST ruleParent = (GrammarAST)rule.ast.Parent;
ruleParent.InsertChild(rule.ast.ChildIndex + 1, unfactoredAst);
ruleParent.FreshenParentAndChildIndexes(rule.ast.ChildIndex);
IList<GrammarAST> alts = unfactoredBlock.GetAllChildrenWithType(ANTLRParser.ALT);
Rule variant = new Rule(_g, unfactoredAst.GetChild(0).Text, unfactoredAst, alts.Count);
_g.DefineRule(variant);
for (int i = 0; i < alts.Count; i++)
{
variant.alt[i + 1].ast = (AltAST)alts[i];
}
}
/*
* result
*/
return unfactoredAst == null ? RuleVariants.FULLY_FACTORED : RuleVariants.PARTIALLY_FACTORED;
}