From 0fbf8618466d65c2e1907e597b27aa1c041edc36 Mon Sep 17 00:00:00 2001
From: Niklas Fors <niklas.fors@cs.lth.se>
Date: Tue, 3 Jul 2018 14:52:20 +0200
Subject: [PATCH] Add code generation for abstract grammar and fix bug
---
spec/jastadd/Analysis.jrag | 44 ++++++++++---
spec/jastadd/Backend.jadd | 61 +++++++++++++++++++
spec/jastadd/Errors.jrag | 2 +-
spec/parser/RelAstBase.parser | 2 +-
.../org/jastadd/relast/compiler/Compiler.java | 2 +-
5 files changed, 99 insertions(+), 12 deletions(-)
create mode 100644 spec/jastadd/Backend.jadd
diff --git a/spec/jastadd/Analysis.jrag b/spec/jastadd/Analysis.jrag
index b7b0b8c..6972b05 100644
--- a/spec/jastadd/Analysis.jrag
+++ b/spec/jastadd/Analysis.jrag
@@ -18,7 +18,17 @@ aspect TypeAnalysis {
}
aspect ComponentAnalysis {
+ syn boolean Component.isDeclaringName() = true;
+ eq RelationComponent.isDeclaringName() = !isTargetOfRightDirection();
+ inh boolean RelationComponent.isTargetOfRightDirection();
+ eq Relation.getRight().isTargetOfRightDirection()
+ = getDirection() instanceof RightDirection;
+ eq Program.getChild().isTargetOfRightDirection() = false;
+
syn String Component.name() {
+ if (!isDeclaringName()) {
+ return "";
+ }
if (!getID().isEmpty()) {
return getID();
}
@@ -32,14 +42,18 @@ aspect ComponentAnalysis {
eq Program.getChild().otherRelationSideName()
= "";
- syn TypeDecl Component.typeDecl() = enclosingTypeDecl();
- eq RelationComponent.typeDecl() = getTypeUse().decl();
+ syn TypeDecl Component.toTypeDecl() = enclosingTypeDecl();
+ eq RelationComponent.toTypeDecl() = getTypeUse().decl();
inh TypeDecl Component.enclosingTypeDecl();
eq TypeDecl.getChild().enclosingTypeDecl() = this;
eq Program.getChild().enclosingTypeDecl() = null;
+ inh TypeDecl RelationComponent.ofTypeDecl();
+ eq Relation.getLeft().ofTypeDecl() = getRight().toTypeDecl();
+ eq Relation.getRight().ofTypeDecl() = getLeft().toTypeDecl();
+ eq Program.getChild().ofTypeDecl() = null;
syn boolean Component.isAlreadyDeclared()
- = lookupComponent(typeDecl(), name()) != this;
+ = isDeclaringName() && lookupComponent(toTypeDecl(), name()) != this;
inh Component Component.lookupComponent(TypeDecl td, String name);
eq Program.getChild().lookupComponent(TypeDecl td, String name) {
if (td != null) {
@@ -50,15 +64,27 @@ aspect ComponentAnalysis {
}
}
for (Relation r: getRelations()) {
- if (r.getLeft().typeDecl() == td && r.getLeft().name().equals(name)) {
- return r.getLeft();
- }
- if (r.getRight().typeDecl() == td && r.getRight().name().equals(name)) {
- return r.getRight();
- }
+ Component c = r.getLeft().lookup(td, name);
+ if (c != null) return c;
+ c = r.getRight().lookup(td, name);
+ if (c != null) return c;
}
return null;
}
+
+ syn RelationComponent RelationComponent.lookup(TypeDecl td, String name)
+ = isDeclaringName() && toTypeDecl() == td && name().equals(name)
+ ? this
+ : null;
+
+
+ coll Set<RelationComponent> TypeDecl.relationComponents()
+ [new HashSet<RelationComponent>()]
+ root Program;
+ RelationComponent contributes this
+ when isDeclaringName() && toTypeDecl() != null
+ to TypeDecl.relationComponents()
+ for toTypeDecl();
}
aspect Utils {
diff --git a/spec/jastadd/Backend.jadd b/spec/jastadd/Backend.jadd
new file mode 100644
index 0000000..3aee5c4
--- /dev/null
+++ b/spec/jastadd/Backend.jadd
@@ -0,0 +1,61 @@
+aspect BackendAbstractGrammar {
+ public String Program.generateAbstractGrammar() {
+ StringBuilder sb = new StringBuilder();
+ generateAbstractGrammar(sb);
+ return sb.toString();
+ }
+
+ public void Program.generateAbstractGrammar(StringBuilder sb) {
+ for (TypeDecl td: getTypeDecls()) {
+ td.generateAbstractGrammar(sb);
+ }
+ }
+
+ public void TypeDecl.generateAbstractGrammar(StringBuilder sb) {
+ if (getAbstract()) {
+ sb.append("abstract ");
+ }
+ sb.append(getID());
+ if (hasSuper()) {
+ sb.append(" : " + getSuper());
+ }
+
+ if (getNumComponent() > 0 || relationComponents().size() > 0) {
+ sb.append(" ::=");
+ }
+ for (Component c: getComponents()) {
+ sb.append(" ");
+ sb.append(c.generateAbstractGrammar());
+ }
+ for (RelationComponent c: relationComponents()) {
+ sb.append(" ");
+ sb.append(c.generateAbstractGrammar());
+ }
+
+ sb.append(";\n");
+ }
+
+ public String Component.generateAbstractGrammar() {
+ if (getID().equals(getTypeUse().toString())) {
+ return getTypeUse().toString();
+ } else {
+ return getID() + ":" + getTypeUse();
+ }
+ }
+ public String ListComponent.generateAbstractGrammar() {
+ return super.generateAbstractGrammar() + "*";
+ }
+ public String OptComponent.generateAbstractGrammar() {
+ return "[" + super.generateAbstractGrammar() + "]";
+ }
+ public String TokenComponent.generateAbstractGrammar() {
+ return "<" + getID() + ":" + getTypeUse() + ">";
+ }
+
+ public String RelationComponent.generateAbstractGrammar() {
+ return "<_impl_" + getID() + ":" + ofTypeDecl() + ">";
+ }
+ public String ManyRelationComponent.generateAbstractGrammar() {
+ return "<_impl_" + getID() + ":MySet<" + ofTypeDecl() + ">>";
+ }
+}
\ No newline at end of file
diff --git a/spec/jastadd/Errors.jrag b/spec/jastadd/Errors.jrag
index a997303..3aa6ff2 100644
--- a/spec/jastadd/Errors.jrag
+++ b/spec/jastadd/Errors.jrag
@@ -16,7 +16,7 @@ aspect Errors {
to Program.errors();
Component contributes error("Component '" + name()
- + "' is already declared for type '" + typeDecl() + "'")
+ + "' is already declared for type '" + toTypeDecl() + "'")
when isAlreadyDeclared()
to Program.errors();
}
diff --git a/spec/parser/RelAstBase.parser b/spec/parser/RelAstBase.parser
index 291055d..3948cf2 100644
--- a/spec/parser/RelAstBase.parser
+++ b/spec/parser/RelAstBase.parser
@@ -66,7 +66,7 @@ RelationComponent relation_comp =
| LBRACKET type_use.u DOT ID RBRACKET {: return new OptionalRelationComponent(ID, u); :}
| LBRACKET type_use.u RBRACKET {: return new OptionalRelationComponent("", u); :}
// Many
- | type_use.u STAR DOT ID {: return new ManyRelationComponent(ID, u); :}
+ | type_use.u DOT ID STAR {: return new ManyRelationComponent(ID, u); :}
| type_use.u STAR {: return new ManyRelationComponent("", u); :}
;
diff --git a/src/java/org/jastadd/relast/compiler/Compiler.java b/src/java/org/jastadd/relast/compiler/Compiler.java
index e5692ee..4fd6591 100644
--- a/src/java/org/jastadd/relast/compiler/Compiler.java
+++ b/src/java/org/jastadd/relast/compiler/Compiler.java
@@ -40,7 +40,7 @@ public class Compiler {
}
System.exit(1);
} else {
- System.out.println(p.dumpTree());
+ System.out.println(p.generateAbstractGrammar());
}
/* } else {
if (optionPrintDot.isSet()) {
--
GitLab