Commit 6dabe6ff authored by Thomas Michael Timmermanns's avatar Thomas Michael Timmermanns
Browse files

Removed Generator from repo (see repo EMADL2CPP)

parent 170c13e6
......@@ -48,7 +48,6 @@
<CNNTrain.version>0.2.0-SNAPSHOT</CNNTrain.version>
<Math.version>0.0.11-SNAPSHOT</Math.version>
<Embedded-MontiArc-Math.version>0.0.11-SNAPSHOT</Embedded-MontiArc-Math.version>
<embedded-montiarc-math-generator>0.0.9-SNAPSHOT</embedded-montiarc-math-generator>
<!-- .. Libraries .................................................. -->
<guava.version>18.0</guava.version>
......@@ -200,12 +199,6 @@
<version>${Embedded-MontiArc-Math.version}</version>
</dependency>
<dependency>
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>embedded-montiarc-math-generator</artifactId>
<version>${embedded-montiarc-math-generator}</version>
</dependency>
<dependency>
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>cnn-arch</artifactId>
......
......@@ -29,7 +29,6 @@ import de.monticore.lang.math.math._symboltable.MathLanguage;
import de.monticore.lang.monticar.cnnarch._symboltable.CNNArchLanguage;
import de.monticore.lang.monticar.emadl._parser.EMADLParser;
import de.monticore.lang.monticar.emadl.adapter.PortArraySymbol2IODeclarationSymbolTypeFilter;
import de.monticore.lang.monticar.emadl.adapter.ResolutionDeclarationSymbol2VariableSymbolTypeFilter;
import de.monticore.symboltable.MutableScope;
import de.monticore.symboltable.ResolvingConfiguration;
import de.monticore.symboltable.Symbol;
......
......@@ -20,21 +20,14 @@
*/
package de.monticore.lang.monticar.emadl._symboltable;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._ast.ASTComponent;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._ast.ASTEMACompilationUnit;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.*;
import de.monticore.lang.embeddedmontiarc.helper.ArcTypePrinter;
import de.monticore.lang.monticar.types2._ast.ASTReferenceType;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ComponentSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.EmbeddedMontiArcSymbolTableCreator;
import de.monticore.symboltable.MutableScope;
import de.monticore.symboltable.ResolvingConfiguration;
import de.monticore.symboltable.Scope;
import de.monticore.symboltable.Symbol;
import de.monticore.symboltable.modifiers.BasicAccessModifier;
import de.se_rwth.commons.logging.Log;
import java.util.Collection;
import java.util.Deque;
import java.util.Optional;
public class ModifiedEMASymbolTableCreator extends EmbeddedMontiArcSymbolTableCreator {
......
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* 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.lang.monticar.emadl.generator;
import de.monticore.ModelingLanguageFamily;
import de.monticore.io.paths.ModelPath;
import de.monticore.lang.embeddedmontiarc.LogConfig;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ConstantPortSymbol;
import de.monticore.lang.monticar.emadl._symboltable.EMADLLanguage;
import de.monticore.lang.monticar.enumlang._symboltable.EnumLangLanguage;
import de.monticore.lang.monticar.generator.cpp.converter.MathConverter;
import de.monticore.lang.monticar.generator.optimization.ThreadingOptimizer;
import de.monticore.lang.monticar.generator.order.nfp.TagBreakpointsTagSchema.TagBreakpointsTagSchema;
import de.monticore.lang.monticar.generator.order.nfp.TagDelayTagSchema.TagDelayTagSchema;
import de.monticore.lang.monticar.generator.order.nfp.TagExecutionOrderTagSchema.TagExecutionOrderTagSchema;
import de.monticore.lang.monticar.generator.order.nfp.TagInitTagSchema.TagInitTagSchema;
import de.monticore.lang.monticar.generator.order.nfp.TagMinMaxTagSchema.TagMinMaxTagSchema;
import de.monticore.lang.monticar.generator.order.nfp.TagTableTagSchema.TagTableTagSchema;
import de.monticore.lang.monticar.generator.order.nfp.TagThresholdTagSchema.TagThresholdTagSchema;
import de.monticore.lang.monticar.streamunits._symboltable.StreamUnitsLanguage;
import de.monticore.lang.monticar.struct._symboltable.StructLanguage;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.monticore.symboltable.GlobalScope;
import de.monticore.symboltable.Scope;
import java.nio.file.Paths;
import java.util.Arrays;
public class AbstractSymtab {
public static TaggingResolver createSymTabAndTaggingResolver(String... modelPath) {
Scope scope = createSymTab(modelPath);
TaggingResolver tagging = new TaggingResolver(scope, Arrays.asList(modelPath));
TagMinMaxTagSchema.registerTagTypes(tagging);
TagTableTagSchema.registerTagTypes(tagging);
TagBreakpointsTagSchema.registerTagTypes(tagging);
TagExecutionOrderTagSchema.registerTagTypes(tagging);
TagInitTagSchema.registerTagTypes(tagging);
TagThresholdTagSchema.registerTagTypes(tagging);
TagDelayTagSchema.registerTagTypes(tagging);
return tagging;
}
public static Scope createSymTab(String... modelPath) {
ConstantPortSymbol.resetLastID();
MathConverter.resetIDs();
ThreadingOptimizer.resetID();
ModelingLanguageFamily fam = new ModelingLanguageFamily();
EMADLLanguage montiArcLanguage = new EMADLLanguage();
fam.addModelingLanguage(montiArcLanguage);
fam.addModelingLanguage(new StreamUnitsLanguage());
fam.addModelingLanguage(new StructLanguage());
fam.addModelingLanguage(new EnumLangLanguage());
final ModelPath mp = new ModelPath();
for (String m : modelPath) {
mp.addEntry(Paths.get(m));
}
LogConfig.init();//TODO comment for debug output
GlobalScope scope = new GlobalScope(mp, fam);
de.monticore.lang.monticar.Utils.addBuiltInTypes(scope);
return scope;
}
}
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* 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.lang.monticar.emadl.generator;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import de.monticore.io.paths.ModelPath;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._ast.ASTComponent;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ComponentSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol;
import de.monticore.lang.math.math._symboltable.MathStatementsSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol;
import de.monticore.lang.monticar.cnnarch.generator.CNNArchGenerator;
import de.monticore.lang.monticar.cnntrain._symboltable.CNNTrainLanguage;
import de.monticore.lang.monticar.cnntrain.generator.CNNTrainGenerator;
import de.monticore.lang.monticar.emadl._cocos.EMADLCocos;
import de.monticore.lang.monticar.generator.FileContent;
import de.monticore.lang.monticar.generator.cpp.ArmadilloHelper;
import de.monticore.lang.monticar.generator.cpp.GeneratorCPP;
import de.monticore.lang.monticar.generator.cpp.SimulatorIntegrationHelper;
import de.monticore.lang.monticar.generator.cpp.TypesGeneratorCPP;
import de.monticore.lang.monticar.generator.cpp.converter.TypeConverter;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.monticore.symboltable.GlobalScope;
import de.monticore.symboltable.Scope;
import de.se_rwth.commons.Splitters;
import de.se_rwth.commons.logging.Log;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
public class EMADLGenerator {
public static final String CNN_HELPER = "CNNTranslator";
public static final String CNN_TRAINER = "CNNTrainer";
private GeneratorCPP emamGen;
public EMADLGenerator() {
emamGen = new GeneratorCPP();
emamGen.useArmadilloBackend();
emamGen.setGenerationTargetPath("./target/generated-sources-emadl/");
}
private String modelsPath;
public String getModelsPath() {
return modelsPath;
}
public void setModelsPath(String modelsPath) {
if (!(modelsPath.substring(modelsPath.length() - 1).equals("/"))){
this.modelsPath = modelsPath + "/";
}
else {
this.modelsPath = modelsPath;
}
}
public void setGenerationTargetPath(String generationTargetPath){
if (!(generationTargetPath.substring(generationTargetPath.length() - 1).equals("/"))){
getEmamGen().setGenerationTargetPath(generationTargetPath + "/");
}
else {
getEmamGen().setGenerationTargetPath(generationTargetPath);
}
}
public String getGenerationTargetPath(){
return getEmamGen().getGenerationTargetPath();
}
public GeneratorCPP getEmamGen() {
return emamGen;
}
public void generate(String modelPath, String qualifiedName) throws IOException, TemplateException {
setModelsPath( modelPath );
TaggingResolver symtab = AbstractSymtab.createSymTabAndTaggingResolver(getModelsPath());
ComponentSymbol component = symtab.<ComponentSymbol>resolve(qualifiedName, ComponentSymbol.KIND).orElse(null);
List<String> splitName = Splitters.DOT.splitToList(qualifiedName);
String componentName = splitName.get(splitName.size() - 1);
String instanceName = componentName.substring(0, 1).toLowerCase() + componentName.substring(1);
if (component == null){
Log.error("Component with name '" + componentName + "' does not exist.");
System.exit(1);
}
ExpandedComponentInstanceSymbol instance = component.getEnclosingScope().<ExpandedComponentInstanceSymbol>resolve(instanceName, ExpandedComponentInstanceSymbol.KIND).get();
generateFiles(symtab, instance, symtab);
}
public void generateFiles(TaggingResolver taggingResolver, ExpandedComponentInstanceSymbol componentSymbol, Scope symtab) throws IOException {
List<FileContent> fileContents = generateStrings(taggingResolver, componentSymbol, symtab);
for (FileContent fileContent : fileContents) {
emamGen.generateFile(fileContent);
}
}
public List<FileContent> generateStrings(TaggingResolver taggingResolver, ExpandedComponentInstanceSymbol componentInstanceSymbol, Scope symtab){
List<FileContent> fileContents = new ArrayList<>();
Set<ExpandedComponentInstanceSymbol> allInstances = new HashSet<>();
generateComponent(fileContents, allInstances, taggingResolver, componentInstanceSymbol, symtab);
fileContents.add(generateCNNTrainer(allInstances, componentInstanceSymbol.getComponentType().getFullName().replaceAll("\\.", "_")));
fileContents.add(ArmadilloHelper.getArmadilloHelperFileContent());
TypesGeneratorCPP tg = new TypesGeneratorCPP();
fileContents.addAll(tg.generateTypes(TypeConverter.getTypeSymbols()));
if (emamGen.shouldGenerateMainClass()) {
//fileContents.add(emamGen.getMainClassFileContent(componentInstanceSymbol, fileContents.get(0)));
} else if (emamGen.shouldGenerateSimulatorInterface()) {
fileContents.addAll(SimulatorIntegrationHelper.getSimulatorIntegrationHelperFileContent());
}
fixArmadilloImports(fileContents);
return fileContents;
}
protected void generateComponent(List<FileContent> fileContents,
Set<ExpandedComponentInstanceSymbol> allInstances,
TaggingResolver taggingResolver,
ExpandedComponentInstanceSymbol componentInstanceSymbol,
Scope symtab){
allInstances.add(componentInstanceSymbol);
ComponentSymbol componentSymbol = componentInstanceSymbol.getComponentType().getReferencedSymbol();
/* remove the following two lines if the component symbol full name bug with generic variables is fixed */
componentSymbol.setFullName(null);
componentSymbol.getFullName();
/* */
Optional<ArchitectureSymbol> architecture = componentInstanceSymbol.getSpannedScope().resolve("", ArchitectureSymbol.KIND);
Optional<MathStatementsSymbol> mathStatements = componentSymbol.getSpannedScope().resolve("MathStatements", MathStatementsSymbol.KIND);
EMADLCocos.checkAll(componentInstanceSymbol);
if (architecture.isPresent()){
generateCNN(fileContents, taggingResolver, componentInstanceSymbol, architecture.get());
}
else if (mathStatements.isPresent()){
generateMathComponent(fileContents, taggingResolver, componentInstanceSymbol, mathStatements.get());
}
else {
generateSubComponents(fileContents, allInstances, taggingResolver, componentInstanceSymbol, symtab);
}
}
private void fixArmadilloImports(List<FileContent> fileContents){
for (FileContent fileContent : fileContents){
fileContent.setFileContent(fileContent.getFileContent()
.replaceFirst("#include \"armadillo.h\"",
"#include \"armadillo\""));
}
}
public void generateCNN(List<FileContent> fileContents, TaggingResolver taggingResolver, ExpandedComponentInstanceSymbol instance, ArchitectureSymbol architecture){
CNNArchGenerator cnnArchGenerator = new CNNArchGenerator();
Map<String,String> contentMap = cnnArchGenerator.generateStrings(architecture);
String fullName = instance.getFullName().replaceAll("\\.", "_");
//get the components execute method
String executeKey = "execute_" + fullName;
String executeMethod = contentMap.get(executeKey);
if (executeMethod == null){
throw new IllegalStateException("execute method of " + fullName + " not found");
}
contentMap.remove(executeKey);
String component = emamGen.generateString(taggingResolver, instance, (MathStatementsSymbol) null);
FileContent componentFileContent = new FileContent(
transformComponent(component, "CNNPredictor_" + fullName, executeMethod),
instance);
for (String fileName : contentMap.keySet()){
fileContents.add(new FileContent(contentMap.get(fileName), fileName));
}
fileContents.add(componentFileContent);
fileContents.add(new FileContent(processTemplate(new HashMap<>(), CNN_HELPER), CNN_HELPER + ".h"));
}
protected String transformComponent(String component, String predictorClassName, String executeMethod){
String networkVariableName = "_cnn_";
//insert includes
component = component.replaceFirst("using namespace",
"#include \"" + predictorClassName + ".h" + "\"\n" +
"#include \"" + CNN_HELPER + ".h" + "\"\n" +
"using namespace");
//insert network attribute
component = component.replaceFirst("public:",
"public:\n" + predictorClassName + " " + networkVariableName + ";");
//insert execute method
component = component.replaceFirst("void execute\\(\\)\\s\\{\\s\\}",
"void execute(){\n" + executeMethod + "\n}");
return component;
}
public void generateMathComponent(List<FileContent> fileContents, TaggingResolver taggingResolver, ExpandedComponentInstanceSymbol componentSymbol, MathStatementsSymbol mathStatementsSymbol){
fileContents.add(new FileContent(
emamGen.generateString(taggingResolver, componentSymbol, mathStatementsSymbol),
componentSymbol));
}
public void generateSubComponents(List<FileContent> fileContents, Set<ExpandedComponentInstanceSymbol> allInstances, TaggingResolver taggingResolver, ExpandedComponentInstanceSymbol componentInstanceSymbol, Scope symtab){
fileContents.add(new FileContent(emamGen.generateString(taggingResolver, componentInstanceSymbol, (MathStatementsSymbol) null), componentInstanceSymbol));
String lastNameWithoutArrayPart = "";
for (ExpandedComponentInstanceSymbol instanceSymbol : componentInstanceSymbol.getSubComponents()) {
int arrayBracketIndex = instanceSymbol.getName().indexOf("[");
boolean generateComponentInstance = true;
if (arrayBracketIndex != -1) {
generateComponentInstance = !instanceSymbol.getName().substring(0, arrayBracketIndex).equals(lastNameWithoutArrayPart);
lastNameWithoutArrayPart = instanceSymbol.getName().substring(0, arrayBracketIndex);
Log.info(lastNameWithoutArrayPart, "Without:");
Log.info(generateComponentInstance + "", "Bool:");
}
if (generateComponentInstance) {
generateComponent(fileContents, allInstances, taggingResolver, instanceSymbol, symtab);
}
}
}
public FileContent generateCNNTrainer(Set<ExpandedComponentInstanceSymbol> allInstances, String mainComponentName){
List<ExpandedComponentInstanceSymbol> cnnInstances = new ArrayList<>();
List<String> trainParams = new ArrayList<>();
Set<String> componentNames = new HashSet<>();
for (ExpandedComponentInstanceSymbol componentInstance : allInstances){
ComponentSymbol component = componentInstance.getComponentType().getReferencedSymbol();
Optional<ArchitectureSymbol> architecture = component.getSpannedScope().resolve("", ArchitectureSymbol.KIND);
if (architecture.isPresent()){
String fileContent = getTrainingParamsForComponent(mainComponentName, component, componentInstance);
if (!fileContent.isEmpty()) {
trainParams.add(fileContent);
}
cnnInstances.add(componentInstance);
componentNames.add(component.getFullName());
}
}
Map<String, Object> ftlContext = new HashMap<>();
ftlContext.put("instances", cnnInstances);
ftlContext.put("componentNames", componentNames);
ftlContext.put("trainParams", trainParams);
return new FileContent(processTemplate(ftlContext, CNN_TRAINER), CNN_TRAINER + "_" + mainComponentName + ".py");
}
private String getTrainingParamsForComponent(String mainComponentName, ComponentSymbol component, ExpandedComponentInstanceSymbol instance) {
String configFilename;
String mainComponentConfigFilename = mainComponentName.replaceAll("\\.", "/");
String componentConfigFilename = component.getFullName().replaceAll("\\.", "/");
String instanceConfigFilename = component.getFullName().replaceAll("\\.", "/") + "_" + instance.getName();
if (Files.exists(Paths.get( getModelsPath() + instanceConfigFilename + ".cnnt"))) {
configFilename = instanceConfigFilename;
}
else if (Files.exists(Paths.get( getModelsPath() + componentConfigFilename + ".cnnt"))){
configFilename = componentConfigFilename;
}
else if (Files.exists(Paths.get( getModelsPath() + mainComponentConfigFilename + ".cnnt"))){
configFilename = mainComponentConfigFilename;
}
else{
Log.error("Missing configuration file. " +
"Could not find a file with any of the following names (only one needed): '"
+ getModelsPath() + instanceConfigFilename + ".cnnt', '"
+ getModelsPath() + componentConfigFilename + ".cnnt', '"
+ getModelsPath() + mainComponentConfigFilename + ".cnnt'." +
" These files denote respectively the configuration for the single instance, the component or the whole system.");
return "";
}
//should be removed when CNNTrain supports packages
List<String> names = Splitter.on("/").splitToList(configFilename);
configFilename = names.get(names.size()-1);
Path modelPath = Paths.get(getModelsPath() + Joiner.on("/").join(names.subList(0,names.size()-1)));
//
CNNTrainGenerator cnnTrainGenerator = new CNNTrainGenerator();
final ModelPath mp = new ModelPath(modelPath);
GlobalScope trainScope = new GlobalScope(mp, new CNNTrainLanguage());
Map.Entry<String, String> fileContents = cnnTrainGenerator.generateFileContent( trainScope, configFilename );
return fileContents.getValue();
}
protected String processTemplate(Map<String, Object> ftlContext, String templateNameWithoutEnding){
StringWriter writer = new StringWriter();
String templateName = templateNameWithoutEnding + ".ftl";
try{
Template template = TemplateConfiguration.get().getTemplate(templateName);
template.process(ftlContext, writer);
}
catch (IOException e) {
Log.error("Freemarker could not find template " + templateName + " :\n" + e.getMessage());
System.exit(1);
}
catch (TemplateException e){
Log.error("An exception occured in template " + templateName + " :\n" + e.getMessage());
System.exit(1);
}
return writer.toString();
}
}
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* 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.lang.monticar.emadl.generator;
import de.se_rwth.commons.logging.Log;
import freemarker.template.TemplateException;
import org.apache.commons.cli.*;
import java.io.IOException;
public class EMADLGeneratorCli {
public static final Option OPTION_MODELS_PATH = Option.builder("m")
.longOpt("models-dir")
.desc("full path to directory with EMADL models e.g. C:\\Users\\vpupkin\\proj\\MyAwesomeAutopilot\\src\\main\\emam")
.hasArg(true)
.required(true)
.build();
public static final Option OPTION_ROOT_MODEL = Option.builder("r")
.longOpt("root-model")
.desc("fully qualified name of the root model e.g. de.rwth.vpupkin.modeling.mySuperAwesomeAutopilotComponent")
.hasArg(true)
.required(true)
.build();
public static final Option OPTION_OUTPUT_PATH = Option.builder("o")
.longOpt("output-dir")
.desc("full path to output directory for tests e.g. C:\\Users\\vpupkin\\proj\\MyAwesomeAutopilot\\target\\gen-cpp")
.hasArg(true)
.required(false)
.build();
private EMADLGeneratorCli() {
}
public static void main(String[] args) {
Options options = getOptions();
CommandLineParser parser = new DefaultParser();
CommandLine cliArgs = parseArgs(options, parser, args);
if (cliArgs != null) {
runGenerator(cliArgs);
}
}
private static Options getOptions() {
Options options = new Options();
options.addOption(OPTION_MODELS_PATH);
options.addOption(OPTION_ROOT_MODEL);
options.addOption(OPTION_OUTPUT_PATH);
return options;
}
private static CommandLine parseArgs(Options options, CommandLineParser parser, String[] args) {
CommandLine cliArgs;
try {
cliArgs = parser.parse(options, args);
} catch (ParseException e) {
System.err.println("argument parsing exception: " + e.getMessage());
System.exit(1);
return null;
}
return cliArgs;
}