diff --git a/src/main/jastadd/Errors.jrag b/src/main/jastadd/Errors.jrag
index 5cc6aedcbc3c699f8e3c38150177025c8fc90a64..39a1bfd05e9371a646ba7de7c626757b3734be55 100644
--- a/src/main/jastadd/Errors.jrag
+++ b/src/main/jastadd/Errors.jrag
@@ -50,17 +50,33 @@ aspect HelpAttributes {
   eq OptionalRelationComponent.multiplicityOpt() = true;
   syn boolean RelationComponent.multiplicityMany() = false;
   eq ManyRelationComponent.multiplicityMany() = true;
+
+  inh ContainedInFile Component.enclosingFileContainer();
+  eq TypeDecl.getComponent().enclosingFileContainer() = this;
+  eq Relation.getChild().enclosingFileContainer() = this;
+  inh ContainedInFile TypeUse.enclosingFileContainer();
+  eq SimpleTypeComponent.getTypeUse().enclosingFileContainer() = enclosingFileContainer();
+  eq TokenComponent.getTypeUse().enclosingFileContainer() = enclosingFileContainer();
+  eq TypeDecl.getSuper().enclosingFileContainer() = this;
+
+  syn String ASTNode.containedFile() = "Unknown";
+  eq Component.containedFile() = enclosingFileContainer() == null ? "Unknown2" : enclosingFileContainer().containedFile();
+  eq TypeUse.containedFile() = enclosingFileContainer() == null ? "Unknown3" : enclosingFileContainer().containedFile();
+  eq TypeDecl.containedFile() = getFileName();
+  eq Relation.containedFile() = getFileName();
 }
 
 aspect ErrorMessage {
   public class ErrorMessage implements Comparable<ErrorMessage> {
     private final ASTNode node;
+    private final String filename;
     private final int line;
     private final int col;
     private final String message;
 
     public ErrorMessage(ASTNode node, String message) {
       this.node = node;
+      this.filename = node.containedFile();
       this.line = node.getStartLine();
       this.col = node.getStartColumn();
       this.message = message;
@@ -80,12 +96,17 @@ aspect ErrorMessage {
     }
 
     public String toString() {
-      return "Line " + line + ", column " + col + ": " + message;
+      return filename + " Line " + line + ", column " + col + ": " + message;
     }
 
     @Override
     public int compareTo(ErrorMessage err) {
-      int n = line - err.line;
+      int n = filename.compareTo(err.filename);
+      if (n != 0) {
+        return n;
+      }
+
+      n = line - err.line;
       if (n != 0) {
         return n;
       }
@@ -102,4 +123,4 @@ aspect ErrorMessage {
   protected ErrorMessage ASTNode.error(String message) {
     return new ErrorMessage(this, message);
   }
-}
\ No newline at end of file
+}
diff --git a/src/main/jastadd/RelAst.ast b/src/main/jastadd/RelAst.ast
index 3a17c0cfb7fea19f5b33dc9a9bb8fe613137b12b..2b468e91198a0c103a4a6fdc5d2ab0f543f22ca8 100644
--- a/src/main/jastadd/RelAst.ast
+++ b/src/main/jastadd/RelAst.ast
@@ -1,5 +1,6 @@
 Program ::= TypeDecl* Relation*;
-TypeDecl ::= <ID> <Abstract:boolean> [Super:TypeUse] Component*;
+abstract ContainedInFile ::= <FileName> ;
+TypeDecl : ContainedInFile ::= <ID> <Abstract:boolean> [Super:TypeUse] Component*;
 
 abstract Component ::= <ID>;
 abstract SimpleTypeComponent : Component ::= TypeUse:SimpleTypeUse;
@@ -13,7 +14,7 @@ abstract TypeUse ::= <ID>;
 SimpleTypeUse : TypeUse;
 ParameterizedTypeUse : TypeUse ::= TypeUse*;
 
-Relation ::= Left:RelationComponent Direction Right:RelationComponent;
+Relation : ContainedInFile ::= Left:RelationComponent Direction Right:RelationComponent;
 abstract RelationComponent : SimpleTypeComponent;
 OneRelationComponent : RelationComponent;
 OptionalRelationComponent : RelationComponent;
diff --git a/src/main/jastadd/RelAst.parser b/src/main/jastadd/RelAst.parser
index 631b89cc3efc15a3634aeade29d1e84cbb96f4ce..24fb22b1a05e7fe0b150ad543ced5febc04095c6 100644
--- a/src/main/jastadd/RelAst.parser
+++ b/src/main/jastadd/RelAst.parser
@@ -6,9 +6,23 @@ Program goal =
 
 TypeDecl type_decl =
   ID type_decl_super.s components_opt.c SCOL
-  {: return new TypeDecl(ID, false, s, c); :}
+    {:
+      TypeDecl result = new TypeDecl();
+      result.setID(ID);
+      result.setAbstract(false);
+      result.setSuperOpt(s);
+      result.setComponentList(c);
+      return result;
+    :}
   | ABSTRACT ID type_decl_super.s components_opt.c SCOL
-  {: return new TypeDecl(ID, true, s, c); :}
+      {:
+        TypeDecl result = new TypeDecl();
+        result.setID(ID);
+        result.setAbstract(true);
+        result.setSuperOpt(s);
+        result.setComponentList(c);
+        return result;
+      :}
   ;
 
 Opt type_decl_super =
@@ -21,62 +35,68 @@ SimpleTypeUse s_type_use =
   ;
 
 TypeUse type_use =
-  s_type_use.u {: return u; :}
-  | parameterized_type_use.p {: return p; :}
+    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); :}
+  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); :}
+  type_use.u                              {: return new List().add(u); :}
+  | type_use_list.l COMMA type_use.u      {: return l.add(u); :}
   ;
 
 List components_opt =
-  /* empty */ {: return new List(); :}
-  | ASSIGN components.l {: return l; :}
+  /* empty */               {: return new List(); :}
+  | ASSIGN components.l     {: return l; :}
   ;
 
 List components =
-  {: return new List(); :}
-  | components.l component.c {: return l.add(c); :}
+  /* empty */                   {: return new List(); :}
+  | components.l component.c    {: return l.add(c); :}
   ;
 
 Component component =
-  ID COL s_type_use.u {: return new NormalComponent(ID, u); :}
-  | s_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 s_type_use.u STAR {: return new ListComponent(ID, u); :}
-  | s_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
-  | LBRACKET ID COL s_type_use.u RBRACKET {: return new OptComponent(ID, u); :}
-  | LBRACKET s_type_use.u RBRACKET {: return new OptComponent(u.getID(), u); :}
+  | LBRACKET ID COL s_type_use.u RBRACKET     {: return new OptComponent(ID, u); :}
+  | LBRACKET s_type_use.u RBRACKET            {: return new OptComponent(u.getID(), u); :}
   // NTA
-  | SLASH ID COL s_type_use.u SLASH {: return new NTAComponent(ID, u); :}
-  | SLASH s_type_use.u SLASH {: return new NTAComponent(u.getID(), u); :}
+  | SLASH ID COL s_type_use.u SLASH           {: return new NTAComponent(ID, u); :}
+  | SLASH s_type_use.u SLASH                  {: return new NTAComponent(u.getID(), u); :}
   // NTA Token (same as NTA)
-  | SLASH LT ID COL s_type_use.u GT SLASH {: return new NTAComponent(ID, u); :}
-  | SLASH LT s_type_use.u GT SLASH {: return new NTAComponent(u.getID(), u); :}
+  | SLASH LT ID COL s_type_use.u GT SLASH     {: return new NTAComponent(ID, u); :}
+  | SLASH LT s_type_use.u GT SLASH            {: return new NTAComponent(u.getID(), u); :}
   // Token
-  | LT ID COL type_use.u GT {: return new TokenComponent(ID, u); :}
-  | LT ID GT {: return new TokenComponent(ID, new SimpleTypeUse("String")); :}
+  | LT ID COL type_use.u GT                   {: return new TokenComponent(ID, u); :}
+  | LT ID GT                                  {: return new TokenComponent(ID, new SimpleTypeUse("String")); :}
   ;
 
 Relation relation =
   RELATION relation_comp.l direction relation_comp.r SCOL
-  {: return new Relation(l, direction, r); :}
+   {:
+      Relation result = new Relation();
+      result.setLeft(l);
+      result.setDirection(direction);
+      result.setRight(r);
+      return result;
+   :}
   ;
 
 RelationComponent relation_comp =
   // One
-  s_type_use.u DOT ID {: return new OneRelationComponent(ID, u); :}
-  | s_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
-  | s_type_use.u DOT ID QUESTION_MARK {: return new OptionalRelationComponent(ID, u); :}
-  | s_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
-  | s_type_use.u DOT ID STAR {: return new ManyRelationComponent(ID, u); :}
-  | s_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/src/main/java/org/jastadd/relast/compiler/Compiler.java b/src/main/java/org/jastadd/relast/compiler/Compiler.java
index cfdfb473517ba71c2ea68b6eb233fda1a4e785a4..0ec91633b0f04ea6415159ae74510184ab4fa97f 100644
--- a/src/main/java/org/jastadd/relast/compiler/Compiler.java
+++ b/src/main/java/org/jastadd/relast/compiler/Compiler.java
@@ -14,7 +14,7 @@ import java.util.List;
 
 public class Compiler {
 
-  private static final String VERSION = "0.2.1";
+  private static final String VERSION = "0.2.2";
 
   private ArrayList<Option<?>> options;
   private FlagOption optionWriteToFile;
@@ -177,9 +177,11 @@ public class Compiler {
     try {
       Program newProgram = (Program) parser.parse(scanner);
       for (TypeDecl typeDecl : newProgram.getTypeDeclList()) {
+        typeDecl.setFileName(file);
         program.addTypeDecl(typeDecl);
       }
       for (Relation relation : newProgram.getRelationList()) {
+        relation.setFileName(file);
         program.addRelation(relation);
       }
     } catch (IOException e) {
diff --git a/src/test/jastadd/errors/Errors.expected b/src/test/jastadd/errors/Errors.expected
index 93b0d7d9e8e17a2399c0e5fca93b2af03c0d43e0..01049a4a3ae266a25ed024698f93ad49b129aab2 100644
--- a/src/test/jastadd/errors/Errors.expected
+++ b/src/test/jastadd/errors/Errors.expected
@@ -1,5 +1,5 @@
 Errors:
-Line 5, column 5: Role name missing for type 'A'
-Line 6, column 15: Role name missing for type 'B'
-Line 7, column 12: The target of a directed relation cannot have a role name
-Line 8, column 13: The target of a directed relation may only have multiplicity 1
+$FILENAME Line 5, column 5: Role name missing for type 'A'
+$FILENAME Line 6, column 15: Role name missing for type 'B'
+$FILENAME Line 7, column 12: The target of a directed relation cannot have a role name
+$FILENAME Line 8, column 13: The target of a directed relation may only have multiplicity 1
diff --git a/src/test/jastadd/errors/Inheritance.expected b/src/test/jastadd/errors/Inheritance.expected
index 42aab57d7f2ea21c0440ff60a46e30191482c7de..048fc9760094a975cbe8e5ffec1207b72fcd55c9 100644
--- a/src/test/jastadd/errors/Inheritance.expected
+++ b/src/test/jastadd/errors/Inheritance.expected
@@ -1,3 +1,3 @@
 Errors:
-Line 2, column 12: Component 'X' is already declared for type 'B1'
-Line 6, column 5: Component 'X' is already declared for type 'B2'
+$FILENAME Line 2, column 12: Component 'X' is already declared for type 'B1'
+$FILENAME Line 6, column 5: Component 'X' is already declared for type 'B2'
diff --git a/src/test/jastadd/errors/Multiple.expected b/src/test/jastadd/errors/Multiple.expected
new file mode 100644
index 0000000000000000000000000000000000000000..f2e680e63959a02ce82d6a13ef730dcaa1b571b0
--- /dev/null
+++ b/src/test/jastadd/errors/Multiple.expected
@@ -0,0 +1,5 @@
+Errors:
+$FILENAME1 Line 5, column 5: Role name missing for type 'A'
+$FILENAME1 Line 6, column 15: Role name missing for type 'B'
+$FILENAME2 Line 1, column 12: The target of a directed relation cannot have a role name
+$FILENAME2 Line 2, column 13: The target of a directed relation may only have multiplicity 1
diff --git a/src/test/jastadd/errors/Multiple_1.relast b/src/test/jastadd/errors/Multiple_1.relast
new file mode 100644
index 0000000000000000000000000000000000000000..e66cfac704e5b63c965d4339ea6984815f650ed2
--- /dev/null
+++ b/src/test/jastadd/errors/Multiple_1.relast
@@ -0,0 +1,6 @@
+Program ::= A* B*;
+A;
+B;
+
+rel A -> B;
+rel A.bs* <-> B*;
diff --git a/src/test/jastadd/errors/Multiple_2.relast b/src/test/jastadd/errors/Multiple_2.relast
new file mode 100644
index 0000000000000000000000000000000000000000..4ffd076b84de87f180b274f6ee4af5abbcd6a29b
--- /dev/null
+++ b/src/test/jastadd/errors/Multiple_2.relast
@@ -0,0 +1,2 @@
+rel A.b -> B.b;
+rel A.b2 -> B*;
diff --git a/src/test/java/org/jastadd/relast/tests/Errors.java b/src/test/java/org/jastadd/relast/tests/Errors.java
index 63b597f3a1fb6eee6f969619ad9047f7c4736a73..8154c198c346527271bbd8768e35bf5e4eaa0394 100644
--- a/src/test/java/org/jastadd/relast/tests/Errors.java
+++ b/src/test/java/org/jastadd/relast/tests/Errors.java
@@ -9,6 +9,9 @@ import org.junit.jupiter.api.Test;
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
 import static org.jastadd.relast.tests.TestHelpers.exec;
 import static org.jastadd.relast.tests.TestHelpers.readFile;
@@ -17,39 +20,33 @@ import static org.jastadd.relast.tests.TestHelpers.readFile;
 class Errors {
 
   private static final Logger logger = LogManager.getLogger(Errors.class);
+  private static final String FILENAME_PATTERN = "$FILENAME";
+
   @Test
   void test1() throws IOException {
-
-    String inFile = "./src/test/jastadd/errors/Errors.relast";
-    String outFile = "./src/test/jastadd/errors/Errors.out";
-    String expectedFile = "./src/test/jastadd/errors/Errors.expected";
-
-    try {
-      System.out.println(System.getProperty("user.dir"));
-      int returnValue = exec(Compiler.class, new String[]{inFile}, new File(outFile));
-      Assertions.assertEquals(1, returnValue, "Relast did not return with value 1");
-    } catch (IOException | InterruptedException e) {
-      e.printStackTrace();
-    }
-
-    String out = readFile(outFile, Charset.defaultCharset());
-    String expected = readFile(expectedFile, Charset.defaultCharset());
-
-    Assertions.assertEquals(out, expected);
-
-    logger.info("'relast Errors.relast' returned \n{}", out);
+    test("Errors");
   }
 
   @Test
   void test2() throws IOException {
+    test("Inheritance");
+  }
 
-    String inFile = "./src/test/jastadd/errors/Inheritance.relast";
-    String outFile = "./src/test/jastadd/errors/Inheritance.out";
-    String expectedFile = "./src/test/jastadd/errors/Inheritance.expected";
+  @Test
+  void test3() throws IOException {
+    test("Multiple", "Multiple_1", "Multiple_2");
+  }
+
+  private void test(String name, String... inFilenames) throws IOException {
+    List<String> inFiles = Arrays.stream(inFilenames.length > 0 ? inFilenames : new String[]{name})
+        .map(f -> "./src/test/jastadd/errors/" + f + ".relast")
+        .collect(Collectors.toList());
+    String outFile = "./src/test/jastadd/errors/" + name + ".out";
+    String expectedFile = "./src/test/jastadd/errors/" + name + ".expected";
 
     try {
       System.out.println(System.getProperty("user.dir"));
-      int returnValue = exec(Compiler.class, new String[]{inFile}, new File(outFile));
+      int returnValue = exec(Compiler.class, inFiles.toArray(new String[0]), new File(outFile));
       Assertions.assertEquals(1, returnValue, "Relast did not return with value 1");
     } catch (IOException | InterruptedException e) {
       e.printStackTrace();
@@ -57,10 +54,16 @@ class Errors {
 
     String out = readFile(outFile, Charset.defaultCharset());
     String expected = readFile(expectedFile, Charset.defaultCharset());
+    if (inFiles.size() == 1) {
+      expected = expected.replace(FILENAME_PATTERN, inFiles.get(0));
+    } else {
+      for (int i = 0; i < inFiles.size(); i++) {
+        expected = expected.replace(FILENAME_PATTERN + (i + 1), inFiles.get(i));
+      }
+    }
+    Assertions.assertEquals(expected, out);
 
-    Assertions.assertEquals(out, expected);
-
-    logger.info("'relast Inheritance.relast' returned \n{}", out);
+    logger.info("relast for " + name + " returned \n{}", out);
   }