/* * ****************************************************************************** * MontiCore Language Workbench * Copyright (c) 2015, MontiCore, All rights reserved. * * This project is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this project. If not, see <http://www.gnu.org/licenses/>. * ****************************************************************************** */ package de.monticore.codegen.parser.antlr; import java.util.Optional; import de.monticore.codegen.cd2java.ast.AstGeneratorHelper; import de.monticore.codegen.mc2cd.MCGrammarSymbolTableHelper; import de.monticore.codegen.parser.ParserGeneratorHelper; import de.monticore.grammar.HelperGrammar; import de.monticore.grammar.grammar._ast.ASTClassProd; import de.monticore.grammar.grammar._ast.ASTConstant; import de.monticore.grammar.grammar._ast.ASTConstantGroup; import de.monticore.grammar.grammar._ast.ASTNonTerminal; import de.monticore.grammar.grammar._ast.ASTTerminal; import de.monticore.grammar.symboltable.MCGrammarSymbol; import de.monticore.grammar.symboltable.MCProdSymbol; import de.se_rwth.commons.Names; import de.se_rwth.commons.StringTransformations; public class ASTConstructionActions { private final static String DEFAULT_RETURN_PARAM = "ret"; protected ParserGeneratorHelper parserGenHelper; protected MCGrammarSymbol symbolTable; public ASTConstructionActions(ParserGeneratorHelper parserGenHelper) { this.parserGenHelper = parserGenHelper; this.symbolTable = parserGenHelper.getGrammarSymbol(); } public String getConstantInConstantGroupMultipleEntries(ASTConstant constant, ASTConstantGroup constgroup) { String tmp = ""; if (constgroup.getUsageName().isPresent()) { String constfile; String constantname; Optional<MCProdSymbol> rule = MCGrammarSymbolTableHelper .getEnclosingRule(constgroup); Optional<MCGrammarSymbol> ruleGrammar = MCGrammarSymbolTableHelper .getMCGrammarSymbol(constgroup); if (ruleGrammar.isPresent()) { constfile = AstGeneratorHelper.getConstantClassName(ruleGrammar.get()); constantname = parserGenHelper.getConstantNameForConstant(constant); } else { constfile = AstGeneratorHelper.getConstantClassName(symbolTable); constantname = parserGenHelper.getConstantNameForConstant(constant); } // Add as attribute to AST tmp = "_aNode.set%uname%(%constfile%.%constantname%);"; tmp = tmp.replaceAll("%uname%", StringTransformations.capitalize(constgroup.getUsageName().get())); tmp = tmp.replaceAll("%constfile%", constfile); tmp = tmp.replaceAll("%constantname%", constantname); } return tmp; } public String getActionAfterConstantInEnumProdSingle(ASTConstant c) { return "ret = true ;"; } public String getActionAfterConstantInEnumProdIterated(ASTConstant c) { String constfile; String constantname; Optional<MCProdSymbol> rule = MCGrammarSymbolTableHelper.getEnclosingRule(c); Optional<MCGrammarSymbol> ruleGrammar = MCGrammarSymbolTableHelper .getMCGrammarSymbol(c); if (ruleGrammar.isPresent()) { constfile = AstGeneratorHelper.getConstantClassName(ruleGrammar.get()); constantname = parserGenHelper.getConstantNameForConstant(c); } else { constfile = AstGeneratorHelper.getConstantClassName(symbolTable); constantname = parserGenHelper.getConstantNameForConstant(c); } return "ret = " + constfile + "." + constantname + ";"; } public String getConstantInConstantGroupSingleEntry(ASTConstant constant, ASTConstantGroup constgroup) { String tmp = ""; if (constgroup.getUsageName().isPresent()) { // Add as attribute to AST tmp = "_aNode.set%uname%(true);"; tmp = tmp.replaceAll("%uname%", StringTransformations.capitalize(constgroup.getUsageName().get())); } else { if (constgroup.getConstants().size() == 1) { // both == null and #constants == 1 -> use constant string as name tmp = "_aNode.set%cname%(true);"; tmp = tmp.replaceAll("%cname%", StringTransformations.capitalize(HelperGrammar .getAttributeNameForConstant(constgroup.getConstants().get(0)))); } else { // both == null and #constants > 1 -> user wants to ignore token in AST } } return tmp; } public String getActionForRuleBeforeRuleBody(ASTClassProd a) { StringBuilder b = new StringBuilder(); String type = MCGrammarSymbolTableHelper .getQualifiedName(symbolTable.getProdWithInherited(HelperGrammar.getRuleName(a)).get()); Optional<MCGrammarSymbol> grammar = MCGrammarSymbolTableHelper .getMCGrammarSymbol(a); String name = grammar.isPresent() ? grammar.get().getName() : symbolTable.getProdWithInherited(HelperGrammar.getRuleName(a)).get().getName(); // Setup return value b.append( "// ret is normally returned, a is used to be compatible with rule using the return construct\n"); b.append(type + " _aNode = null;\n"); b.append("_aNode=" + Names.getQualifier(type) + "." + name + "NodeFactory.create" + Names.getSimpleName(type) + "();\n"); b.append("$ret=_aNode;\n"); return b.toString(); } public String getActionForRuleBeforeRuleBodyExplicitReturnClass(ASTClassProd a) { StringBuilder b = new StringBuilder(); String type = MCGrammarSymbolTableHelper .getQualifiedName(symbolTable.getProdWithInherited(HelperGrammar.getRuleName(a)).get()); // Setup return value b.append("// ret is normally returned, a can be instanciated later\n"); b.append(type + " _aNode = null;\n"); return b.toString(); } public String getActionForLexerRuleNotIteratedAttribute(ASTNonTerminal a) { String tmp = "_aNode.set%u_usage%(convert" + a.getName() + "($%tmp%));"; // Replace templates tmp = tmp.replaceAll("%u_usage%", StringTransformations.capitalize(HelperGrammar.getUsuageName(a))); tmp = tmp.replaceAll("%tmp%", parserGenHelper.getTmpVarNameForAntlrCode(a)); return tmp; } public String getActionForLexerRuleNotIteratedHandedOn(ASTNonTerminal a) { String tmp = "%handontmp% = convert" + a.getName() + "$%tmp%);"; // Replace templates tmp = tmp.replaceAll("%tmp%", parserGenHelper.getTmpVarNameForAntlrCode(a)); return tmp; } public String getActionForLexerRuleIteratedAttribute(ASTNonTerminal a) { String tmpname = parserGenHelper.getTmpVarNameForAntlrCode(a); String tmp = " addToIteratedAttributeIfNotNull(_aNode.get%u_usage%(), convert" + a.getName() + "($%tmp%));"; // Replace templates tmp = tmp.replaceAll("%u_usage%", StringTransformations.capitalize(HelperGrammar.getUsuageName(a))); tmp = tmp.replaceAll("%tmp%", tmpname); return tmp; } public String getActionForLexerRuleIteratedHandedOn(ASTNonTerminal a) { String tmp = "addToIteratedAttributeIfNotNull(%handontmp%, convert" + a.getName() + "($%tmp%));"; // Replace templates tmp = tmp.replaceAll("%tmp%", parserGenHelper.getTmpVarNameForAntlrCode(a)); return tmp; } public String getActionForInternalRuleIteratedAttribute(ASTNonTerminal a) { String tmp = "addToIteratedAttributeIfNotNull(_aNode.get%u_usage%(), _localctx.%tmp%.ret);"; // TODO GV: || isConst() if (symbolTable.getProdWithInherited(a.getName()).get().isEnum() ) { tmp = "addToIteratedAttributeIfNotNull(_aNode.get%u_usage%(), _localctx.%tmp%.ret);"; } // Replace templates tmp = tmp.replaceAll("%u_usage%", StringTransformations.capitalize(HelperGrammar.getUsuageName(a))); tmp = tmp.replaceAll("%tmp%", parserGenHelper.getTmpVarNameForAntlrCode(a)); return tmp; } public String getActionForInternalRuleNotIteratedAttribute(ASTNonTerminal a) { String tmp = "_aNode.set%u_usage%(_localctx.%tmp%.ret);"; // Replace templates tmp = tmp.replaceAll("%u_usage%", StringTransformations.capitalize(HelperGrammar.getUsuageName(a))); tmp = tmp.replaceAll("%tmp%", parserGenHelper.getTmpVarNameForAntlrCode(a)); return tmp; } public String getActionForInternalRuleNotIteratedLeftRecursiveAttribute(ASTNonTerminal a) { String type = MCGrammarSymbolTableHelper .getQualifiedName(symbolTable.getProdWithInherited(a.getName()).get()); // TODO // GV: // getDefinedType().getQualifiedName() String name = MCGrammarSymbolTableHelper.getMCGrammarSymbol(a).get().getName(); SourcePositionActions sourcePositionBuilder = new SourcePositionActions(parserGenHelper); StringBuilder b = new StringBuilder(); b.append("// Action code for left recursive rule \n"); b.append("_aNode=" + Names.getQualifier(type) + "." + name + "NodeFactory.create" + Names.getSimpleName(type) + "();\n"); b.append(sourcePositionBuilder.startPositionForLeftRecursiveRule(a)); b.append(sourcePositionBuilder.endPositionForLeftRecursiveRule(a)); b.append("$ret=_aNode;\n"); return b.toString(); } /** * Nothing to do for ignore */ public String getActionForTerminalIgnore(ASTTerminal a) { return ""; } public String getActionForTerminalNotIteratedAttribute(ASTTerminal a) { String tmp = "_aNode.set%u_usage%(\"%text%\");"; if (!a.getUsageName().isPresent()) { return ""; } // Replace templates tmp = tmp.replaceAll("%u_usage%", StringTransformations.capitalize(a.getUsageName().get())); tmp = tmp.replaceAll("%text%", a.getName()); return tmp; } public String getActionForTerminalIteratedAttribute(ASTTerminal a) { if (!a.getUsageName().isPresent()) { return ""; } String tmp = "_aNode.get%u_usage%().add(\"%text%\");"; // Replace templates tmp = tmp.replaceAll("%u_usage%", StringTransformations.capitalize(a.getUsageName().get())); tmp = tmp.replaceAll("%text%", a.getName()); return tmp; } }