Skip to content
Snippets Groups Projects
Commit 5f4cbbf8 authored by René Schöne's avatar René Schöne
Browse files

Parser for ros2rag parses file with success for first time.

- renamed scanner and parser to Ros2Rag{Scanner,Parser}
- changed Compiler to not use System.exit throwing exceptions instead and have a dedicated run method
- implemented ASTNode.globallyResolveTokenComponentByToken and UpdateDefinition.resolveMappingByToken
parent 4bf5c1ea
No related branches found
No related tags found
No related merge requests found
......@@ -74,23 +74,23 @@ task relast(type: JavaExec) {
"--useJastAddNames",
"--file",
"--resolverHelper",
"--grammarName=./src/gen/jastadd/RelAST"
"--grammarName=./src/gen/jastadd/Ros2Rag"
]
inputs.files file("../libs/relast.jar"),
file("src/main/jastadd/RelAST.relast"),
file("src/main/jastadd/Ros2Rag.relast")
outputs.files file("./src/gen/jastadd/RelAst.ast"),
file("src/gen/jastadd/RelAst.jadd"),
file("src/gen/jastadd/RelAstRefResolver.jadd"),
file('src/gen/jastadd/RelAstResolverStubs.jrag')
outputs.files file("./src/gen/jastadd/Ros2Rag.ast"),
file("src/gen/jastadd/Ros2Rag.jadd"),
file("src/gen/jastadd/Ros2RagRefResolver.jadd"),
file('src/gen/jastadd/Ros2RagResolverStubs.jrag')
}
jastadd {
configureModuleBuild()
modules {
//noinspection GroovyAssignabilityCheck
module("RelAst") {
module("Ros2Rag") {
java {
basedir "."
......@@ -131,11 +131,11 @@ jastadd {
}
module = "RelAst"
module = "Ros2Rag"
astPackage = 'org.jastadd.ros2rag.ast'
parser.name = 'RelAstParser'
parser.name = 'Ros2RagParser'
genDir = 'src/gen/java'
......
......@@ -21,7 +21,7 @@ aspect DumpTree {
}
out.println();
String childIndent = indent + DUMP_TREE_INDENT;
for (ASTNode child : astChildren()) {
for (ASTNode<?> child : astChildren()) {
if (child == null) {
out.println(childIndent + "null");
} else {
......
......@@ -11,5 +11,31 @@ aspect NameResolution {
throw new RuntimeException("TypeDecl " + name + " could not be resolved.");
}
refine RefResolverStubs eq ASTNode.globallyResolveTokenComponentByToken(String id) {
// return a TokenComponent. id is of the form 'type_name + "." + token_name'
int dotIndex = id.indexOf(".");
String typeName = id.substring(0, dotIndex);
String tokenName = id.substring(dotIndex + 1);
TypeDecl type = program().resolveTypeDecl(typeName);
// iterate over components and find the matching tokenComponent
for (Component comp : type.getComponentList()) {
if (comp.isTokenComponent() && comp.getName().equals(tokenName)) {
return comp.asTokenComponent();
}
}
System.err.println("Could not resolve TokenComponent '" + id + "'.");
return null;
}
refine RefResolverStubs eq UpdateDefinition.resolveMappingByToken(String id) {
// return a MappingDefinition
for (MappingDefinition mappingDefinition : ros2rag().getMappingDefinitionList()) {
if (mappingDefinition.getID().equals(id)) {
return mappingDefinition;
}
}
System.err.println("Could not resolve MappingDefinition '" + id + "'.");
return null;
}
}
aspect Navigation {
// --- program ---
inh Program ASTNode.program();
eq Program.getChild().program() = this;
eq Ros2Rag.getChild().program() = getProgram();
// --- ros2rag
inh Ros2Rag ASTNode.ros2rag();
eq Ros2Rag.getChild().ros2rag() = this;
// --- typeDecls ---
coll java.util.Set<TypeDecl> Program.typeDecls() [new java.util.HashSet<>()] root Program;
TypeDecl contributes this
to Program.typeDecls()
for program();
// --- relations ---
coll java.util.Set<Relation> Program.relations() [new java.util.HashSet<>()] root Program;
Relation contributes this
to Program.relations()
for program();
// --- containingTypeDecl ---
inh TypeDecl Component.containingTypeDecl();
eq TypeDecl.getChild().containingTypeDecl() = this;
......@@ -23,6 +32,15 @@ aspect Navigation {
// syn boolean RelationComponent.multiplicityMany() = false;
// eq ManyRelationComponent.multiplicityMany() = true;
// --- containedFile ---
inh GrammarFile ASTNode.containedFile();
eq GrammarFile.getChild().containedFile() = this;
// --- isTokenComponent ---
syn boolean Component.isTokenComponent() = false;
eq TokenComponent.isTokenComponent() = true;
// --- asTokenComponent ---
syn TokenComponent Component.asTokenComponent() = null;
eq TokenComponent.asTokenComponent() = this;
}
package org.jastadd.ros2rag.scanner;
import org.jastadd.ros2rag.parser.RelAstParser.Terminals;
import org.jastadd.ros2rag.parser.Ros2RagParser.Terminals;
%%
%public
%final
%class RelAstScanner
%class Ros2RagScanner
%extends beaver.Scanner
%type beaver.Symbol
%function nextToken
%yylexthrow beaver.Scanner.Exception
%scanerror RelAstScanner.ScannerError
%scanerror Ros2RagScanner.ScannerError
%line
%column
......@@ -40,11 +40,14 @@ TraditionalComment = [/][*][^*]*[*]+([^*/][^*]*[*]+)*[/]
EndOfLineComment = "//" [^\n\r]*
Comment = {TraditionalComment} | {EndOfLineComment}
MappingContent = [{][:][^:]*[:]+([^:}][^:]*[:]+)*[}]
ID = [a-zA-Z$_][a-zA-Z0-9$_]*
%%
{WhiteSpace} { /* ignore */ }
{Comment} { return sym(Terminals.COMMENT); }
{MappingContent} { return sym(Terminals.MAPPING_CONTENT); }
"abstract" { return sym(Terminals.ABSTRACT); }
"rel" { return sym(Terminals.RELATION); }
......@@ -56,6 +59,7 @@ ID = [a-zA-Z$_][a-zA-Z0-9$_]*
"maps" { return sym(Terminals.MAPS); }
"to" { return sym(Terminals.TO); }
"as" { return sym(Terminals.AS); }
"with" { return sym(Terminals.WITH); }
";" { return sym(Terminals.SCOL); }
":" { return sym(Terminals.COL); }
......@@ -67,8 +71,6 @@ ID = [a-zA-Z$_][a-zA-Z0-9$_]*
">" { return sym(Terminals.GT); }
"[" { return sym(Terminals.LBRACKET); }
"]" { return sym(Terminals.RBRACKET); }
"{" { return sym(Terminals.LB_CURLY); }
"}" { return sym(Terminals.RB_CURLY); }
"/" { return sym(Terminals.SLASH); }
"?" { return sym(Terminals.QUESTION_MARK); }
"->" { return sym(Terminals.RIGHT); }
......
......@@ -2,6 +2,7 @@ Ros2Rag ros2rag
= update_definition.d ros2rag.r {: r.getUpdateDefinitionList().insertChild(d, 0); return r; :}
| dependency_definition.d ros2rag.r {: r.getDependencyDefinitionList().insertChild(d, 0); return r; :}
| mapping_definition.d ros2rag.r {: r.getMappingDefinitionList().insertChild(d, 0); return r; :}
| comment ros2rag.r {: return r; :}
| {: return new Ros2Rag(); :}
;
......@@ -53,17 +54,43 @@ DependencyDefinition dependency_definition
// y = IntPosition.of((int) p.getPositionX(), (int) p.getPositionY(), (int) p.getPositionZ());
//}
MappingDefinition mapping_definition
= ID.id MAPS java_type_use.from_type ID.from_variable TO java_type_use.to_type ID.to_variable LB_CURLY mapping_def_content.content RB_CURLY
= ID.id MAPS mapping_type.from TO mapping_type.to MAPPING_CONTENT.content
{:
MappingDefinition result = new MappingDefinition();
result.setID(id);
result.setFrom(from_type);
result.setFromVariable(from_variable);
result.setTo(to_type);
result.setToVariable(to_variable);
result.setContent(content);
result.setFrom(from);
result.setTo(to);
result.setContent(content.substring(2, content.length() - 2));
return result;
:}
;
String mapping_def_content = ID ;
MappingDefinitionType mapping_type
= java_type_use.type ID.variable
{:
MappingDefinitionType result = new MappingDefinitionType();
result.setType(type);
result.setVariableName(variable);
return result;
:}
| java_type_use.type ID.variable WITH ID.method
{:
MappingDefinitionType result = new MappingDefinitionType();
result.setType(type);
result.setVariableName(variable);
result.setSerializationMethodName(method);
return result;
:}
;
//String mapping_def_content
// = LB_CURLY COL mapping_def_content_body.b {: return b.stream().collect(java.util.stream.Collectors.joining("\n")); :}
//;
//
//ArrayList mapping_def_content_body
// = COL RB_CURLY {: return new ArrayList(); :}
// | TEXT.text mapping_def_content_body.b {: b.add(0, text); return b; :}
//;
//String mapping_def_content
// = MappingContent.c {: int length = c.length(); return c.substring(2, length - 2); :}
//;
......@@ -15,4 +15,5 @@ DependencyDefinition ::= <ID> ;
rel DependencyDefinition.Source -> TokenComponent ;
rel DependencyDefinition.Target -> TokenComponent ;
MappingDefinition ::= <ID> From:JavaTypeUse <FromVariable> To:JavaTypeUse <ToVariable> <Content> ;
MappingDefinition ::= <ID> From:MappingDefinitionType To:MappingDefinitionType <Content> ;
MappingDefinitionType ::= Type:JavaTypeUse <VariableName> <SerializationMethodName> ; // SerializationMethodName may be empty
......@@ -6,8 +6,8 @@ import org.jastadd.ros2rag.compiler.options.CommandLine;
import org.jastadd.ros2rag.compiler.options.CommandLine.CommandLineException;
import org.jastadd.ros2rag.compiler.options.Option;
import org.jastadd.ros2rag.compiler.options.StringOption;
import org.jastadd.ros2rag.parser.RelAstParser;
import org.jastadd.ros2rag.scanner.RelAstScanner;
import org.jastadd.ros2rag.parser.Ros2RagParser;
import org.jastadd.ros2rag.scanner.Ros2RagScanner;
import java.io.*;
import java.nio.file.Files;
......@@ -24,10 +24,14 @@ public class Compiler {
private ArrayList<Option<?>> options;
private CommandLine commandLine;
public Compiler(String[] args) throws CommandLineException {
public Compiler() {
options = new ArrayList<>();
addOptions();
}
public int run(String[] args) throws CommandLineException, CompilerException {
options = new ArrayList<>();
addOptions();
commandLine = new CommandLine(options);
commandLine.parse(args);
......@@ -41,11 +45,11 @@ public class Compiler {
printMessage("Running ROS2RAG Preprocessor");
if (!optionInputGrammar.isSet()) {
error("specify an input grammar");
return error("specify an input grammar");
}
if (!optionInputRos2Rag.isSet()) {
error("specify the ros2rag definition file");
return error("specify the ros2rag definition file");
}
List<String> otherArgs = commandLine.getArguments();
......@@ -57,15 +61,16 @@ public class Compiler {
printMessage("Writing output files");
writeToFile(outputDir + "/Grammar.relast", ros2Rag.getProgram().generateAbstractGrammar());
writeToFile(outputDir + "/ROS2RAG.jadd", ros2Rag.generateAspect());
return 0;
}
public static void main(String[] args) {
public static int main(String[] args) {
try {
new Compiler(args);
} catch (CommandLineException e) {
return new Compiler().run(args);
} catch (CommandLineException | CompilerException e) {
System.err.println(e.getMessage());
System.exit(1);
return 1;
}
}
......@@ -73,14 +78,13 @@ public class Compiler {
System.out.println(message);
}
private void writeToFile(String filename, String str) {
private void writeToFile(String filename, String str) throws CompilerException {
try {
PrintWriter writer = new PrintWriter(filename);
writer.print(str);
writer.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
throw new CompilerException("Could not write to file " + filename, e);
}
}
......@@ -95,37 +99,40 @@ public class Compiler {
return option;
}
private Ros2Rag parseProgram(String inputGrammarFileName, String inputRos2RagFileName) {
private Ros2Rag parseProgram(String inputGrammarFileName, String inputRos2RagFileName) throws CompilerException {
Program program = new Program();
Ros2Rag ros2Rag;
try (BufferedReader reader = Files.newBufferedReader(Paths.get(inputGrammarFileName))) {
RelAstScanner scanner = new RelAstScanner(reader);
RelAstParser parser = new RelAstParser();
Ros2RagScanner scanner = new Ros2RagScanner(reader);
Ros2RagParser parser = new Ros2RagParser();
GrammarFile inputGrammar = (GrammarFile) parser.parse(scanner);
inputGrammar.dumpTree(System.out);
program.addGrammarFile(inputGrammar);
inputGrammar.treeResolveAll();
} catch (IOException | Parser.Exception e) {
System.err.println(e.getMessage());
System.exit(1);
throw new CompilerException("Could not parse grammar file " + inputGrammarFileName, e);
}
try (BufferedReader reader = Files.newBufferedReader(Paths.get(inputRos2RagFileName))) {
RelAstScanner scanner = new RelAstScanner(reader);
RelAstParser parser = new RelAstParser();
ros2Rag = (Ros2Rag) parser.parse(scanner, RelAstParser.AltGoals.ros2rag);
Ros2RagScanner scanner = new Ros2RagScanner(reader);
Ros2RagParser parser = new Ros2RagParser();
ros2Rag = (Ros2Rag) parser.parse(scanner, Ros2RagParser.AltGoals.ros2rag);
ros2Rag.setProgram(program);
} catch (IOException | Parser.Exception e) {
System.err.println(e.getMessage());
System.exit(2);
return null; // poor compiler does not know System.exit()
throw new CompilerException("Could not parse ros2rag file " + inputRos2RagFileName, e);
}
ros2Rag.dumpTree(System.out);
ros2Rag.treeResolveAll();
ros2Rag.dumpTree(System.out);
return ros2Rag;
}
private void parse(Program program, Reader reader, String file) {
RelAstScanner scanner = new RelAstScanner(reader);
RelAstParser parser = new RelAstParser();
Ros2RagScanner scanner = new Ros2RagScanner(reader);
Ros2RagParser parser = new Ros2RagParser();
try {
GrammarFile newFile = (GrammarFile) parser.parse(scanner);
......@@ -139,13 +146,19 @@ public class Compiler {
}
}
protected void error(String message) {
protected int error(String message) {
System.err.println("Error: " + message);
System.err.println();
System.err.println("Usage: java -jar ros2rag.jar [--option1] [--option2=value] ... <filename1> <filename2> ... ");
System.err.println("Options:");
System.err.print(commandLine.printOptionHelp());
System.exit(1);
return 1;
}
public static class CompilerException extends Exception {
CompilerException(String message, Throwable cause) {
super(message, cause);
}
}
}
......@@ -2,8 +2,8 @@ package org.jastadd.ros2rag.compiler;
import beaver.Parser;
import org.jastadd.ros2rag.ast.*;
import org.jastadd.ros2rag.parser.RelAstParser;
import org.jastadd.ros2rag.scanner.RelAstScanner;
import org.jastadd.ros2rag.parser.Ros2RagParser;
import org.jastadd.ros2rag.scanner.Ros2RagScanner;
import java.io.BufferedReader;
import java.io.IOException;
......@@ -46,13 +46,13 @@ public class SimpleMain {
r.getShouldUseLowSpeed().connectTo("/robot/config/speed");
*/
Ros2Rag model = new Ros2Rag();
Program program = parseProgram(Paths.get("src", "test", "resources", "MinimalExample.relast"));
Program program = parseProgram(Paths.get("src", "test", "resources", "Example.relast"));
model.setProgram(program);
MappingDefinition mappingDefinition = new MappingDefinition();
mappingDefinition.setID("PoseToPosition");
mappingDefinition.setFrom(new SimpleJavaTypeUse("PBPose"));
mappingDefinition.setTo(new SimpleJavaTypeUse("Position"));
mappingDefinition.setFrom(makeMappingDefinitionType("PBPose", "x"));
mappingDefinition.setTo(makeMappingDefinitionType("Position", "y"));
mappingDefinition.setContent(" pose.position.x += sqrt(.5 * size.x)\n" +
" MAP round(2)\n" +
" x = x / 100\n" +
......@@ -71,10 +71,17 @@ public class SimpleMain {
System.out.println(model.generateAspect());
}
private static MappingDefinitionType makeMappingDefinitionType(String type, String variable) {
MappingDefinitionType result = new MappingDefinitionType();
result.setType(new SimpleJavaTypeUse(type));
result.setVariableName(variable);
return result;
}
private static Program parseProgram(Path path) {
try (BufferedReader reader = Files.newBufferedReader(path)) {
RelAstScanner scanner = new RelAstScanner(reader);
RelAstParser parser = new RelAstParser();
Ros2RagScanner scanner = new Ros2RagScanner(reader);
Ros2RagParser parser = new Ros2RagParser();
return (Program) parser.parse(scanner);
} catch (IOException | Parser.Exception e) {
e.printStackTrace();
......
......@@ -6,12 +6,13 @@ import org.junit.jupiter.api.Test;
import java.io.File;
import java.nio.file.Paths;
import java.util.Objects;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class RosToRagTest {
void transform(String inputGrammar, String inputRos2Rag, String outputDir) throws CommandLine.CommandLineException {
void transform(String inputGrammar, String inputRos2Rag, String outputDir) throws CommandLine.CommandLineException, Compiler.CompilerException {
System.out.println(Paths.get(".").toAbsolutePath());
assertTrue(Paths.get(inputGrammar).toFile().exists(), "input grammar does not exist");
......@@ -19,11 +20,11 @@ public class RosToRagTest {
File outputDirFile = Paths.get(outputDir).toFile();
if (outputDirFile.exists()) {
assertTrue(outputDirFile.isDirectory());
if (outputDirFile.list().length != 0) {
if (Objects.requireNonNull(outputDirFile.list(), "Could not read output directory").length != 0) {
System.out.println("output directory is not empty!");
}
} else {
outputDirFile.mkdir();
assertTrue(outputDirFile.mkdir());
}
String[] args = {
......@@ -32,11 +33,11 @@ public class RosToRagTest {
"--inputRos2Rag=" + inputRos2Rag
};
new Compiler(args);
new Compiler().run(args);
}
@Test
void transformMinimalExample() throws CommandLine.CommandLineException {
void transformMinimalExample() throws CommandLine.CommandLineException, Compiler.CompilerException {
transform("src/test/resources/Example.relast",
"src/test/resources/Example.ros2rag",
"src/test/resources/out");
......
......@@ -6,7 +6,7 @@ Zone ::= Coordinate* ;
RobotArm ::= Joint* EndEffector <_AttributeTestSource:int> /<_AppropriateSpeed:double>/ ; // normally this would be: <AttributeTestSource:int> ;
Joint ::= <Name> <_CurrentPosition:IntPosition> ; // normally this would be: <CurrentPosition:IntPosition>
Joint ::= <Name> <CurrentPosition:IntPosition> ; // normally this would be: <CurrentPosition:IntPosition>
EndEffector : Joint;
......
......@@ -8,13 +8,14 @@ RobotArm._AppropriateSpeed canDependOn Joint.CurrentPosition as dependency1 ;
RobotArm._AppropriateSpeed canDependOn RobotArm._AttributeTestSource as dependency2 ;
// --- mapping definitions ---
LinkStateToIntPosition: map protobuf panda.Linkstate.PandaLinkState x to IntPosition y {
LinkStateToIntPosition maps panda.Linkstate.PandaLinkState x to IntPosition y {:
panda.Linkstate.PandaLinkState.Position p = x.getPos();
{ int i = 0; }
y = IntPosition.of((int) p.getPositionX(), (int) p.getPositionY(), (int) p.getPositionZ());
}
:}
CreateSpeedMessage: map double x to protobuf config.Robotconfig.RobotConfig y {
CreateSpeedMessage maps double x to config.Robotconfig.RobotConfig y {:
y = config.Robotconfig.RobotConfig.newBuilder()
.setSpeed(x)
.build();
}
:}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment