use of org.antlr.v4.codegen.model.CodeBlockForAlt in project antlr4 by antlr.
the class ParserFactory method getComplexEBNFBlock.
@Override
public Choice getComplexEBNFBlock(GrammarAST ebnfRoot, List<CodeBlockForAlt> alts) {
int ebnf = 0;
if (ebnfRoot != null)
ebnf = ebnfRoot.getType();
Choice c = null;
switch(ebnf) {
case ANTLRParser.OPTIONAL:
c = new OptionalBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.CLOSURE:
c = new StarBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.POSITIVE_CLOSURE:
c = new PlusBlock(this, ebnfRoot, alts);
break;
}
return c;
}
use of org.antlr.v4.codegen.model.CodeBlockForAlt in project antlr4 by antlr.
the class OutputModelController method buildLeftRecursiveRuleFunction.
public void buildLeftRecursiveRuleFunction(LeftRecursiveRule r, LeftRecursiveRuleFunction function) {
buildNormalRuleFunction(r, function);
// now inject code to start alts
CodeGenerator gen = delegate.getGenerator();
STGroup codegenTemplates = gen.getTemplates();
// pick out alt(s) for primaries
CodeBlockForOuterMostAlt outerAlt = (CodeBlockForOuterMostAlt) function.code.get(0);
List<CodeBlockForAlt> primaryAltsCode = new ArrayList<CodeBlockForAlt>();
SrcOp primaryStuff = outerAlt.ops.get(0);
if (primaryStuff instanceof Choice) {
Choice primaryAltBlock = (Choice) primaryStuff;
primaryAltsCode.addAll(primaryAltBlock.alts);
} else {
// just a single alt I guess; no block
primaryAltsCode.add((CodeBlockForAlt) primaryStuff);
}
// pick out alt(s) for op alts
StarBlock opAltStarBlock = (StarBlock) outerAlt.ops.get(1);
CodeBlockForAlt altForOpAltBlock = opAltStarBlock.alts.get(0);
List<CodeBlockForAlt> opAltsCode = new ArrayList<CodeBlockForAlt>();
SrcOp opStuff = altForOpAltBlock.ops.get(0);
if (opStuff instanceof AltBlock) {
AltBlock opAltBlock = (AltBlock) opStuff;
opAltsCode.addAll(opAltBlock.alts);
} else {
// just a single alt I guess; no block
opAltsCode.add((CodeBlockForAlt) opStuff);
}
// Insert code in front of each primary alt to create specialized ctx if there was a label
for (int i = 0; i < primaryAltsCode.size(); i++) {
LeftRecursiveRuleAltInfo altInfo = r.recPrimaryAlts.get(i);
if (altInfo.altLabel == null)
continue;
ST altActionST = codegenTemplates.getInstanceOf("recRuleReplaceContext");
altActionST.add("ctxName", Utils.capitalize(altInfo.altLabel));
Action altAction = new Action(delegate, function.altLabelCtxs.get(altInfo.altLabel), altActionST);
CodeBlockForAlt alt = primaryAltsCode.get(i);
alt.insertOp(0, altAction);
}
// Insert code to set ctx.stop after primary block and before op * loop
ST setStopTokenAST = codegenTemplates.getInstanceOf("recRuleSetStopToken");
Action setStopTokenAction = new Action(delegate, function.ruleCtx, setStopTokenAST);
outerAlt.insertOp(1, setStopTokenAction);
// Insert code to set _prevctx at start of * loop
ST setPrevCtx = codegenTemplates.getInstanceOf("recRuleSetPrevCtx");
Action setPrevCtxAction = new Action(delegate, function.ruleCtx, setPrevCtx);
opAltStarBlock.addIterationOp(setPrevCtxAction);
// Insert code in front of each op alt to create specialized ctx if there was an alt label
for (int i = 0; i < opAltsCode.size(); i++) {
ST altActionST;
LeftRecursiveRuleAltInfo altInfo = r.recOpAlts.getElement(i);
String templateName;
if (altInfo.altLabel != null) {
templateName = "recRuleLabeledAltStartAction";
altActionST = codegenTemplates.getInstanceOf(templateName);
altActionST.add("currentAltLabel", altInfo.altLabel);
} else {
templateName = "recRuleAltStartAction";
altActionST = codegenTemplates.getInstanceOf(templateName);
altActionST.add("ctxName", Utils.capitalize(r.name));
}
altActionST.add("ruleName", r.name);
// add label of any lr ref we deleted
altActionST.add("label", altInfo.leftRecursiveRuleRefLabel);
if (altActionST.impl.formalArguments.containsKey("isListLabel")) {
altActionST.add("isListLabel", altInfo.isListLabel);
} else if (altInfo.isListLabel) {
delegate.getGenerator().tool.errMgr.toolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, "isListLabel");
}
Action altAction = new Action(delegate, function.altLabelCtxs.get(altInfo.altLabel), altActionST);
CodeBlockForAlt alt = opAltsCode.get(i);
alt.insertOp(0, altAction);
}
}
use of org.antlr.v4.codegen.model.CodeBlockForAlt in project antlr4 by antlr.
the class ParserFactory method getChoiceBlock.
@Override
public Choice getChoiceBlock(BlockAST blkAST, List<CodeBlockForAlt> alts, GrammarAST labelAST) {
int decision = ((DecisionState) blkAST.atnState).decision;
Choice c;
if (!g.tool.force_atn && AnalysisPipeline.disjoint(g.decisionLOOK.get(decision))) {
c = getLL1ChoiceBlock(blkAST, alts);
} else {
c = getComplexChoiceBlock(blkAST, alts);
}
if (labelAST != null) {
// for x=(...), define x or x_list
String label = labelAST.getText();
Decl d = getTokenLabelDecl(label);
c.label = d;
getCurrentRuleFunction().addContextDecl(labelAST.getAltLabel(), d);
if (labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN) {
String listLabel = gen.getTarget().getListLabel(label);
TokenListDecl l = new TokenListDecl(this, listLabel);
getCurrentRuleFunction().addContextDecl(labelAST.getAltLabel(), l);
}
}
return c;
}
use of org.antlr.v4.codegen.model.CodeBlockForAlt in project antlr4 by antlr.
the class ParserFactory method getLL1EBNFBlock.
@Override
public Choice getLL1EBNFBlock(GrammarAST ebnfRoot, List<CodeBlockForAlt> alts) {
int ebnf = 0;
if (ebnfRoot != null)
ebnf = ebnfRoot.getType();
Choice c = null;
switch(ebnf) {
case ANTLRParser.OPTIONAL:
if (alts.size() == 1)
c = new LL1OptionalBlockSingleAlt(this, ebnfRoot, alts);
else
c = new LL1OptionalBlock(this, ebnfRoot, alts);
break;
case ANTLRParser.CLOSURE:
if (alts.size() == 1)
c = new LL1StarBlockSingleAlt(this, ebnfRoot, alts);
else
c = getComplexEBNFBlock(ebnfRoot, alts);
break;
case ANTLRParser.POSITIVE_CLOSURE:
if (alts.size() == 1)
c = new LL1PlusBlockSingleAlt(this, ebnfRoot, alts);
else
c = getComplexEBNFBlock(ebnfRoot, alts);
break;
}
return c;
}
Aggregations