/* * ****************************************************************************** * 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.symboltable; import java.io.File; import java.util.Collection; import java.util.stream.Collectors; import de.monticore.generating.GeneratorEngine; import de.monticore.generating.GeneratorSetup; import de.monticore.generating.templateengine.GlobalExtensionManagement; import de.monticore.grammar.grammar._ast.ASTMCGrammar; import de.monticore.grammar.symboltable.MCGrammarSymbol; import de.monticore.grammar.symboltable.MCProdSymbol; import de.monticore.io.paths.IterablePath; import de.se_rwth.commons.Names; import de.se_rwth.commons.logging.Log; /** * @author Pedram Mir Seyed Nazari */ public class SymbolTableGenerator { public static final String PACKAGE = "_symboltable"; public static final String LOG = SymbolTableGenerator.class.getSimpleName(); private final ModelingLanguageGenerator modelingLanguageGenerator; private final ModelLoaderGenerator modelLoaderGenerator; private final ModelNameCalculatorGenerator modelNameCalculatorGenerator; private final ResolvingFilterGenerator resolvingFilterGenerator; private final SymbolGenerator symbolGenerator; private final SymbolKindGenerator symbolKindGenerator; private final ScopeSpanningSymbolGenerator scopeSpanningSymbolGenerator; private final SymbolReferenceGenerator symbolReferenceGenerator; private final SymbolTableCreatorGenerator symbolTableCreatorGenerator; protected SymbolTableGenerator( ModelingLanguageGenerator modelingLanguageGenerator, ModelLoaderGenerator modelLoaderGenerator, ModelNameCalculatorGenerator modelNameCalculatorGenerator, ResolvingFilterGenerator resolvingFilterGenerator, SymbolGenerator symbolGenerator, SymbolKindGenerator symbolKindGenerator, ScopeSpanningSymbolGenerator scopeSpanningSymbolGenerator, SymbolReferenceGenerator symbolReferenceGenerator, SymbolTableCreatorGenerator symbolTableCreatorGenerator) { this.modelingLanguageGenerator = modelingLanguageGenerator; this.modelLoaderGenerator = modelLoaderGenerator; this.modelNameCalculatorGenerator = modelNameCalculatorGenerator; this.resolvingFilterGenerator = resolvingFilterGenerator; this.symbolGenerator = symbolGenerator; this.symbolKindGenerator = symbolKindGenerator; this.scopeSpanningSymbolGenerator = scopeSpanningSymbolGenerator; this.symbolReferenceGenerator = symbolReferenceGenerator; this.symbolTableCreatorGenerator = symbolTableCreatorGenerator; } public void generate(ASTMCGrammar astGrammar, SymbolTableGeneratorHelper genHelper, File outputPath, final IterablePath handCodedPath) { MCGrammarSymbol grammarSymbol = genHelper.getGrammarSymbol(); // TODO PN also generate for components grammars everything that is possible // and useful. if (grammarSymbol.isComponent()) { return; } // Skip generation if no rules are defined in the grammar, since no top asts // will be generated. if (!grammarSymbol.getStartProd().isPresent()) { return; } Log.debug("Start symbol table generation for the grammar " + astGrammar.getName(), LOG); // TODO PN consider only class rules? final Collection<MCProdSymbol> allSymbolDefiningRules = genHelper.getAllSymbolDefiningRules(); final Collection<String> ruleNames = allSymbolDefiningRules.stream() .map(MCProdSymbol::getName).collect(Collectors.toSet()); /* If no rules with name are defined, no symbols can be generated. Hence, * skip generation of: ModelNameCalculator, SymbolTableCreator, Symbol, * SymbolKind, SymbolReference, ScopeSpanningSymbol, (Spanned) Scope and * ResolvingFilter */ final boolean skipSymbolTableGeneration = allSymbolDefiningRules.isEmpty(); final GeneratorSetup setup = new GeneratorSetup(outputPath); GlobalExtensionManagement glex = new GlobalExtensionManagement(); glex.setGlobalValue("stHelper", genHelper); glex.setGlobalValue("nameHelper", new Names()); glex.setGlobalValue("skipSTGen", skipSymbolTableGeneration); setup.setGlex(glex); final GeneratorEngine genEngine = new GeneratorEngine(setup); modelingLanguageGenerator.generate(genEngine, genHelper, handCodedPath, grammarSymbol, ruleNames); modelLoaderGenerator.generate(genEngine, genHelper, handCodedPath, grammarSymbol); if (!skipSymbolTableGeneration) { modelNameCalculatorGenerator.generate(genEngine, genHelper, handCodedPath, grammarSymbol, ruleNames); symbolTableCreatorGenerator.generate(genEngine, genHelper, handCodedPath, grammarSymbol); for (MCProdSymbol ruleSymbol : allSymbolDefiningRules) { generateSymbolOrScopeSpanningSymbol(genEngine, genHelper, ruleSymbol, handCodedPath); symbolKindGenerator.generate(genEngine, genHelper, handCodedPath, ruleSymbol); symbolReferenceGenerator.generate(genEngine, genHelper, handCodedPath, ruleSymbol, genHelper.isScopeSpanningSymbol(ruleSymbol)); resolvingFilterGenerator.generate(genEngine, genHelper, handCodedPath, ruleSymbol); } } Log.debug("End symbol table generation for the grammar " + astGrammar.getName(), LOG); } private void generateSymbolOrScopeSpanningSymbol(GeneratorEngine genEngine, SymbolTableGeneratorHelper genHelper, MCProdSymbol ruleSymbol, IterablePath handCodedPath) { if (ruleSymbol.getAstNode().isPresent()) { if (!genHelper.isScopeSpanningSymbol(ruleSymbol)) { symbolGenerator.generate(genEngine, genHelper, handCodedPath, ruleSymbol); } else { scopeSpanningSymbolGenerator.generate(genEngine, genHelper, handCodedPath, ruleSymbol); } } } }