diff --git a/spec/jastadd/Analysis.jrag b/spec/jastadd/Analysis.jrag
index b7b0b8c704d1800c6ffdd69635c0343684774c8e..6972b0569b08ae4abb350b49befab04d81f0c51b 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 0000000000000000000000000000000000000000..3aee5c447dc1107a4d260c9a7f0390eec569028a
--- /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 a997303fa9d834ff9174ace66afe775acf97ebef..3aa6ff27a17bd45fd367ee44925005347b165e14 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 291055d02c977f55fec7696632bf3e113c12bb6d..3948cf27ce333d440ce68573072fba20f60bb1a0 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 e5692ee83981b84ce3c1f830e717779944a99570..4fd6591496cdb4ac9048fc94600ea129deaf6843 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()) {