From 83ee58cb2f40c40e7e328b390a046db3fea7219c Mon Sep 17 00:00:00 2001 From: Niklas Fors <niklas.fors@cs.lth.se> Date: Thu, 5 Jul 2018 15:32:59 +0200 Subject: [PATCH] Support parameterized types in intrinsic attributes --- spec/jastadd/Analysis.jrag | 19 ++++++++++++++-- spec/jastadd/RelAst.ast | 17 ++++++++------ spec/parser/RelAstBase.parser | 42 ++++++++++++++++++++++------------- spec/scanner/RelAst.flex | 3 ++- test/.gitignore | 2 ++ test/Makefile | 7 ++++-- 6 files changed, 63 insertions(+), 27 deletions(-) diff --git a/spec/jastadd/Analysis.jrag b/spec/jastadd/Analysis.jrag index f71c225..223a1fb 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 82bf011..3a7116e 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 7c12f1f..6b99a76 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 1e40019..44ec2a2 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 f09d75c..12f898e 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 d30d502..4f66686 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 -- GitLab