diff --git a/spec/jastadd/Analysis.jrag b/spec/jastadd/Analysis.jrag index f71c225ffeb3f2f19fa716f7aee9bc7f2198f915..223a1fbebd5674c09da1fe4c3fa644d8322b0bf6 100644 --- a/spec/jastadd/Analysis.jrag +++ b/spec/jastadd/Analysis.jrag @@ -2,6 +2,8 @@ import java.util.*; aspect TypeAnalysis { + public abstract TypeUse Component.getTypeUse(); + syn TypeDecl TypeUse.decl() = lookupType(getID()); inh TypeDecl TypeUse.lookupType(String name); eq Program.getChild().lookupType(String name) { @@ -37,7 +39,7 @@ aspect ComponentAnalysis { eq Relation.getLeft().otherSide() = getRight(); eq Relation.getRight().otherSide() = getLeft(); eq Program.getChild().otherSide() = null; - + syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().toTypeDecl(); syn boolean Component.isAlreadyDeclared() @@ -102,9 +104,22 @@ aspect Constructors { } aspect Utils { - public String TypeUse.toString() { + public String SimpleTypeUse.toString() { return getID(); } + public String ParameterizedTypeUse.toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getID()).append("<"); + int i = 0; + for (TypeUse u: getTypeUses()) { + sb.append(u.toString()); + if (++i < getNumTypeUse()) { + sb.append(", "); + } + } + sb.append(">"); + return sb.toString(); + } public String TypeDecl.toString() { return getID(); } diff --git a/spec/jastadd/RelAst.ast b/spec/jastadd/RelAst.ast index 82bf0117f54d78542df004e1f9a8a4a78ab1569c..3a7116ec1544d7626f9c01c50cca60cb6892563f 100644 --- a/spec/jastadd/RelAst.ast +++ b/spec/jastadd/RelAst.ast @@ -1,16 +1,19 @@ Program ::= TypeDecl* Relation*; TypeDecl ::= <ID> <Abstract:boolean> [Super:TypeUse] Component*; -abstract Component ::= <ID> TypeUse; -NormalComponent : Component; -ListComponent : Component; -TokenComponent : Component; -OptComponent : Component; +abstract Component ::= <ID>; +abstract SimpleTypeComponent : Component ::= TypeUse:SimpleTypeUse; +NormalComponent : SimpleTypeComponent; +ListComponent : SimpleTypeComponent; +OptComponent : SimpleTypeComponent; +TokenComponent : Component ::= TypeUse; -TypeUse ::= <ID>; +abstract TypeUse ::= <ID>; +SimpleTypeUse : TypeUse; +ParameterizedTypeUse : TypeUse ::= TypeUse*; Relation ::= Left:RelationComponent Direction Right:RelationComponent; -abstract RelationComponent : Component; +abstract RelationComponent : SimpleTypeComponent; OneRelationComponent : RelationComponent; OptionalRelationComponent : RelationComponent; ManyRelationComponent : RelationComponent; diff --git a/spec/parser/RelAstBase.parser b/spec/parser/RelAstBase.parser index 7c12f1f743788dace568fb8e885d4ca063f7da59..6b99a763a260231dfd0badc387d1b1802800356e 100644 --- a/spec/parser/RelAstBase.parser +++ b/spec/parser/RelAstBase.parser @@ -17,11 +17,23 @@ TypeDecl type_decl = Opt type_decl_super = /* empty */ {: return new Opt(); :} - | COL type_use.u {: return new Opt(u); :} + | COL s_type_use.u {: return new Opt(u); :} + ; + +SimpleTypeUse s_type_use = + ID {: return new SimpleTypeUse(ID); :} ; TypeUse type_use = - ID {: return new TypeUse(ID); :} + s_type_use.u {: return u; :} + | parameterized_type_use.p {: return p; :} + ; +ParameterizedTypeUse parameterized_type_use = + ID LT type_use_list.l GT {: return new ParameterizedTypeUse(ID, l); :} + ; +List type_use_list = + type_use.u {: return new List().add(u); :} + | type_use_list.l COMMA type_use.u {: return l.add(u); :} ; List components_opt = @@ -35,17 +47,17 @@ List components = ; Component component = - ID COL type_use.u {: return new NormalComponent(ID, u); :} - | type_use.u {: return new NormalComponent(u.getID(), u); :} + ID COL s_type_use.u {: return new NormalComponent(ID, u); :} + | s_type_use.u {: return new NormalComponent(u.getID(), u); :} // List - | ID COL type_use.u STAR {: return new ListComponent(ID, u); :} - | type_use.u STAR {: return new ListComponent(u.getID(), u); :} + | ID COL s_type_use.u STAR {: return new ListComponent(ID, u); :} + | s_type_use.u STAR {: return new ListComponent(u.getID(), u); :} // Opt - | ID COL type_use.u QUESTION_MARK {: return new OptComponent(ID, u); :} - | type_use.u QUESTION_MARK {: return new OptComponent(u.getID(), u); :} + | ID COL s_type_use.u QUESTION_MARK {: return new OptComponent(ID, u); :} + | s_type_use.u QUESTION_MARK {: return new OptComponent(u.getID(), u); :} // Token | LT ID COL type_use.u GT {: return new TokenComponent(ID, u); :} - | LT ID GT {: return new TokenComponent(ID, new TypeUse("String")); :} + | LT ID GT {: return new TokenComponent(ID, new SimpleTypeUse("String")); :} ; List relations = @@ -60,14 +72,14 @@ Relation relation = RelationComponent relation_comp = // One - type_use.u DOT ID {: return new OneRelationComponent(ID, u); :} - | type_use.u {: return new OneRelationComponent("", u); :} + s_type_use.u DOT ID {: return new OneRelationComponent(ID, u); :} + | s_type_use.u {: return new OneRelationComponent("", u); :} // Optional - | type_use.u DOT ID QUESTION_MARK {: return new OptionalRelationComponent(ID, u); :} - | type_use.u QUESTION_MARK {: return new OptionalRelationComponent("", u); :} + | s_type_use.u DOT ID QUESTION_MARK {: return new OptionalRelationComponent(ID, u); :} + | s_type_use.u QUESTION_MARK {: return new OptionalRelationComponent("", u); :} // Many - | type_use.u DOT ID STAR {: return new ManyRelationComponent(ID, u); :} - | type_use.u STAR {: return new ManyRelationComponent("", u); :} + | s_type_use.u DOT ID STAR {: return new ManyRelationComponent(ID, u); :} + | s_type_use.u STAR {: return new ManyRelationComponent("", u); :} ; Direction direction = diff --git a/spec/scanner/RelAst.flex b/spec/scanner/RelAst.flex index 1e4001989901e5377c152a9a0933fe136a7ff20a..44ec2a284059625c3cd71166f8cba80d213378da 100644 --- a/spec/scanner/RelAst.flex +++ b/spec/scanner/RelAst.flex @@ -40,7 +40,7 @@ TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/" EndOfLineComment = "//" [^\n|\r|\r\n]* Comment = {TraditionalComment} | {EndOfLineComment} -ID = [a-zA-Z$][a-zA-Z0-9$_]* +ID = [a-zA-Z$_][a-zA-Z0-9$_]* %state STRING @@ -57,6 +57,7 @@ ID = [a-zA-Z$][a-zA-Z0-9$_]* "::=" { return sym(Terminals.ASSIGN); } "*" { return sym(Terminals.STAR); } "." { return sym(Terminals.DOT); } + "," { return sym(Terminals.COMMA); } "<" { return sym(Terminals.LT); } ">" { return sym(Terminals.GT); } "?" { return sym(Terminals.QUESTION_MARK); } diff --git a/test/.gitignore b/test/.gitignore index f09d75c9089a0b724a1dfb2700a4ebb1656bcb53..12f898e8d2252730be738bf6f990bdb9fe84c16e 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,3 +1,5 @@ /AST/* /AllGen.ast /AllGen.jadd +/AllGenGen.ast +/AllGenGen.jadd diff --git a/test/Makefile b/test/Makefile index d30d502dfded3fb154d8eb4a4eec13d34c8d9224..4f66686a2a0c34dfd5f9b4b6adb1aac23204b146 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,8 +1,11 @@ -all: compile run +all: compile run check-idempotent compile: (cd .. && ant jar) java -jar ../relast-compiler.jar All.relast --file java -jar ../tools/jastadd2.jar --package=AST AllGen.ast AllGen.jadd Utils.jadd run: javac AST/*.java Test.java - java Test \ No newline at end of file + java Test +check-idempotent: + java -jar ../relast-compiler.jar AllGen.ast --file + diff AllGen.ast AllGenGen.ast