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

switch to relast

parent b49db15d
No related branches found
No related tags found
No related merge requests found
Pipeline #6231 passed
......@@ -55,15 +55,15 @@ jar {
}
}
task preprocess(type: JavaExec) {
task relast(type: JavaExec) {
group = 'Build'
main = "-jar"
doFirst {
delete "./src/gen/jastadd/*.ast"
delete "./src/gen/jastadd/RelAst.jadd"
delete "./src/gen/jastadd/RelAstRefResolver.jadd"
delete "./src/gen/jastadd/RelAstResolverStubs.jrag"
delete "src/gen/jastadd/*.ast"
delete "src/gen/jastadd/RelAst.jadd"
delete "src/gen/jastadd/RelAstRefResolver.jadd"
delete "src/gen/jastadd/RelAstResolverStubs.jrag"
mkdir "src/gen/jastadd/"
}
......@@ -78,12 +78,12 @@ task preprocess(type: JavaExec) {
"--grammarName=./src/gen/jastadd/RelAST"
]
inputs.files file("./src/main/jastadd/RelAST.relast"),
file("./libs/relast.jar")
inputs.files file("src/main/jastadd/RelAST.relast"),
file("libs/relast.jar")
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')
file("src/gen/jastadd/RelAst.jadd"),
file("src/gen/jastadd/RelAstRefResolver.jadd"),
file('src/gen/jastadd/RelAstResolverStubs.jrag')
}
jastadd {
......@@ -99,13 +99,13 @@ jastadd {
}
jastadd {
basedir "src/"
include "main/jastadd/**/*.ast"
include "main/jastadd/**/*.jadd"
include "main/jastadd/**/*.jrag"
include "gen/jastadd/**/*.ast"
include "gen/jastadd/**/*.jadd"
include "gen/jastadd/**/*.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 {
......@@ -143,7 +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 preprocess
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();
// 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;
}
......@@ -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 ::= 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;
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>;
......@@ -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());
}
}
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) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment