/*
 * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
 * Use of this file is governed by the BSD 3-clause license that
 * can be found in the LICENSE.txt file in the project root.
 */

package org.antlr.v4.codegen;

import org.antlr.v4.codegen.model.Action;
import org.antlr.v4.codegen.model.CodeBlockForOuterMostAlt;
import org.antlr.v4.codegen.model.OutputModelObject;
import org.antlr.v4.codegen.model.RuleFunction;
import org.antlr.v4.codegen.model.SrcOp;
import org.antlr.v4.codegen.model.decl.CodeBlock;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.Alternative;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.Rule;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

Create output objects for elements *within* rule functions except buildOutputModel() which builds outer/root model object and any objects such as RuleFunction that surround elements in rule functions.
/** Create output objects for elements *within* rule functions except * buildOutputModel() which builds outer/root model object and any * objects such as RuleFunction that surround elements in rule * functions. */
public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory { // Interface to outside world public final Grammar g; public final CodeGenerator gen; public OutputModelController controller; protected DefaultOutputModelFactory(CodeGenerator gen) { this.gen = gen; this.g = gen.g; } @Override public void setController(OutputModelController controller) { this.controller = controller; } @Override public OutputModelController getController() { return controller; } @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); } // Convenience methods @Override public Grammar getGrammar() { return g; } @Override public CodeGenerator getGenerator() { return gen; } @Override public OutputModelObject getRoot() { return controller.getRoot(); } @Override public RuleFunction getCurrentRuleFunction() { return controller.getCurrentRuleFunction(); } @Override public Alternative getCurrentOuterMostAlt() { return controller.getCurrentOuterMostAlt(); } @Override public CodeBlock getCurrentBlock() { return controller.getCurrentBlock(); } @Override public CodeBlockForOuterMostAlt getCurrentOuterMostAlternativeBlock() { return controller.getCurrentOuterMostAlternativeBlock(); } @Override public int getCodeBlockLevel() { return controller.codeBlockLevel; } @Override public int getTreeLevel() { return controller.treeLevel; } // MISC public static List<SrcOp> list(SrcOp... values) { return new ArrayList<SrcOp>(Arrays.asList(values)); } public static List<SrcOp> list(Collection<? extends SrcOp> values) { return new ArrayList<SrcOp>(values); } public Decl getCurrentDeclForName(String name) { if ( getCurrentBlock().locals==null ) return null; for (Decl d : getCurrentBlock().locals.elements()) { if ( d.name.equals(name) ) return d; } return null; } }