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: 'application'
apply plugin: "idea"
sourceCompatibility = 1.8
......@@ -20,13 +23,11 @@ dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0'
testCompile 'org.assertj:assertj-core:3.12.1'
compile "com.fasterxml.jackson.core:jackson-core:${jackson_version}"
compile "com.fasterxml.jackson.core:jackson-databind:${jackson_version}"
compile 'com.fasterxml.jackson.core:jackson-core:2.9.8'
compile 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
compile '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: '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 {
......@@ -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 {
configureModuleBuild()
modules {
......@@ -65,10 +99,13 @@ jastadd {
}
jastadd {
basedir "src/main/jastadd/"
include "**/*.ast"
include "**/*.jadd"
include "**/*.jrag"
basedir "."
include "src/main/jastadd/**/*.ast"
include "src/main/jastadd/**/*.jadd"
include "src/main/jastadd/**/*.jrag"
include "src/gen/jastadd/**/*.ast"
include "src/gen/jastadd/**/*.jadd"
include "src/gen/jastadd/**/*.jrag"
}
scanner {
......@@ -106,6 +143,7 @@ jastadd {
scanner.genDir = "src/gen/java/org/jastadd/ros2rag/scanner"
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 {
public String ASTNode.extraDumpInfo() { return ""; }
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()));
......
import java.util.Set;
import java.util.TreeSet;
import java.util.LinkedList;
aspect Errors {
coll Set<ErrorMessage> Program.errors()
[new TreeSet<ErrorMessage>()]
root Program;
TypeUse contributes error("Type '" + getID() + "' not found")
when decl() == null && !isToken()
to Program.errors();
TypeDecl contributes error("Type '" + getID() + "' is already declared")
when isAlreadyDeclared()
to Program.errors();
RelationComponent contributes error("Role '" + name()
+ "' is already declared for type '" + getTypeUse().decl() + "'")
when isAlreadyDeclared()
to Program.errors();
RelationComponent contributes error("Role '" + name()
+ "' is an invalid redefinition for type '" + getTypeUse().decl() + "', conflicts with supertype '"
+ invalidRedefinition().enclosingTypeDecl() + "'")
when isInvalidRedefinition()
to Program.errors();
TokenComponent contributes error("Token '" + name()
+ "' is an invalid redefinition for type '" + enclosingTypeDecl() + "', conflicts with supertype '"
+ invalidRedefinition().enclosingTypeDecl() + "'")
when isInvalidRedefinition()
to Program.errors();
RelationComponent contributes
error("Role name missing for type '" + getTypeUse().decl() + "'")
when !isTargetOfDirectedRelation() && name().isEmpty()
to Program.errors();
RelationComponent contributes
error("The target of a directed relation cannot have a role name")
when isTargetOfDirectedRelation() && !getID().isEmpty()
to Program.errors();
RelationComponent contributes
error("The target of a directed relation may only have multiplicity 1")
when isTargetOfDirectedRelation() && !multiplicityOne()
to Program.errors();
}
aspect HelpAttributes {
inh Program ASTNode.program();
eq Program.getChild().program() = this;
inh boolean TypeUse.isToken();
eq Program.getChild().isToken() = false;
eq TokenComponent.getTypeUse().isToken() = true;
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 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);
}
}
//import java.util.Set;
//import java.util.TreeSet;
//import java.util.LinkedList;
//
//
//
//
//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().getFileName();
// 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$_]*
%%
{WhiteSpace} { /* ignore */ }
{Comment} { /* ignore */ }
{Comment} { return sym(Terminals.COMMENT); }
"abstract" { return sym(Terminals.ABSTRACT); }
"rel" { return sym(Terminals.RELATION); }
......
Program goal =
/* empty */ {: return new Program(); :}
| type_decl.t goal.p {: p.getTypeDeclList().insertChild(t, 0); return p; :}
| relation.r goal.p {: p.getRelationList().insertChild(r, 0); return p; :}
GrammarFile goal
= declaration.d goal.p {: p.getDeclarationList().insertChild(d, 0); return p; :}
| {: return new GrammarFile(); :}
;
TypeDecl type_decl =
ID type_decl_super.s components_opt.c SCOL
Declaration declaration
= type_decl
| relation
| comment
;
Comment comment
= COMMENT {: return new Comment(COMMENT); :};
TypeDecl type_decl
= ID components_opt.c SCOL
{:
TypeDecl result = new TypeDecl();
result.setName(ID);
result.setAbstract(false);
result.setComponentList(c);
return result;
:}
| ID COL ID.s components_opt.c SCOL
{:
TypeDecl result = new TypeDecl();
result.setID(ID);
result.setName(ID);
result.setAbstract(false);
result.setSuperOpt(s);
result.setSuperType(TypeDecl.createRef(s));
result.setComponentList(c);
return result;
:}
| ABSTRACT ID type_decl_super.s components_opt.c SCOL
| ABSTRACT ID components_opt.c SCOL
{:
TypeDecl result = new TypeDecl();
result.setID(ID);
result.setName(ID);
result.setAbstract(true);
result.setSuperOpt(s);
result.setComponentList(c);
return result;
:}
| ABSTRACT ID COL ID.s components_opt.c SCOL
{:
TypeDecl result = new TypeDecl();
result.setName(ID);
result.setAbstract(true);
result.setSuperType(TypeDecl.createRef(s));
result.setComponentList(c);
return result;
:}
;
Opt type_decl_super =
/* empty */ {: return new Opt(); :}
| COL s_type_use.u {: return new Opt(u); :}
JastAddList components_opt
= /* empty */ {: return new JastAddList(); :}
| ASSIGN components.l {: return l; :}
;
SimpleTypeUse s_type_use =
ID {: return new SimpleTypeUse(ID); :}
JastAddList components
= /* empty */ {: return new JastAddList(); :}
| components.l component.c {: return l.add(c); :}
;
ArrayList inner_type_use
= ID
| inner_type_use DOT ID
Component component
= SLASH actual_component.c SLASH
{:
c.setNTA(true);
return c;
:}
| actual_component
;
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("."))); :}
Component actual_component
= ID.name COL ID.type STAR
{:
ListComponent result = new ListComponent();
result.setName(name);
result.setTypeDecl(TypeDecl.createRef(type));
return result;
:}
| ID.name COL ID.type
{:
NormalComponent result = new NormalComponent();
result.setName(name);
result.setTypeDecl(TypeDecl.createRef(type));
return result;
:}
| ID.type STAR
{:
ListComponent result = new ListComponent();
result.setName(type);
result.setTypeDecl(TypeDecl.createRef(type));
return result;
:}
| ID.type
{:
NormalComponent result = new NormalComponent();
result.setName(type);
result.setTypeDecl(TypeDecl.createRef(type));
return result;
:}
| LBRACKET ID.name COL ID.type RBRACKET
{:
OptComponent result = new OptComponent();
result.setName(name);
result.setTypeDecl(TypeDecl.createRef(type));
return result;
:}
| LBRACKET ID.type RBRACKET
{:
OptComponent result = new OptComponent();
result.setName(type);
result.setTypeDecl(TypeDecl.createRef(type));
return result;
:}
| LT ID.name COL java_type_use.type GT
{:
TokenComponent result = new TokenComponent();
result.setName(name);
result.setJavaTypeUse(type);
return result;
:}
| LT ID.type GT
{:
TokenComponent result = new TokenComponent();
result.setName(type);
result.setJavaTypeUse(new SimpleJavaTypeUse(type));
return result;
:}
;
ParameterizedTypeUse parameterized_type_use =
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); :}
JavaTypeUse java_type_use
= parameterized_java_type_use
| simple_java_type_use
;
List type_use_list =
type_use.u {: return new List().add(u); :}
| type_use_list.l COMMA type_use.u {: return l.add(u); :}
ArrayList qualified_name
= ID
| qualified_name DOT ID
;
List components_opt =
/* empty */ {: return new List(); :}
| ASSIGN components.l {: return l; :}
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); :}
;
List components =
/* empty */ {: return new List(); :}
| components.l component.c {: return l.add(c); :}
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(".")));
:}
;
Component component =
ID COL s_type_use.u {: return new NormalComponent(ID, u); :}
| s_type_use.u {: return new NormalComponent(u.getID(), u); :}
// List
| ID COL s_type_use.u STAR {: return new ListComponent(ID, u); :}
| s_type_use.u STAR {: return new ListComponent(u.getID(), u); :}
// Opt
| 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
| SLASH ID COL s_type_use.u STAR SLASH {: return new NTAListComponent(ID, u); :}
| SLASH s_type_use.u STAR SLASH {: return new NTAListComponent(u.getID(), u); :}
// NTA opt
| SLASH LBRACKET ID COL s_type_use.u RBRACKET SLASH {: return new NTAOptComponent(ID, u); :}
| SLASH LBRACKET s_type_use.u RBRACKET SLASH {: return new NTAOptComponent(u.getID(), u); :}
// NTA
| 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); :}
// NTA Token (same as NTA)
| SLASH LT ID COL s_type_use.u GT SLASH {: return new NTATokenComponent(ID, u); :}
| SLASH LT ID GT SLASH {: return new NTATokenComponent(ID, new SimpleTypeUse("String")); :}
// Token
| LT ID COL type_use.u GT {: return new TokenComponent(ID, u); :}
| LT ID GT {: return new TokenComponent(ID, new SimpleTypeUse("String")); :}
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 relation_comp.l direction relation_comp.r SCOL
Relation relation
= RELATION unnamed_role.a LEFT navigable_role.b SCOL
{:
Relation result = new Relation();
if (direction instanceof LeftDirection) {
result.setLeft(r);
result.setDirection(new RightDirection());
result.setRight(l);
} else {
result.setLeft(l);
result.setDirection(direction);
result.setRight(r);
}
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;
:}
;
RelationComponent relation_comp =
// One
s_type_use.u DOT ID {: return new OneRelationComponent(ID, u); :}
| s_type_use.u {: return new OneRelationComponent("", u); :}
// Optional
| s_type_use.u DOT ID QUESTION_MARK {: return new OptionalRelationComponent(ID, u); :}
| s_type_use.u QUESTION_MARK {: return new OptionalRelationComponent("", u); :}
// Many
| s_type_use.u DOT ID STAR {: return new ManyRelationComponent(ID, u); :}
| s_type_use.u STAR {: return new ManyRelationComponent("", u); :}
UnnamedRole unnamed_role
= ID.type
{:
UnnamedRole result = new UnnamedRole();
result.setType(TypeDecl.createRef(type));
return result;
:}
| navigable_role
;
Direction direction =
RIGHT {: return new RightDirection(); :}
| LEFT {: return new LeftDirection(); :}
| BIDIRECTIONAL {: return new Bidirectional(); :}
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 {
return sb.toString();
}
public void Program.generateAbstractGrammar(StringBuilder sb) {
for (TypeDecl td: getTypeDecls()) {
td.generateAbstractGrammar(sb);
public void Program.generateAbstractGrammar(StringBuilder b) {
for (GrammarFile file : getGrammarFileList()) {
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()) {
sb.append("abstract ");
b.append("abstract ");
}
b.append(getName()).append(" ");
if (hasSuperType()) {
b.append(": ").append(getSuperType().getName()).append(" ");
}
b.append("::=");
for (Component component : getComponentList()) {
b.append(" ");
component.generateAbstractGrammar(b);
}
sb.append(getID());
if (hasSuper()) {
sb.append(" : " + getSuper());
b.append(";\n");
}
public abstract void Component.generateAbstractGrammar(StringBuilder b);
public void NormalComponent.generateAbstractGrammar(StringBuilder b) {
if (getNTA()) {
b.append("/");
}
if (getNumComponent() > 0 || relationComponents().size() > 0) {
sb.append(" ::=");
if (!getName().equals("")) {
b.append(getName()).append(":");
}
b.append(getTypeDecl().getName());
if (getNTA()) {
b.append("/");
}
for (Component c: getComponents()) {
sb.append(" ");
sb.append(c.generateAbstractGrammar());
}
sb.append(";\n");
public void ListComponent.generateAbstractGrammar(StringBuilder b) {
if (getNTA()) {
b.append("/");
}
public String Component.generateAbstractGrammar() {
if (getID().equals(getTypeUse().toString())) {
return getTypeUse().toString();
} 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 String OptComponent.generateAbstractGrammar() {
return "[" + super.generateAbstractGrammar() + "]";
public void OptComponent.generateAbstractGrammar(StringBuilder b) {
if (getNTA()) {
b.append("/");
}
public String NTAComponent.generateAbstractGrammar() {
return "/" + super.generateAbstractGrammar() + "/";
b.append("[");
if (!getName().equals("")) {
b.append(getName()).append(":");
}
public String NTAListComponent.generateAbstractGrammar() {
return "/" + super.generateAbstractGrammar() + "*/";
b.append(getTypeDecl().getName()).append("]");
if (getNTA()) {
b.append("/");
}
public String NTAOptComponent.generateAbstractGrammar() {
return "/[" + super.generateAbstractGrammar() + "]/";
}
public String TokenComponent.generateAbstractGrammar() {
return "<" + getID() + ":" + getTypeUse() + ">";
public void TokenComponent.generateAbstractGrammar(StringBuilder b) {
if (getNTA()) {
b.append("/");
}
public String NTATokenComponent.generateAbstractGrammar() {
return "/<" + getID() + ":" + getTypeUse() + ">/";
b.append("<");
if (!getName().equals("")) {
b.append(getName()).append(":");
}
getJavaTypeUse().generateAbstractGrammar(b);
b.append(">");
if (getNTA()) {
b.append("/");
}
}
abstract public void JavaTypeUse.generateAbstractGrammar(StringBuilder b);
public String Relation.generateAbstractGrammar() {
return "rel "
+ getLeft().generateAbstractGrammar() + " "
+ getDirection().generateAbstractGrammar() + " "
+ getRight().generateAbstractGrammar();
public void SimpleJavaTypeUse.generateAbstractGrammar(StringBuilder b) {
b.append(getName());
}
public String RelationComponent.generateAbstractGrammar() {
if (getID().isEmpty()) {
return getTypeUse().toString();
public void ParameterizedJavaTypeUse.generateAbstractGrammar(StringBuilder b) {
b.append("<");
boolean first = true;
for (JavaTypeUse javaTypeUse : getJavaTypeUseList()) {
if (first) {
first = false;
} else {
return getTypeUse() + "." + getID();
b.append(", ");
}
javaTypeUse.generateAbstractGrammar(b);
}
b.append(">");
}
abstract public void Relation.generateAbstractGrammar(StringBuilder b);
public void DirectedRelation.generateAbstractGrammar(StringBuilder b) {
b.append("rel ");
getSource().generateAbstractGrammar(b);
b.append(" -> ");
getTarget().generateAbstractGrammar(b);
b.append(";\n");
}
public String OptionalRelationComponent.generateAbstractGrammar() {
return super.generateAbstractGrammar() + "?";
public void BidirectionalRelation.generateAbstractGrammar(StringBuilder b) {
b.append("rel ");
getLeft().generateAbstractGrammar(b);
b.append(" <-> ");
getRight().generateAbstractGrammar(b);
b.append(";\n");
}
public String ManyRelationComponent.generateAbstractGrammar() {
return super.generateAbstractGrammar() + "*";
abstract public void Role.generateAbstractGrammar(StringBuilder b);
public void NormalRole.generateAbstractGrammar(StringBuilder b) {
b.append(getType().getName()).append(".").append(getName());
}
abstract public String Direction.generateAbstractGrammar();
public String RightDirection.generateAbstractGrammar() {
return "->";
public void ListRole.generateAbstractGrammar(StringBuilder b) {
b.append(getType().getName()).append(".").append(getName()).append("*");
}
public String LeftDirection.generateAbstractGrammar() {
return "<-";
public void OptRole.generateAbstractGrammar(StringBuilder b) {
b.append(getType().getName()).append(".").append(getName()).append("?");
}
public String Bidirectional.generateAbstractGrammar() {
return "<->";
public void UnnamedRole.generateAbstractGrammar(StringBuilder b) {
b.append(getType().getName());
}
}
......@@ -39,10 +39,10 @@ aspect Aspect {
}
abstract void SyncDefinition.generateAspect(StringBuilder sb);
@Override
void UpdateDefinition.generateAspect(StringBuilder sb) {
// TODO
}
// @Override
// void UpdateDefinition.generateAspect(StringBuilder sb) {
// // TODO
// }
// will be "addConnectionJoint_CurrentPosition" in example
/* // see discussion in codimd (InstanceLocation), why this won't work here
......@@ -60,14 +60,22 @@ aspect Aspect {
void ReadFromMqttDefinition.generateAspect(StringBuilder sb) {
sb.append("public void ").append("type").append(".connectTo(String topic) {\n")
.append(aspectIndent).append("mqttUpdater().addConnection")
.append(getTargetType().getID()).append("_")
.append(getTargetChild())
.append(getToken().containingTypeDecl().getName())
.append("_")
.append(getToken().getName())
.append("(this, topic);\n")
.append("}\n");
}
@Override
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;
import beaver.Parser;
import org.jastadd.ros2rag.ast.ErrorMessage;
import org.jastadd.ros2rag.ast.Program;
import org.jastadd.ros2rag.ast.Relation;
import org.jastadd.ros2rag.ast.TypeDecl;
import org.jastadd.ros2rag.ast.*;
import org.jastadd.ros2rag.compiler.options.CommandLine;
import org.jastadd.ros2rag.compiler.options.CommandLine.CommandLineException;
import org.jastadd.ros2rag.compiler.options.Option;
......@@ -46,20 +43,10 @@ public class Compiler {
List<String> filenames = commandLine.getArguments();
Program p = parseProgram(filenames);
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());
}
}
public static void main(String[] args) {
......@@ -110,6 +97,7 @@ public class Compiler {
parse(program, reader, fileName);
}
program.treeResolveAll();
return program;
}
......@@ -118,15 +106,8 @@ public class Compiler {
RelAstParser parser = new RelAstParser();
try {
Program newProgram = (Program) parser.parse(scanner);
for (TypeDecl typeDecl : newProgram.getTypeDeclList()) {
typeDecl.setFileName(file);
program.addTypeDecl(typeDecl);
}
for (Relation relation : newProgram.getRelationList()) {
relation.setFileName(file);
program.addRelation(relation);
}
GrammarFile newFile = (GrammarFile) parser.parse(scanner);
program.addGrammarFile(newFile);
} catch (IOException e) {
error(e.getMessage());
} catch (Parser.Exception e) {
......
......@@ -51,8 +51,8 @@ public class SimpleMain {
MappingDefinition mappingDefinition = new MappingDefinition();
mappingDefinition.setID("PoseToPosition");
mappingDefinition.setFrom(new SimpleTypeUse("PBPose"));
mappingDefinition.setTo(new SimpleTypeUse("Position"));
mappingDefinition.setFrom(TypeDecl.createRef("PBPose"));
mappingDefinition.setTo(TypeDecl.createRef("Position"));
mappingDefinition.setContent(" pose.position.x += sqrt(.5 * size.x)\n" +
" MAP round(2)\n" +
" x = x / 100\n" +
......@@ -62,11 +62,12 @@ public class SimpleMain {
ReadFromMqttDefinition readFromMqttDefinition = new ReadFromMqttDefinition();
readFromMqttDefinition.setAlwaysApply(false);
readFromMqttDefinition.setTargetType(new SimpleTypeUse("Joint"));
readFromMqttDefinition.setTargetChild("CurrentPosition");
readFromMqttDefinition.setMappingDefinitionUse(new MappingDefinitionUse("PoseToPosition"));
readFromMqttDefinition.setToken(TokenComponent.createRef("Joint.CurrentPosition"));
readFromMqttDefinition.setMapping(mappingDefinition);
model.addSyncDefinition(readFromMqttDefinition);
model.treeResolveAll();
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