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