From b63622abab4e4754941e52c1d49f95ec1c54fd28 Mon Sep 17 00:00:00 2001 From: Niklas Fors <niklas.fors@cs.lth.se> Date: Tue, 3 Jul 2018 13:38:20 +0200 Subject: [PATCH] Add semantic analysis --- build.xml | 8 +-- spec/jastadd/Analysis.jrag | 69 ++++++++++++++++++- spec/jastadd/Errors.jrag | 27 ++++++-- spec/jastadd/RelAst.ast | 12 ++-- spec/parser/RelAstBase.parser | 16 ++--- .../org/jastadd/relast/compiler/Compiler.java | 6 +- 6 files changed, 107 insertions(+), 31 deletions(-) diff --git a/build.xml b/build.xml index 7dad026..a35cb94 100755 --- a/build.xml +++ b/build.xml @@ -1,6 +1,5 @@ <project name="RelAstCompiler" default="build" basedir="."> <property name="srcdir" value="${basedir}/src" /> - <property name="resourcedir" value="${srcdir}/resource" /> <property name="gendir" value="${srcdir}/generated" /> <property name="bindir" value="${basedir}/ant-bin" /> <property name="docdir" value="${basedir}/doc" /> @@ -43,9 +42,6 @@ target="8" source="8" /> - <copy todir="${bindir}/"> - <fileset dir="${resourcedir}"/> - </copy> </target> <!-- generate compiler source files --> @@ -93,7 +89,6 @@ <delete file="${jarfile}" /> <delete> <fileset dir="." includes="**/*.class" excludes="bin/" /> - <fileset dir="testfiles/code_generation/" includes="*.c *.executable *.out"/> </delete> </target> @@ -118,9 +113,8 @@ <target name="jar" depends="build"> <jar destfile="${jarfile}"> - <fileset dir="${bindir}" includes="**/*.class,resource/" excludes="org/jastadd/relast/tests/*" /> + <fileset dir="${bindir}" includes="**/*.class" excludes="org/jastadd/relast/tests/*" /> <fileset dir="${srcdir}/java" includes="**/*.java" excludes="org/jastadd/relast/tests/*" /> - <fileset dir="${resourcedir}" includes="**" /> <fileset dir="${gendir}" includes="**/*.java" /> <zipfileset includes="**/*.class" src="${tools}/beaver-rt.jar"/> <manifest> diff --git a/spec/jastadd/Analysis.jrag b/spec/jastadd/Analysis.jrag index 8aa8502..b7b0b8c 100644 --- a/spec/jastadd/Analysis.jrag +++ b/spec/jastadd/Analysis.jrag @@ -1,6 +1,71 @@ import java.util.*; -aspect Analysis { +aspect TypeAnalysis { + syn TypeDecl TypeUse.decl() = lookupType(getID()); + inh TypeDecl TypeUse.lookupType(String name); + eq Program.getChild().lookupType(String name) { + for (TypeDecl td: getTypeDecls()) { + if (td.getID().equals(name)) { + return td; + } + } + return null; + } + syn boolean TypeDecl.isAlreadyDeclared() + = lookupType(getID()) != this; + inh TypeDecl TypeDecl.lookupType(String name); +} -} \ No newline at end of file +aspect ComponentAnalysis { + syn String Component.name() { + if (!getID().isEmpty()) { + return getID(); + } + return otherRelationSideName(); + } + inh String Component.otherRelationSideName(); + eq Relation.getLeft().otherRelationSideName() + = getRight().getTypeUse().getID(); + eq Relation.getRight().otherRelationSideName() + = getLeft().getTypeUse().getID(); + eq Program.getChild().otherRelationSideName() + = ""; + + syn TypeDecl Component.typeDecl() = enclosingTypeDecl(); + eq RelationComponent.typeDecl() = getTypeUse().decl(); + inh TypeDecl Component.enclosingTypeDecl(); + eq TypeDecl.getChild().enclosingTypeDecl() = this; + eq Program.getChild().enclosingTypeDecl() = null; + + syn boolean Component.isAlreadyDeclared() + = lookupComponent(typeDecl(), name()) != this; + inh Component Component.lookupComponent(TypeDecl td, String name); + eq Program.getChild().lookupComponent(TypeDecl td, String name) { + if (td != null) { + for (Component c: td.getComponents()) { + if (c.name().equals(name)) { + return c; + } + } + } + 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(); + } + } + return null; + } +} + +aspect Utils { + public String TypeUse.toString() { + return getID(); + } + public String TypeDecl.toString() { + return getID(); + } +} diff --git a/spec/jastadd/Errors.jrag b/spec/jastadd/Errors.jrag index 788a383..a997303 100644 --- a/spec/jastadd/Errors.jrag +++ b/spec/jastadd/Errors.jrag @@ -3,14 +3,31 @@ import java.util.TreeSet; import java.util.LinkedList; aspect Errors { -// coll Set<ErrorMessage> Program.errors() -// [new TreeSet<ErrorMessage>()] -// root Program; + coll Set<ErrorMessage> Program.errors() + [new TreeSet<ErrorMessage>()] + root Program; + + TypeUse contributes error("Type '" + getID() + "' not found") + when decl() == null && !isToken() + to Program.errors(); + + TypeDecl contributes error("Type '" + getID() + "' is already declared") + when isAlreadyDeclared() + to Program.errors(); + + Component contributes error("Component '" + name() + + "' is already declared for type '" + typeDecl() + "'") + when isAlreadyDeclared() + to Program.errors(); } aspect HelpAttributes { -// inh Program ASTNode.program(); -// eq Program.getChild().program() = this; + inh Program ASTNode.program(); + eq Program.getChild().program() = this; + + inh boolean TypeUse.isToken(); + eq Program.getChild().isToken() = false; + eq TokenComponent.getTypeUse().isToken() = true; } aspect ErrorMessage { diff --git a/spec/jastadd/RelAst.ast b/spec/jastadd/RelAst.ast index cf320aa..82bf011 100644 --- a/spec/jastadd/RelAst.ast +++ b/spec/jastadd/RelAst.ast @@ -9,13 +9,11 @@ OptComponent : Component; TypeUse ::= <ID>; -Relation ::= Left:RelationSide Direction Right:RelationSide; -abstract RelationSide ::= TypeUse <ID>; -OneRelationSide : RelationSide; -OptionalRelationSide : RelationSide; -ManyRelationSide : RelationSide; - - +Relation ::= Left:RelationComponent Direction Right:RelationComponent; +abstract RelationComponent : Component; +OneRelationComponent : RelationComponent; +OptionalRelationComponent : RelationComponent; +ManyRelationComponent : RelationComponent; abstract Direction; RightDirection : Direction; Bidirectional : Direction; \ No newline at end of file diff --git a/spec/parser/RelAstBase.parser b/spec/parser/RelAstBase.parser index dac3519..291055d 100644 --- a/spec/parser/RelAstBase.parser +++ b/spec/parser/RelAstBase.parser @@ -54,20 +54,20 @@ List relations = ; Relation relation = - RELATION relation_side.l direction relation_side.r SCOL + RELATION relation_comp.l direction relation_comp.r SCOL {: return new Relation(l, direction, r); :} ; -RelationSide relation_side = +RelationComponent relation_comp = // One - type_use.u DOT ID {: return new OneRelationSide(u, ID); :} - | type_use.u {: return new OneRelationSide(u, ""); :} + type_use.u DOT ID {: return new OneRelationComponent(ID, u); :} + | type_use.u {: return new OneRelationComponent("", u); :} // Optional - | LBRACKET type_use.u DOT ID RBRACKET {: return new OptionalRelationSide(u, ID); :} - | LBRACKET type_use.u RBRACKET {: return new OptionalRelationSide(u, ""); :} + | 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 ManyRelationSide(u, ID); :} - | type_use.u STAR {: return new ManyRelationSide(u, ""); :} + | type_use.u STAR DOT ID {: return new ManyRelationComponent(ID, u); :} + | type_use.u STAR {: return new ManyRelationComponent("", u); :} ; Direction direction = diff --git a/src/java/org/jastadd/relast/compiler/Compiler.java b/src/java/org/jastadd/relast/compiler/Compiler.java index 397ee2a..e5692ee 100644 --- a/src/java/org/jastadd/relast/compiler/Compiler.java +++ b/src/java/org/jastadd/relast/compiler/Compiler.java @@ -33,14 +33,16 @@ public class Compiler { Program p = parseProgram(commandLine.getArguments().get(0)); - System.out.println(p.dumpTree()); - /*if (!p.errors().isEmpty()) { + if (!p.errors().isEmpty()) { System.err.println("Errors:"); for (ErrorMessage e: p.errors()) { System.err.println(e); } System.exit(1); } else { + System.out.println(p.dumpTree()); + } +/* } else { if (optionPrintDot.isSet()) { System.out.println(p.genDot()); } else if (optionFlatPrettyPrint.isSet()) { -- GitLab