Search in sources :

Example 26 with CodeGenerator

use of org.antlr.v4.codegen.CodeGenerator in project antlr4 by antlr.

the class OutputModelController method buildNormalRuleFunction.

public void buildNormalRuleFunction(Rule r, RuleFunction function) {
    CodeGenerator gen = delegate.getGenerator();
    // TRIGGER factory functions for rule alts, elements
    GrammarASTAdaptor adaptor = new GrammarASTAdaptor(r.ast.token.getInputStream());
    GrammarAST blk = (GrammarAST) r.ast.getFirstChildWithType(ANTLRParser.BLOCK);
    CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor, blk);
    walker = new SourceGenTriggers(nodes, this);
    try {
        // walk AST of rule alts/elements
        function.code = DefaultOutputModelFactory.list(walker.block(null, null));
        function.hasLookaheadBlock = walker.hasLookaheadBlock;
    } catch (org.antlr.runtime.RecognitionException e) {
        e.printStackTrace(System.err);
    }
    function.ctxType = gen.getTarget().getRuleFunctionContextStructName(function);
    function.postamble = rulePostamble(function, r);
}
Also used : GrammarAST(org.antlr.v4.tool.ast.GrammarAST) GrammarASTAdaptor(org.antlr.v4.parse.GrammarASTAdaptor) CommonTreeNodeStream(org.antlr.runtime.tree.CommonTreeNodeStream)

Example 27 with CodeGenerator

use of org.antlr.v4.codegen.CodeGenerator 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);
    }
}
Also used : GrammarAST(org.antlr.v4.tool.ast.GrammarAST) ActionAST(org.antlr.v4.tool.ast.ActionAST) BlockAST(org.antlr.v4.tool.ast.BlockAST) ST(org.stringtemplate.v4.ST) PredAST(org.antlr.v4.tool.ast.PredAST) Action(org.antlr.v4.codegen.model.Action) SrcOp(org.antlr.v4.codegen.model.SrcOp) Choice(org.antlr.v4.codegen.model.Choice) STGroup(org.stringtemplate.v4.STGroup) ArrayList(java.util.ArrayList) StarBlock(org.antlr.v4.codegen.model.StarBlock) CodeBlockForOuterMostAlt(org.antlr.v4.codegen.model.CodeBlockForOuterMostAlt) CodeBlockForAlt(org.antlr.v4.codegen.model.CodeBlockForAlt) AltBlock(org.antlr.v4.codegen.model.AltBlock) LeftRecursiveRuleAltInfo(org.antlr.v4.analysis.LeftRecursiveRuleAltInfo)

Example 28 with CodeGenerator

use of org.antlr.v4.codegen.CodeGenerator in project antlr4 by antlr.

the class DefaultOutputModelFactory method rulePostamble.

@Override
public List<SrcOp> rulePostamble(RuleFunction function, Rule r) {
    if (r.namedActions.containsKey("after") || r.namedActions.containsKey("finally")) {
        // See OutputModelController.buildLeftRecursiveRuleFunction
        // and Parser.exitRule for other places which set stop.
        CodeGenerator gen = getGenerator();
        STGroup codegenTemplates = gen.getTemplates();
        ST setStopTokenAST = codegenTemplates.getInstanceOf("recRuleSetStopToken");
        Action setStopTokenAction = new Action(this, function.ruleCtx, setStopTokenAST);
        List<SrcOp> ops = new ArrayList<SrcOp>(1);
        ops.add(setStopTokenAction);
        return ops;
    }
    return super.rulePostamble(function, r);
}
Also used : ST(org.stringtemplate.v4.ST) Action(org.antlr.v4.codegen.model.Action) SrcOp(org.antlr.v4.codegen.model.SrcOp) STGroup(org.stringtemplate.v4.STGroup) ArrayList(java.util.ArrayList)

Example 29 with CodeGenerator

use of org.antlr.v4.codegen.CodeGenerator in project antlr4 by antlr.

the class OutputModelController method buildLexerRuleActions.

public void buildLexerRuleActions(Lexer lexer, final Rule r) {
    if (r.actions.isEmpty()) {
        return;
    }
    CodeGenerator gen = delegate.getGenerator();
    Grammar g = delegate.getGrammar();
    String ctxType = gen.getTarget().getRuleFunctionContextStructName(r);
    RuleActionFunction raf = lexer.actionFuncs.get(r);
    if (raf == null) {
        raf = new RuleActionFunction(delegate, r, ctxType);
    }
    for (ActionAST a : r.actions) {
        if (a instanceof PredAST) {
            PredAST p = (PredAST) a;
            RuleSempredFunction rsf = lexer.sempredFuncs.get(r);
            if (rsf == null) {
                rsf = new RuleSempredFunction(delegate, r, ctxType);
                lexer.sempredFuncs.put(r, rsf);
            }
            rsf.actions.put(g.sempreds.get(p), new Action(delegate, p));
        } else if (a.getType() == ANTLRParser.ACTION) {
            raf.actions.put(g.lexerActions.get(a), new Action(delegate, a));
        }
    }
    if (!raf.actions.isEmpty() && !lexer.actionFuncs.containsKey(r)) {
        // only add to lexer if the function actually contains actions
        lexer.actionFuncs.put(r, raf);
    }
}
Also used : RuleActionFunction(org.antlr.v4.codegen.model.RuleActionFunction) Action(org.antlr.v4.codegen.model.Action) PredAST(org.antlr.v4.tool.ast.PredAST) RuleSempredFunction(org.antlr.v4.codegen.model.RuleSempredFunction) Grammar(org.antlr.v4.tool.Grammar) ActionAST(org.antlr.v4.tool.ast.ActionAST)

Example 30 with CodeGenerator

use of org.antlr.v4.codegen.CodeGenerator in project antlr4 by antlr.

the class CodeGenPipeline method process.

public void process() {
    if (!CodeGenerator.targetExists(g.getOptionString("language")))
        return;
    CodeGenerator gen = new CodeGenerator(g);
    IntervalSet idTypes = new IntervalSet();
    idTypes.add(ANTLRParser.ID);
    idTypes.add(ANTLRParser.RULE_REF);
    idTypes.add(ANTLRParser.TOKEN_REF);
    List<GrammarAST> idNodes = g.ast.getNodesWithType(idTypes);
    for (GrammarAST idNode : idNodes) {
        if (gen.getTarget().grammarSymbolCausesIssueInGeneratedCode(idNode)) {
            g.tool.errMgr.grammarError(ErrorType.USE_OF_BAD_WORD, g.fileName, idNode.getToken(), idNode.getText());
        }
    }
    // all templates are generated in memory to report the most complete
    // error information possible, but actually writing output files stops
    // after the first error is reported
    int errorCount = g.tool.errMgr.getNumErrors();
    if (g.isLexer()) {
        if (gen.getTarget().needsHeader()) {
            // Header file if needed.
            ST lexer = gen.generateLexer(true);
            if (g.tool.errMgr.getNumErrors() == errorCount) {
                writeRecognizer(lexer, gen, true);
            }
        }
        ST lexer = gen.generateLexer(false);
        if (g.tool.errMgr.getNumErrors() == errorCount) {
            writeRecognizer(lexer, gen, false);
        }
    } else {
        if (gen.getTarget().needsHeader()) {
            ST parser = gen.generateParser(true);
            if (g.tool.errMgr.getNumErrors() == errorCount) {
                writeRecognizer(parser, gen, true);
            }
        }
        ST parser = gen.generateParser(false);
        if (g.tool.errMgr.getNumErrors() == errorCount) {
            writeRecognizer(parser, gen, false);
        }
        if (g.tool.gen_listener) {
            if (gen.getTarget().needsHeader()) {
                ST listener = gen.generateListener(true);
                if (g.tool.errMgr.getNumErrors() == errorCount) {
                    gen.writeListener(listener, true);
                }
            }
            ST listener = gen.generateListener(false);
            if (g.tool.errMgr.getNumErrors() == errorCount) {
                gen.writeListener(listener, false);
            }
            if (gen.getTarget().needsHeader()) {
                ST baseListener = gen.generateBaseListener(true);
                if (g.tool.errMgr.getNumErrors() == errorCount) {
                    gen.writeBaseListener(baseListener, true);
                }
            }
            if (gen.getTarget().wantsBaseListener()) {
                ST baseListener = gen.generateBaseListener(false);
                if (g.tool.errMgr.getNumErrors() == errorCount) {
                    gen.writeBaseListener(baseListener, false);
                }
            }
        }
        if (g.tool.gen_visitor) {
            if (gen.getTarget().needsHeader()) {
                ST visitor = gen.generateVisitor(true);
                if (g.tool.errMgr.getNumErrors() == errorCount) {
                    gen.writeVisitor(visitor, true);
                }
            }
            ST visitor = gen.generateVisitor(false);
            if (g.tool.errMgr.getNumErrors() == errorCount) {
                gen.writeVisitor(visitor, false);
            }
            if (gen.getTarget().needsHeader()) {
                ST baseVisitor = gen.generateBaseVisitor(true);
                if (g.tool.errMgr.getNumErrors() == errorCount) {
                    gen.writeBaseVisitor(baseVisitor, true);
                }
            }
            if (gen.getTarget().wantsBaseVisitor()) {
                ST baseVisitor = gen.generateBaseVisitor(false);
                if (g.tool.errMgr.getNumErrors() == errorCount) {
                    gen.writeBaseVisitor(baseVisitor, false);
                }
            }
        }
    }
    gen.writeVocabFile();
}
Also used : ST(org.stringtemplate.v4.ST) GrammarAST(org.antlr.v4.tool.ast.GrammarAST) IntervalSet(org.antlr.v4.runtime.misc.IntervalSet) GrammarAST(org.antlr.v4.tool.ast.GrammarAST)

Aggregations

Grammar (org.antlr.v4.tool.Grammar)21 CodeGenerator (org.antlr.v4.codegen.CodeGenerator)17 ST (org.stringtemplate.v4.ST)15 STGroup (org.stringtemplate.v4.STGroup)11 LexerGrammar (org.antlr.v4.tool.LexerGrammar)10 ATNFactory (org.antlr.v4.automata.ATNFactory)9 LexerATNFactory (org.antlr.v4.automata.LexerATNFactory)9 ParserATNFactory (org.antlr.v4.automata.ParserATNFactory)9 SemanticPipeline (org.antlr.v4.semantics.SemanticPipeline)9 STGroupString (org.stringtemplate.v4.STGroupString)7 ErrorQueue (org.antlr.v4.test.runtime.ErrorQueue)6 GrammarAST (org.antlr.v4.tool.ast.GrammarAST)6 ArrayList (java.util.ArrayList)5 Action (org.antlr.v4.codegen.model.Action)5 BaseRuntimeTest.antlrOnString (org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString)5 LeftRecursiveRule (org.antlr.v4.tool.LeftRecursiveRule)4 Rule (org.antlr.v4.tool.Rule)4 SrcOp (org.antlr.v4.codegen.model.SrcOp)3 IntervalSet (org.antlr.v4.runtime.misc.IntervalSet)3 ActionAST (org.antlr.v4.tool.ast.ActionAST)3