Skip to content
Snippets Groups Projects
Commit 0311cae7 authored by Johannes Mey's avatar Johannes Mey
Browse files

Merge branch 'dev/rene' into feature/relast. this required many adaptations.

parent b5551dc7
No related branches found
No related tags found
No related merge requests found
Showing
with 584 additions and 672 deletions
apply plugin: 'java'
apply plugin: 'jastadd' apply plugin: 'jastadd'
apply plugin: 'application' apply plugin: 'application'
apply plugin: "idea"
sourceCompatibility = 1.8 sourceCompatibility = 1.8
...@@ -20,13 +23,11 @@ dependencies { ...@@ -20,13 +23,11 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0'
testCompile 'org.assertj:assertj-core:3.12.1' testCompile 'org.assertj:assertj-core:3.12.1'
compile "com.fasterxml.jackson.core:jackson-core:${jackson_version}" compile 'com.fasterxml.jackson.core:jackson-core:2.9.8'
compile "com.fasterxml.jackson.core:jackson-databind:${jackson_version}" compile 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
compile 'org.jastadd:jastadd:2.3.4' compile 'org.jastadd:jastadd:2.3.4'
runtime 'org.jastadd:jastadd:2.3.4' runtime 'org.jastadd:jastadd:2.3.4'
compile group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11' compile group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'
} }
sourceSets { sourceSets {
...@@ -52,6 +53,39 @@ jar { ...@@ -52,6 +53,39 @@ jar {
} }
} }
task relast(type: JavaExec) {
group = 'Build'
main = "-jar"
doFirst {
delete "src/gen/jastadd/*.ast"
delete "src/gen/jastadd/Ros2Rag.jadd"
delete "src/gen/jastadd/Ros2RagRefResolver.jadd"
delete "src/gen/jastadd/Ros2RagResolverStubs.jrag"
mkdir "src/gen/jastadd/"
}
args = [
"../libs/relast.jar",
"./src/main/jastadd/RelAst.relast",
"./src/main/jastadd/Ros2Rag.relast",
"--listClass=java.util.ArrayList",
"--jastAddList=JastAddList",
"--useJastAddNames",
"--file",
"--resolverHelper",
"--grammarName=./src/gen/jastadd/RelAST"
]
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')
}
jastadd { jastadd {
configureModuleBuild() configureModuleBuild()
modules { modules {
...@@ -65,10 +99,13 @@ jastadd { ...@@ -65,10 +99,13 @@ jastadd {
} }
jastadd { jastadd {
basedir "src/main/jastadd/" basedir "."
include "**/*.ast" include "src/main/jastadd/**/*.ast"
include "**/*.jadd" include "src/main/jastadd/**/*.jadd"
include "**/*.jrag" include "src/main/jastadd/**/*.jrag"
include "src/gen/jastadd/**/*.ast"
include "src/gen/jastadd/**/*.jadd"
include "src/gen/jastadd/**/*.jrag"
} }
scanner { scanner {
...@@ -106,6 +143,7 @@ jastadd { ...@@ -106,6 +143,7 @@ jastadd {
scanner.genDir = "src/gen/java/org/jastadd/ros2rag/scanner" scanner.genDir = "src/gen/java/org/jastadd/ros2rag/scanner"
parser.genDir = "src/gen/java/org/jastadd/ros2rag/parser" parser.genDir = "src/gen/java/org/jastadd/ros2rag/parser"
jastaddOptions = ["--lineColumnNumbers", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"] jastaddOptions = ["--lineColumnNumbers", "--List=JastAddList", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"]
} }
generateAst.dependsOn relast
import java.util.*; aspect Analysis {
aspect TypeAnalysis {
public abstract TypeUse Component.getTypeUse();
//--- lookupType ---
syn TypeDecl TypeUse.decl() = lookupType(getID());
inh TypeDecl TypeUse.lookupType(String name);
inh TypeDecl TypeDecl.lookupType(String name);
eq Program.getChild().lookupType(String name) {
for (TypeDecl td : getTypeDecls()) {
if (td.getID().equals(name)) {
return td;
}
}
return null;
}
//--- isAlreadyDeclared ---
syn boolean TypeDecl.isAlreadyDeclared() = lookupType(getID()) != this;
}
aspect ComponentAnalysis {
//--- isTargetOfDirectedRelation ---
inh boolean Component.isTargetOfDirectedRelation();
eq Relation.getRight().isTargetOfDirectedRelation() = getDirection() instanceof RightDirection;
eq Program.getChild().isTargetOfDirectedRelation() = false;
//--- name ---
syn String Component.name() = getID();
//--- enclosingTypeDecl ---
inh TypeDecl Component.enclosingTypeDecl();
eq TypeDecl.getChild().enclosingTypeDecl() = this;
eq Program.getChild().enclosingTypeDecl() = null;
//--- otherSide ---
inh RelationComponent RelationComponent.opposite();
eq Relation.getLeft().opposite() = getRight();
eq Relation.getRight().opposite() = getLeft();
eq Program.getChild().opposite() = null;
//--- ofTypeDecl ---
syn TypeDecl RelationComponent.ofTypeDecl() = opposite().getTypeUse().decl();
//--- isAlreadyDeclared ---
/**
* Check, if role with the same name is already declared on the same nonterminal
*/
syn boolean RelationComponent.isAlreadyDeclared()
= !isTargetOfDirectedRelation() /* if unnamed in relation, there is no role name, so no error */
&& getTypeUse().decl() != null /* nonterminal type of role is defined */
&& findComponent(getTypeUse().decl(), name()) != this; /* there is another role defined previously with the same name */
//--- findComponent ---
/** Search for either a component on the RHS of the given type with the given name,
* or a relation part for the given type and a role with the given name */
inh Component Component.findComponent(TypeDecl td, String name);
eq Program.getChild().findComponent(TypeDecl td, String name)
= findComponentSyn(td, name);
syn Component Program.findComponentSyn(TypeDecl td, String name) {
for (Component c: td.getComponents()) {
if (c.name().equals(name)) {
return c;
}
}
for (Relation r : getRelations()) {
if (r.getLeft().matches(td, name))
return r.getLeft();
if (r.getRight().matches(td, name))
return r.getRight();
}
return null;
}
//--- isInvalidRedefinition ---
/**
* Check, if a component with the same name is already declared in some supertype
*/
syn boolean Component.isInvalidRedefinition() = invalidRedefinition() != null;
/**
* Check, if a component with the same name is already declared in some supertype, and return it, if any
*/
syn Component Component.invalidRedefinition() = null;
eq TokenComponent.invalidRedefinition() = invalidRedefinitionOn(enclosingTypeDecl());
eq RelationComponent.invalidRedefinition() = invalidRedefinitionOn(getTypeUse().decl());
syn Component Component.invalidRedefinitionOn(TypeDecl td) {
if (td == null) return null;
while (td.hasSuper() && td.getSuper().decl() != null) {
td = td.getSuper().decl();
// find a matching component on the RHS of the (current) super type
Component c = findComponent(td, getID());
if (c != null && !this.isEqual(c)) return c;
}
return null;
}
//--- isEqual ---
syn boolean Component.isEqual(Component c) = this.getClass() == c.getClass() && getTypeUse().isEqual(c.getTypeUse());
/**
* TokenComponents may be specialized by NTATokenComponents and vice versa
*/
eq TokenComponent.isEqual(Component c) = (c instanceof TokenComponent) && getTypeUse().isEqual(c.getTypeUse());
syn boolean TypeUse.isEqual(TypeUse u);
eq SimpleTypeUse.isEqual(TypeUse u) = u instanceof SimpleTypeUse && getID().equals(u.getID());
eq ParameterizedTypeUse.isEqual(TypeUse u) {
if (!getID().equals(u.getID())) return false;
if (!(u instanceof ParameterizedTypeUse)) return false;
ParameterizedTypeUse pu = (ParameterizedTypeUse) u;
if (getNumTypeUse() != pu.getNumTypeUse()) return false;
for (int i = 0; i < getNumTypeUse(); i++) {
if (!getTypeUse(i).isEqual(pu.getTypeUse(i))) return false;
}
return true;
}
//--- matches ---
/**
* @return true, if the component has both type and role, its type matches the given typeDecl and its name matches the given name
*/
syn boolean RelationComponent.matches(TypeDecl td, String name)
= !isTargetOfDirectedRelation() && getTypeUse().decl() == td && name().equals(name);
//--- relationComponents ---
coll Set<RelationComponent> TypeDecl.relationComponents()
[new HashSet<RelationComponent>()]
root Program;
RelationComponent contributes this
when !isTargetOfDirectedRelation() && getTypeUse().decl() != null
to TypeDecl.relationComponents()
for getTypeUse().decl();
//--- relationComponentsTransitive ---
syn Collection<RelationComponent> TypeDecl.relationComponentsTransitive() {
Collection<RelationComponent> list = new ArrayList<>();
if (hasSuper() && getSuper().decl() != null) {
list.addAll(getSuper().decl().relationComponentsTransitive());
}
list.addAll(relationComponents());
return list;
}
//--- oneRelationComponents ---
syn Set<OneRelationComponent> TypeDecl.oneRelationComponents() {
Set<OneRelationComponent> set = new HashSet<>();
for (RelationComponent rc: relationComponents()) {
if (rc instanceof OneRelationComponent) {
set.add((OneRelationComponent) rc);
}
}
return set;
}
//--- needUnresolvedClass ---
syn boolean TypeDecl.needUnresolvedClass() {
// a TypeDecl needs an unresolved class, if it can appear in a relation
// TODO
return true;
}
//--- isList ---
syn boolean Component.isList() = false;
eq ListComponent.isList() = true;
eq NTAListComponent.isList() = true;
eq ManyRelationComponent.isList() = true;
//--- isOpt ---
syn boolean Component.isOpt() = false;
eq OptComponent.isOpt() = true;
eq NTAOptComponent.isOpt() = true;
eq OptionalRelationComponent.isOpt() = true;
//--- isNullable ---
syn boolean Component.isNullable() = false;
eq TokenComponent.isNullable() = !"float double int short long char byte boolean".contains(getTypeUse().getID());
}
aspect InstanceSupplier {
//--- program ---
inh Program TypeDecl.program();
eq Program.getTypeDecl(int i).program() = this;
//--- subTypeDecls ---
syn Collection<TypeDecl> TypeDecl.subTypeDecls() {
Collection<TypeDecl> subDecls = new ArrayList();
for (TypeDecl decl : program().getTypeDeclList()) {
if (decl.hasSuper() && decl.getSuper().getID().equals(getID())) {
subDecls.add(decl);
}
}
return subDecls;
}
//--- instantiableSubType ---
syn TypeDecl TypeDecl.instantiableSubType() {
if (getAbstract() == false) {
return this;
} else {
for (TypeDecl sub : subTypeDecls()) {
if (sub.getAbstract() == false) {
return sub;
} else {
TypeDecl subInstance = sub.instantiableSubType();
if (subInstance != null) {
return subInstance;
}
}
}
}
return null;
}
}
aspect Constructors {
//--- componentsTransitive ---
syn Collection<Component> TypeDecl.componentsTransitive() {
ArrayList<Component> list = new ArrayList<>();
if (hasSuper() && getSuper().decl() != null) {
list.addAll(getSuper().decl().componentsTransitive());
}
for (Component c: getComponents()) {
if (c.inConstructor()) {
list.add(c);
}
}
return list;
}
//--- needsConstructor ---
syn boolean TypeDecl.needsConstructor() = !componentsTransitive().isEmpty() && !relationComponentsTransitive().isEmpty();
//--- inConstructor ---
/**
* @return true, if the component should be added to the constructor (i.e., is not an NTA)
*/
syn boolean Component.inConstructor() = true;
eq NTAComponent.inConstructor() = false;
eq NTAOptComponent.inConstructor() = false;
eq NTAListComponent.inConstructor() = false;
eq NTATokenComponent.inConstructor() = false;
}
aspect Utils {
//--- toString ---
public String SimpleTypeUse.toString() {
return getID();
}
public String ParameterizedTypeUse.toString() {
StringBuilder sb = new StringBuilder();
sb.append(getID()).append("<");
boolean first = true;
for (TypeUse u: getTypeUses()) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(u.toString());
}
sb.append(">");
return sb.toString();
}
public String TypeDecl.toString() {
return getID();
}
} }
...@@ -33,7 +33,7 @@ aspect DumpTree { ...@@ -33,7 +33,7 @@ aspect DumpTree {
public String ASTNode.extraDumpInfo() { return ""; } public String ASTNode.extraDumpInfo() { return ""; }
public String ASTNode.getTokens() { public String ASTNode.getTokens() {
java.util.TreeSet<java.lang.reflect.Method> methods = new java.util.TreeSet<>(Comparator.comparing(java.lang.reflect.Method::getName)); java.util.TreeSet<java.lang.reflect.Method> methods = new java.util.TreeSet<>(java.util.Comparator.comparing(java.lang.reflect.Method::getName));
methods.addAll(java.util.Arrays.asList(getClass().getMethods())); methods.addAll(java.util.Arrays.asList(getClass().getMethods()));
......
import java.util.Set; //import java.util.Set;
import java.util.TreeSet; //import java.util.TreeSet;
import java.util.LinkedList; //import java.util.LinkedList;
//
aspect Errors { //
coll Set<ErrorMessage> Program.errors() //
[new TreeSet<ErrorMessage>()] //
root Program; //aspect ErrorMessage {
// public class ErrorMessage implements Comparable<ErrorMessage> {
TypeUse contributes error("Type '" + getID() + "' not found") // private final ASTNode node;
when decl() == null && !isToken() // private final String filename;
to Program.errors(); // private final int line;
// private final int col;
TypeDecl contributes error("Type '" + getID() + "' is already declared") // private final String message;
when isAlreadyDeclared() //
to Program.errors(); // public ErrorMessage(ASTNode node, String message) {
// this.node = node;
RelationComponent contributes error("Role '" + name() // this.filename = node.containedFile().getFileName();
+ "' is already declared for type '" + getTypeUse().decl() + "'") // this.line = node.getStartLine();
when isAlreadyDeclared() // this.col = node.getStartColumn();
to Program.errors(); // this.message = message;
// }
RelationComponent contributes error("Role '" + name() //
+ "' is an invalid redefinition for type '" + getTypeUse().decl() + "', conflicts with supertype '" // public ASTNode getNode() {
+ invalidRedefinition().enclosingTypeDecl() + "'") // return node;
when isInvalidRedefinition() // }
to Program.errors(); // public int getLine() {
// return line;
TokenComponent contributes error("Token '" + name() // }
+ "' is an invalid redefinition for type '" + enclosingTypeDecl() + "', conflicts with supertype '" // public int getCol() {
+ invalidRedefinition().enclosingTypeDecl() + "'") // return col;
when isInvalidRedefinition() // }
to Program.errors(); // public String getMessage() {
// return message;
RelationComponent contributes // }
error("Role name missing for type '" + getTypeUse().decl() + "'") //
when !isTargetOfDirectedRelation() && name().isEmpty() // public String toString() {
to Program.errors(); // return filename + " Line " + line + ", column " + col + ": " + message;
// }
RelationComponent contributes //
error("The target of a directed relation cannot have a role name") // @Override
when isTargetOfDirectedRelation() && !getID().isEmpty() // public int compareTo(ErrorMessage err) {
to Program.errors(); // int n = filename.compareTo(err.filename);
// if (n != 0) {
RelationComponent contributes // return n;
error("The target of a directed relation may only have multiplicity 1") // }
when isTargetOfDirectedRelation() && !multiplicityOne() //
to Program.errors(); // n = line - err.line;
} // if (n != 0) {
// return n;
aspect HelpAttributes { // }
inh Program ASTNode.program(); //
eq Program.getChild().program() = this; // n = col-err.col;
// if (n != 0) {
inh boolean TypeUse.isToken(); // return n;
eq Program.getChild().isToken() = false; // }
eq TokenComponent.getTypeUse().isToken() = true; //
// return message.compareTo(err.message);
syn boolean RelationComponent.multiplicityOne() = false; // }
eq OneRelationComponent.multiplicityOne() = true; // }
syn boolean RelationComponent.multiplicityOpt() = false; //
eq OptionalRelationComponent.multiplicityOpt() = true; // protected ErrorMessage ASTNode.error(String message) {
syn boolean RelationComponent.multiplicityMany() = false; // return new ErrorMessage(this, message);
eq ManyRelationComponent.multiplicityMany() = true; // }
//}
inh ContainedInFile Component.enclosingFileContainer();
eq TypeDecl.getComponent().enclosingFileContainer() = this;
eq Relation.getChild().enclosingFileContainer() = this;
inh ContainedInFile TypeUse.enclosingFileContainer();
eq SimpleTypeComponent.getTypeUse().enclosingFileContainer() = enclosingFileContainer();
eq TokenComponent.getTypeUse().enclosingFileContainer() = enclosingFileContainer();
eq TypeDecl.getSuper().enclosingFileContainer() = this;
syn String ASTNode.containedFile() = "Unknown";
eq Component.containedFile() = enclosingFileContainer() == null ? "Unknown2" : enclosingFileContainer().containedFile();
eq TypeUse.containedFile() = enclosingFileContainer() == null ? "Unknown3" : enclosingFileContainer().containedFile();
eq TypeDecl.containedFile() = getFileName();
eq Relation.containedFile() = getFileName();
}
aspect ErrorMessage {
public class ErrorMessage implements Comparable<ErrorMessage> {
private final ASTNode node;
private final String filename;
private final int line;
private final int col;
private final String message;
public ErrorMessage(ASTNode node, String message) {
this.node = node;
this.filename = node.containedFile();
this.line = node.getStartLine();
this.col = node.getStartColumn();
this.message = message;
}
public ASTNode getNode() {
return node;
}
public int getLine() {
return line;
}
public int getCol() {
return col;
}
public String getMessage() {
return message;
}
public String toString() {
return filename + " Line " + line + ", column " + col + ": " + message;
}
@Override
public int compareTo(ErrorMessage err) {
int n = filename.compareTo(err.filename);
if (n != 0) {
return n;
}
n = line - err.line;
if (n != 0) {
return n;
}
n = col-err.col;
if (n != 0) {
return n;
}
return message.compareTo(err.message);
}
}
protected ErrorMessage ASTNode.error(String message) {
return new ErrorMessage(this, message);
}
}
aspect NameResolution {
refine RefResolverStubs eq ASTNode.globallyResolveTypeDeclByToken(String id) = program().resolveTypeDecl(id);
syn TypeDecl Program.resolveTypeDecl(String name) {
for (TypeDecl decl : typeDecls()) {
if (decl.getName().equals(name)) {
return decl;
}
}
throw new RuntimeException("TypeDecl " + name + " could not be resolved.");
}
}
aspect Navigation {
inh Program ASTNode.program();
eq Program.getChild().program() = this;
coll java.util.Set<TypeDecl> Program.typeDecls() [new java.util.HashSet<>()] root Program;
TypeDecl contributes this
to Program.typeDecls()
for program();
coll java.util.Set<Relation> Program.relations() [new java.util.HashSet<>()] root Program;
Relation contributes this
to Program.relations()
for program();
inh TypeDecl Component.containingTypeDecl();
eq TypeDecl.getChild().containingTypeDecl() = this;
// syn boolean RelationComponent.multiplicityOne() = false;
// eq OneRelationComponent.multiplicityOne() = true;
// syn boolean RelationComponent.multiplicityOpt() = false;
// eq OptionalRelationComponent.multiplicityOpt() = true;
// syn boolean RelationComponent.multiplicityMany() = false;
// eq ManyRelationComponent.multiplicityMany() = true;
inh GrammarFile ASTNode.containedFile();
eq GrammarFile.getChild().containedFile() = this;
}
Program ::= TypeDecl* Relation*;
abstract ContainedInFile ::= <FileName> ;
TypeDecl : ContainedInFile ::= <ID> <Abstract:boolean> [Super:TypeUse] Component*;
abstract Component ::= <ID>;
abstract SimpleTypeComponent : Component ::= TypeUse:SimpleTypeUse;
NormalComponent : SimpleTypeComponent;
ListComponent : SimpleTypeComponent;
OptComponent : SimpleTypeComponent;
NTAComponent : SimpleTypeComponent;
NTAOptComponent : SimpleTypeComponent;
NTAListComponent : SimpleTypeComponent;
TokenComponent : Component ::= TypeUse;
NTATokenComponent : TokenComponent ::= TypeUse;
abstract TypeUse ::= <ID>;
SimpleTypeUse : TypeUse;
ParameterizedTypeUse : TypeUse ::= TypeUse*;
Relation : ContainedInFile ::= Left:RelationComponent Direction Right:RelationComponent;
abstract RelationComponent : SimpleTypeComponent;
OneRelationComponent : RelationComponent;
OptionalRelationComponent : RelationComponent;
ManyRelationComponent : RelationComponent;
abstract Direction;
RightDirection : Direction;
LeftDirection : Direction;
Bidirectional : Direction;
...@@ -44,7 +44,7 @@ ID = [a-zA-Z$_][a-zA-Z0-9$_]* ...@@ -44,7 +44,7 @@ ID = [a-zA-Z$_][a-zA-Z0-9$_]*
%% %%
{WhiteSpace} { /* ignore */ } {WhiteSpace} { /* ignore */ }
{Comment} { /* ignore */ } {Comment} { return sym(Terminals.COMMENT); }
"abstract" { return sym(Terminals.ABSTRACT); } "abstract" { return sym(Terminals.ABSTRACT); }
"rel" { return sym(Terminals.RELATION); } "rel" { return sym(Terminals.RELATION); }
......
Program goal = GrammarFile goal
/* empty */ {: return new Program(); :} = declaration.d goal.p {: p.getDeclarationList().insertChild(d, 0); return p; :}
| type_decl.t goal.p {: p.getTypeDeclList().insertChild(t, 0); return p; :} | {: return new GrammarFile(); :}
| relation.r goal.p {: p.getRelationList().insertChild(r, 0); return p; :} ;
;
TypeDecl type_decl = Declaration declaration
ID type_decl_super.s components_opt.c SCOL = type_decl
| relation
| comment
;
Comment comment
= COMMENT {: return new Comment(COMMENT); :};
TypeDecl type_decl
= ID components_opt.c SCOL
{: {:
TypeDecl result = new TypeDecl(); TypeDecl result = new TypeDecl();
result.setID(ID); result.setName(ID);
result.setAbstract(false); result.setAbstract(false);
result.setSuperOpt(s);
result.setComponentList(c); result.setComponentList(c);
return result; return result;
:} :}
| ABSTRACT ID type_decl_super.s components_opt.c SCOL | ID COL ID.s components_opt.c SCOL
{: {:
TypeDecl result = new TypeDecl(); TypeDecl result = new TypeDecl();
result.setID(ID); result.setName(ID);
result.setAbstract(true); result.setAbstract(false);
result.setSuperOpt(s); result.setSuperType(TypeDecl.createRef(s));
result.setComponentList(c); result.setComponentList(c);
return result; return result;
:} :}
; | ABSTRACT ID components_opt.c SCOL
{:
Opt type_decl_super = TypeDecl result = new TypeDecl();
/* empty */ {: return new Opt(); :} result.setName(ID);
| COL s_type_use.u {: return new Opt(u); :} result.setAbstract(true);
; result.setComponentList(c);
return result;
SimpleTypeUse s_type_use = :}
ID {: return new SimpleTypeUse(ID); :} | ABSTRACT ID COL ID.s components_opt.c SCOL
; {:
TypeDecl result = new TypeDecl();
ArrayList inner_type_use result.setName(ID);
= ID result.setAbstract(true);
| inner_type_use DOT ID result.setSuperType(TypeDecl.createRef(s));
; result.setComponentList(c);
return result;
TypeUse type_use = :}
parameterized_type_use.p {: return p; :} ;
| inner_type_use.p {: return new SimpleTypeUse((String)p.stream().map( x -> ((Symbol)x).value.toString()).collect(java.util.stream.Collectors.joining("."))); :}
; JastAddList components_opt
ParameterizedTypeUse parameterized_type_use = = /* empty */ {: return new JastAddList(); :}
inner_type_use.i LT type_use_list.l GT {: return new ParameterizedTypeUse((String)i.stream().map( x -> ((Symbol)x).value.toString()).collect(java.util.stream.Collectors.joining(".")), l); :}
;
List type_use_list =
type_use.u {: return new List().add(u); :}
| type_use_list.l COMMA type_use.u {: return l.add(u); :}
;
List components_opt =
/* empty */ {: return new List(); :}
| ASSIGN components.l {: return l; :} | ASSIGN components.l {: return l; :}
; ;
List components = JastAddList components
/* empty */ {: return new List(); :} = /* empty */ {: return new JastAddList(); :}
| components.l component.c {: return l.add(c); :} | components.l component.c {: return l.add(c); :}
; ;
Component component = Component component
ID COL s_type_use.u {: return new NormalComponent(ID, u); :} = SLASH actual_component.c SLASH
| s_type_use.u {: return new NormalComponent(u.getID(), u); :} {:
// List c.setNTA(true);
| ID COL s_type_use.u STAR {: return new ListComponent(ID, u); :} return c;
| s_type_use.u STAR {: return new ListComponent(u.getID(), u); :} :}
// Opt | actual_component
| LBRACKET ID COL s_type_use.u RBRACKET {: return new OptComponent(ID, u); :} ;
| LBRACKET s_type_use.u RBRACKET {: return new OptComponent(u.getID(), u); :}
// NTA list Component actual_component
| SLASH ID COL s_type_use.u STAR SLASH {: return new NTAListComponent(ID, u); :} = ID.name COL ID.type STAR
| SLASH s_type_use.u STAR SLASH {: return new NTAListComponent(u.getID(), u); :} {:
// NTA opt ListComponent result = new ListComponent();
| SLASH LBRACKET ID COL s_type_use.u RBRACKET SLASH {: return new NTAOptComponent(ID, u); :} result.setName(name);
| SLASH LBRACKET s_type_use.u RBRACKET SLASH {: return new NTAOptComponent(u.getID(), u); :} result.setTypeDecl(TypeDecl.createRef(type));
// NTA return result;
| SLASH ID COL s_type_use.u SLASH {: return new NTAComponent(ID, u); :} :}
| SLASH s_type_use.u SLASH {: return new NTAComponent(u.getID(), u); :} | ID.name COL ID.type
// NTA Token (same as NTA) {:
| SLASH LT ID COL s_type_use.u GT SLASH {: return new NTATokenComponent(ID, u); :} NormalComponent result = new NormalComponent();
| SLASH LT ID GT SLASH {: return new NTATokenComponent(ID, new SimpleTypeUse("String")); :} result.setName(name);
// Token result.setTypeDecl(TypeDecl.createRef(type));
| LT ID COL type_use.u GT {: return new TokenComponent(ID, u); :} return result;
| LT ID GT {: return new TokenComponent(ID, new SimpleTypeUse("String")); :} :}
; | ID.type STAR
{:
Relation relation = ListComponent result = new ListComponent();
RELATION relation_comp.l direction relation_comp.r SCOL result.setName(type);
{: result.setTypeDecl(TypeDecl.createRef(type));
Relation result = new Relation(); return result;
if (direction instanceof LeftDirection) { :}
result.setLeft(r); | ID.type
result.setDirection(new RightDirection()); {:
result.setRight(l); NormalComponent result = new NormalComponent();
} else { result.setName(type);
result.setLeft(l); result.setTypeDecl(TypeDecl.createRef(type));
result.setDirection(direction); return result;
result.setRight(r); :}
} | LBRACKET ID.name COL ID.type RBRACKET
return result; {:
:} OptComponent result = new OptComponent();
; result.setName(name);
result.setTypeDecl(TypeDecl.createRef(type));
RelationComponent relation_comp = return result;
// One :}
s_type_use.u DOT ID {: return new OneRelationComponent(ID, u); :} | LBRACKET ID.type RBRACKET
| s_type_use.u {: return new OneRelationComponent("", u); :} {:
// Optional OptComponent result = new OptComponent();
| s_type_use.u DOT ID QUESTION_MARK {: return new OptionalRelationComponent(ID, u); :} result.setName(type);
| s_type_use.u QUESTION_MARK {: return new OptionalRelationComponent("", u); :} result.setTypeDecl(TypeDecl.createRef(type));
// Many return result;
| s_type_use.u DOT ID STAR {: return new ManyRelationComponent(ID, u); :} :}
| s_type_use.u STAR {: return new ManyRelationComponent("", u); :} | LT ID.name COL java_type_use.type GT
; {:
TokenComponent result = new TokenComponent();
Direction direction = result.setName(name);
RIGHT {: return new RightDirection(); :} result.setJavaTypeUse(type);
| LEFT {: return new LeftDirection(); :} return result;
| BIDIRECTIONAL {: return new Bidirectional(); :} :}
; | LT ID.type GT
{:
TokenComponent result = new TokenComponent();
result.setName(type);
result.setJavaTypeUse(new SimpleJavaTypeUse(type));
return result;
:}
;
JavaTypeUse java_type_use
= parameterized_java_type_use
| simple_java_type_use
;
ArrayList qualified_name
= ID
| qualified_name DOT ID
;
JastAddList java_type_use_list
= java_type_use.u {: return new JastAddList().add(u); :}
| java_type_use_list.l COMMA java_type_use.u {: return l.add(u); :}
;
SimpleJavaTypeUse simple_java_type_use
= qualified_name.n
{:
return new SimpleJavaTypeUse((String)n.stream().map( x -> ((Symbol)x).value.toString()).collect(java.util.stream.Collectors.joining(".")));
:}
;
ParameterizedJavaTypeUse parameterized_java_type_use
= simple_java_type_use.i LT java_type_use_list.l GT
{:
return new ParameterizedJavaTypeUse(i.getName(), l);
:}
;
Relation relation
= RELATION unnamed_role.a LEFT navigable_role.b SCOL
{:
LeftDirectedRelation result = new LeftDirectedRelation();
result.setSource(b);
result.setTarget(a);
return result;
:}
| RELATION navigable_role.a RIGHT unnamed_role.b SCOL
{:
RightDirectedRelation result = new RightDirectedRelation();
result.setSource(a);
result.setTarget(b);
return result;
:}
| RELATION navigable_role.a BIDIRECTIONAL navigable_role.b SCOL
{:
BidirectionalRelation result = new BidirectionalRelation();
result.setLeft(a);
result.setRight(b);
return result;
:}
;
UnnamedRole unnamed_role
= ID.type
{:
UnnamedRole result = new UnnamedRole();
result.setType(TypeDecl.createRef(type));
return result;
:}
| navigable_role
;
NavigableRole navigable_role
= ID.type DOT ID.name
{:
NormalRole result = new NormalRole();
result.setName(name);
result.setType(TypeDecl.createRef(type));
return result;
:}
| ID.type DOT ID.name STAR
{:
ListRole result = new ListRole();
result.setName(name);
result.setType(TypeDecl.createRef(type));
return result;
:}
| ID.type DOT ID.name QUESTION_MARK
{:
OptRole result = new OptRole();
result.setName(name);
result.setType(TypeDecl.createRef(type));
return result;
:}
;
Program ::= GrammarFile *;
abstract Grammar ::= Declaration*;
GrammarFile : Grammar ::= <FileName> ;
abstract Declaration;
TypeDecl:Declaration ::= <Name> <Abstract:boolean> Component*;
rel TypeDecl.SuperType? <-> TypeDecl.SubType*;
abstract Component ::= <Name> <NTA:boolean>;
abstract TypeComponent : Component;
rel TypeComponent.TypeDecl <-> TypeDecl.PotentialParent*;
NormalComponent : TypeComponent;
ListComponent : TypeComponent;
OptComponent : TypeComponent;
TokenComponent : Component ::= JavaTypeUse;
abstract JavaTypeUse ::= <Name>;
SimpleJavaTypeUse : JavaTypeUse;
ParameterizedJavaTypeUse : JavaTypeUse ::= JavaTypeUse*;
abstract Relation : Declaration;
// rel Source.Name -> Target;
// rel Target <- Source.Name;
abstract DirectedRelation : Relation ::= Source:NavigableRole Target:UnnamedRole ;
LeftDirectedRelation : DirectedRelation;
RightDirectedRelation : DirectedRelation;
// rel Left.LeftName <-> Right.RightName;
BidirectionalRelation : Relation ::= Left:NavigableRole Right:NavigableRole ;
abstract Role;
abstract NavigableRole : Role ::= <Name>;
NormalRole : NavigableRole;
ListRole : NavigableRole;
OptRole : NavigableRole;
UnnamedRole : Role ;
rel Role.Type <-> TypeDecl.Role*;
// comments
Comment : Declaration ::= <Text>;
Ros2Rag ::= MappingDefinition* SyncDefinition* Program; //MqttRoot ;
abstract SyncDefinition ::= <AlwaysApply:Boolean> ;
abstract TokenWritingSyncDefinition : SyncDefinition ::= TargetType:SimpleTypeUse <TargetChild> ;
UpdateDefinition : TokenWritingSyncDefinition ::= <SourceAttribute> [MappingDefinitionUse] ;
ReadFromMqttDefinition : TokenWritingSyncDefinition ::= [MappingDefinitionUse] ;
WriteToMqttDefinition : SyncDefinition ::= SourceType:SimpleTypeUse <SourceChild> [MappingDefinitionUse] ;
MappingDefinition ::= <ID> From:SimpleTypeUse To:SimpleTypeUse <Content> ;
MappingDefinitionUse ::= <ID> ;
Ros2Rag ::= MappingDefinition* SyncDefinition* Program;
abstract SyncDefinition ::= <AlwaysApply:Boolean> ;
rel SyncDefinition.Mapping? -> MappingDefinition;
abstract TokenSyncDefinition : SyncDefinition;
rel TokenSyncDefinition.token -> TokenComponent;
ReadFromMqttDefinition : TokenSyncDefinition;
WriteToMqttDefinition : TokenSyncDefinition;
MappingDefinition ::= <ID> <Content> ;
rel MappingDefinition.from -> TypeDecl;
rel MappingDefinition.to -> TypeDecl;
...@@ -11,95 +11,161 @@ aspect BackendAbstractGrammar { ...@@ -11,95 +11,161 @@ aspect BackendAbstractGrammar {
return sb.toString(); return sb.toString();
} }
public void Program.generateAbstractGrammar(StringBuilder sb) { public void Program.generateAbstractGrammar(StringBuilder b) {
for (TypeDecl td: getTypeDecls()) { for (GrammarFile file : getGrammarFileList()) {
td.generateAbstractGrammar(sb); file.generateAbstractGrammar(b);
} }
} }
public void TypeDecl.generateAbstractGrammar(StringBuilder sb) { public void GrammarFile.generateAbstractGrammar(StringBuilder b) {
b.append("// Grammar for file ").append(getFileName()).append("\n");
super.generateAbstractGrammar(b);
b.append("\n");
}
public void Grammar.generateAbstractGrammar(StringBuilder b) {
for (Declaration decl : getDeclarationList()) {
decl.generateAbstractGrammar(b);
}
}
abstract public void Declaration.generateAbstractGrammar(StringBuilder b);
public void Comment.generateAbstractGrammar(StringBuilder b) {
b.append(getText()).append("\n");
}
public void TypeDecl.generateAbstractGrammar(StringBuilder b) {
if (getAbstract()) { if (getAbstract()) {
sb.append("abstract "); b.append("abstract ");
} }
sb.append(getID()); b.append(getName()).append(" ");
if (hasSuper()) { if (hasSuperType()) {
sb.append(" : " + getSuper()); b.append(": ").append(getSuperType().getName()).append(" ");
} }
b.append("::=");
if (getNumComponent() > 0 || relationComponents().size() > 0) { for (Component component : getComponentList()) {
sb.append(" ::="); b.append(" ");
component.generateAbstractGrammar(b);
} }
for (Component c: getComponents()) { b.append(";\n");
sb.append(" "); }
sb.append(c.generateAbstractGrammar());
public abstract void Component.generateAbstractGrammar(StringBuilder b);
public void NormalComponent.generateAbstractGrammar(StringBuilder b) {
if (getNTA()) {
b.append("/");
} }
sb.append(";\n"); if (!getName().equals("")) {
b.append(getName()).append(":");
}
b.append(getTypeDecl().getName());
if (getNTA()) {
b.append("/");
}
} }
public String Component.generateAbstractGrammar() { public void ListComponent.generateAbstractGrammar(StringBuilder b) {
if (getID().equals(getTypeUse().toString())) { if (getNTA()) {
return getTypeUse().toString(); b.append("/");
} else { }
return getID() + ":" + getTypeUse();
if (!getName().equals("")) {
b.append(getName()).append(":");
}
b.append(getTypeDecl().getName()).append("*");
if (getNTA()) {
b.append("/");
} }
} }
public String ListComponent.generateAbstractGrammar() {
return super.generateAbstractGrammar() + "*"; public void OptComponent.generateAbstractGrammar(StringBuilder b) {
} if (getNTA()) {
public String OptComponent.generateAbstractGrammar() { b.append("/");
return "[" + super.generateAbstractGrammar() + "]"; }
} b.append("[");
public String NTAComponent.generateAbstractGrammar() { if (!getName().equals("")) {
return "/" + super.generateAbstractGrammar() + "/"; b.append(getName()).append(":");
} }
public String NTAListComponent.generateAbstractGrammar() { b.append(getTypeDecl().getName()).append("]");
return "/" + super.generateAbstractGrammar() + "*/"; if (getNTA()) {
} b.append("/");
public String NTAOptComponent.generateAbstractGrammar() { }
return "/[" + super.generateAbstractGrammar() + "]/";
}
public String TokenComponent.generateAbstractGrammar() {
return "<" + getID() + ":" + getTypeUse() + ">";
} }
public String NTATokenComponent.generateAbstractGrammar() {
return "/<" + getID() + ":" + getTypeUse() + ">/"; public void TokenComponent.generateAbstractGrammar(StringBuilder b) {
if (getNTA()) {
b.append("/");
}
b.append("<");
if (!getName().equals("")) {
b.append(getName()).append(":");
}
getJavaTypeUse().generateAbstractGrammar(b);
b.append(">");
if (getNTA()) {
b.append("/");
}
} }
public String Relation.generateAbstractGrammar() { abstract public void JavaTypeUse.generateAbstractGrammar(StringBuilder b);
return "rel "
+ getLeft().generateAbstractGrammar() + " " public void SimpleJavaTypeUse.generateAbstractGrammar(StringBuilder b) {
+ getDirection().generateAbstractGrammar() + " " b.append(getName());
+ getRight().generateAbstractGrammar();
} }
public String RelationComponent.generateAbstractGrammar() { public void ParameterizedJavaTypeUse.generateAbstractGrammar(StringBuilder b) {
if (getID().isEmpty()) { b.append("<");
return getTypeUse().toString(); boolean first = true;
} else { for (JavaTypeUse javaTypeUse : getJavaTypeUseList()) {
return getTypeUse() + "." + getID(); if (first) {
first = false;
} else {
b.append(", ");
}
javaTypeUse.generateAbstractGrammar(b);
} }
b.append(">");
} }
public String OptionalRelationComponent.generateAbstractGrammar() { abstract public void Relation.generateAbstractGrammar(StringBuilder b);
return super.generateAbstractGrammar() + "?";
public void DirectedRelation.generateAbstractGrammar(StringBuilder b) {
b.append("rel ");
getSource().generateAbstractGrammar(b);
b.append(" -> ");
getTarget().generateAbstractGrammar(b);
b.append(";\n");
} }
public String ManyRelationComponent.generateAbstractGrammar() { public void BidirectionalRelation.generateAbstractGrammar(StringBuilder b) {
return super.generateAbstractGrammar() + "*"; b.append("rel ");
getLeft().generateAbstractGrammar(b);
b.append(" <-> ");
getRight().generateAbstractGrammar(b);
b.append(";\n");
} }
abstract public String Direction.generateAbstractGrammar(); abstract public void Role.generateAbstractGrammar(StringBuilder b);
public String RightDirection.generateAbstractGrammar() {
return "->"; public void NormalRole.generateAbstractGrammar(StringBuilder b) {
b.append(getType().getName()).append(".").append(getName());
}
public void ListRole.generateAbstractGrammar(StringBuilder b) {
b.append(getType().getName()).append(".").append(getName()).append("*");
} }
public String LeftDirection.generateAbstractGrammar() { public void OptRole.generateAbstractGrammar(StringBuilder b) {
return "<-"; b.append(getType().getName()).append(".").append(getName()).append("?");
} }
public String Bidirectional.generateAbstractGrammar() { public void UnnamedRole.generateAbstractGrammar(StringBuilder b) {
return "<->"; b.append(getType().getName());
} }
} }
...@@ -39,10 +39,10 @@ aspect Aspect { ...@@ -39,10 +39,10 @@ aspect Aspect {
} }
abstract void SyncDefinition.generateAspect(StringBuilder sb); abstract void SyncDefinition.generateAspect(StringBuilder sb);
@Override // @Override
void UpdateDefinition.generateAspect(StringBuilder sb) { // void UpdateDefinition.generateAspect(StringBuilder sb) {
// TODO // // TODO
} // }
// will be "addConnectionJoint_CurrentPosition" in example // will be "addConnectionJoint_CurrentPosition" in example
/* // see discussion in codimd (InstanceLocation), why this won't work here /* // see discussion in codimd (InstanceLocation), why this won't work here
...@@ -60,14 +60,22 @@ aspect Aspect { ...@@ -60,14 +60,22 @@ aspect Aspect {
void ReadFromMqttDefinition.generateAspect(StringBuilder sb) { void ReadFromMqttDefinition.generateAspect(StringBuilder sb) {
sb.append("public void ").append("type").append(".connectTo(String topic) {\n") sb.append("public void ").append("type").append(".connectTo(String topic) {\n")
.append(aspectIndent).append("mqttUpdater().addConnection") .append(aspectIndent).append("mqttUpdater().addConnection")
.append(getTargetType().getID()).append("_") .append(getToken().containingTypeDecl().getName())
.append(getTargetChild()) .append("_")
.append(getToken().getName())
.append("(this, topic);\n") .append("(this, topic);\n")
.append("}\n"); .append("}\n");
} }
@Override @Override
void WriteToMqttDefinition.generateAspect(StringBuilder sb) { void WriteToMqttDefinition.generateAspect(StringBuilder sb) {
// TODO sb.append("public void ").append("type").append(".connectTo(String topic) {\n")
.append(aspectIndent).append("mqttUpdater().addConnection")
.append(getToken().containingTypeDecl().getName())
.append("_")
.append(getToken().getName())
.append("(this, topic);\n")
.append("}\n");
} }
} }
package org.jastadd.ros2rag.compiler; package org.jastadd.ros2rag.compiler;
import beaver.Parser; import beaver.Parser;
import org.jastadd.ros2rag.ast.ErrorMessage; import org.jastadd.ros2rag.ast.*;
import org.jastadd.ros2rag.ast.Program;
import org.jastadd.ros2rag.ast.Relation;
import org.jastadd.ros2rag.ast.TypeDecl;
import org.jastadd.ros2rag.compiler.options.CommandLine; import org.jastadd.ros2rag.compiler.options.CommandLine;
import org.jastadd.ros2rag.compiler.options.CommandLine.CommandLineException; import org.jastadd.ros2rag.compiler.options.CommandLine.CommandLineException;
import org.jastadd.ros2rag.compiler.options.Option; import org.jastadd.ros2rag.compiler.options.Option;
...@@ -46,19 +43,9 @@ public class Compiler { ...@@ -46,19 +43,9 @@ public class Compiler {
List<String> filenames = commandLine.getArguments(); List<String> filenames = commandLine.getArguments();
Program p = parseProgram(filenames); Program p = parseProgram(filenames);
writeToFile(outputDir + "/Grammar.ast", p.generateAbstractGrammar());
writeToFile(outputDir + "/ROS2RAG.jadd", p.generateAspect());
if (!p.errors().isEmpty()) {
System.err.println("Errors:");
for (ErrorMessage e : p.errors()) {
System.err.println(e);
}
System.exit(1);
} else {
writeToFile(outputDir + "/Grammar.ast", p.generateAbstractGrammar());
writeToFile(outputDir + "/ROS2RAG.jadd", p.generateAspect());
}
} }
...@@ -110,6 +97,7 @@ public class Compiler { ...@@ -110,6 +97,7 @@ public class Compiler {
parse(program, reader, fileName); parse(program, reader, fileName);
} }
program.treeResolveAll();
return program; return program;
} }
...@@ -118,15 +106,8 @@ public class Compiler { ...@@ -118,15 +106,8 @@ public class Compiler {
RelAstParser parser = new RelAstParser(); RelAstParser parser = new RelAstParser();
try { try {
Program newProgram = (Program) parser.parse(scanner); GrammarFile newFile = (GrammarFile) parser.parse(scanner);
for (TypeDecl typeDecl : newProgram.getTypeDeclList()) { program.addGrammarFile(newFile);
typeDecl.setFileName(file);
program.addTypeDecl(typeDecl);
}
for (Relation relation : newProgram.getRelationList()) {
relation.setFileName(file);
program.addRelation(relation);
}
} catch (IOException e) { } catch (IOException e) {
error(e.getMessage()); error(e.getMessage());
} catch (Parser.Exception e) { } catch (Parser.Exception e) {
......
...@@ -51,8 +51,8 @@ public class SimpleMain { ...@@ -51,8 +51,8 @@ public class SimpleMain {
MappingDefinition mappingDefinition = new MappingDefinition(); MappingDefinition mappingDefinition = new MappingDefinition();
mappingDefinition.setID("PoseToPosition"); mappingDefinition.setID("PoseToPosition");
mappingDefinition.setFrom(new SimpleTypeUse("PBPose")); mappingDefinition.setFrom(TypeDecl.createRef("PBPose"));
mappingDefinition.setTo(new SimpleTypeUse("Position")); mappingDefinition.setTo(TypeDecl.createRef("Position"));
mappingDefinition.setContent(" pose.position.x += sqrt(.5 * size.x)\n" + mappingDefinition.setContent(" pose.position.x += sqrt(.5 * size.x)\n" +
" MAP round(2)\n" + " MAP round(2)\n" +
" x = x / 100\n" + " x = x / 100\n" +
...@@ -62,11 +62,12 @@ public class SimpleMain { ...@@ -62,11 +62,12 @@ public class SimpleMain {
ReadFromMqttDefinition readFromMqttDefinition = new ReadFromMqttDefinition(); ReadFromMqttDefinition readFromMqttDefinition = new ReadFromMqttDefinition();
readFromMqttDefinition.setAlwaysApply(false); readFromMqttDefinition.setAlwaysApply(false);
readFromMqttDefinition.setTargetType(new SimpleTypeUse("Joint")); readFromMqttDefinition.setToken(TokenComponent.createRef("Joint.CurrentPosition"));
readFromMqttDefinition.setTargetChild("CurrentPosition"); readFromMqttDefinition.setMapping(mappingDefinition);
readFromMqttDefinition.setMappingDefinitionUse(new MappingDefinitionUse("PoseToPosition"));
model.addSyncDefinition(readFromMqttDefinition); model.addSyncDefinition(readFromMqttDefinition);
model.treeResolveAll();
System.out.println(model.generateAspect()); System.out.println(model.generateAspect());
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment