diff --git a/relast.preprocessor b/relast.preprocessor
index 6fb98d06f2b05b735af78fe68b486c145eb730dc..54af6737685fab0be452f446b70b9842aba89e42 160000
--- a/relast.preprocessor
+++ b/relast.preprocessor
@@ -1 +1 @@
-Subproject commit 6fb98d06f2b05b735af78fe68b486c145eb730dc
+Subproject commit 54af6737685fab0be452f446b70b9842aba89e42
diff --git a/ros2rag.base/build.gradle b/ros2rag.base/build.gradle
index dcf62a1dd96ed1952a9bc9d9e70ad0b66ebe83ad..9c211eb06e5f2005c47e551de00fa4f4e70e9be4 100644
--- a/ros2rag.base/build.gradle
+++ b/ros2rag.base/build.gradle
@@ -114,14 +114,24 @@ jastadd {
             }
 
             scanner {
-                include "src/main/jastadd/Ros2Rag.flex"
+                basedir ".."
+                include "ros2rag.base/src/main/jastadd/scanner/Header.flex",               [-5]
+                include "relast.preprocessor/src/main/jastadd/scanner/Preamble.flex",      [-4]
+                include "relast.preprocessor/src/main/jastadd/scanner/Macros.flex",        [-3]
+                include "ros2rag.base/src/main/jastadd/scanner/Macros.flex",               [-3]
+                include "relast.preprocessor/src/main/jastadd/scanner/RulesPreamble.flex", [-2]
+                include "ros2rag.base/src/main/jastadd/scanner/MappingContent.flex",       [-1]
+                include "ros2rag.base/src/main/jastadd/scanner/Keywords.flex"
+                include "relast.preprocessor/src/main/jastadd/scanner/Keywords.flex"
+                include "relast.preprocessor/src/main/jastadd/scanner/Symbols.flex",        [1]
+                include "relast.preprocessor/src/main/jastadd/scanner/RulesPostamble.flex", [2]
             }
 
             parser {
                 basedir ".."
-                include "ros2rag.base/src/main/jastadd/Preamble.parser"
-                include "relast.preprocessor/src/main/jastadd/RelAst.parser"
-                include "ros2rag.base/src/main/jastadd/Ros2Rag.parser"
+                include "ros2rag.base/src/main/jastadd/parser/Preamble.parser"
+                include "ros2rag.base/src/main/jastadd/parser/Ros2Rag.parser"
+                include "relast.preprocessor/src/main/jastadd/parser/RelAst.parser"
             }
         }
     }
diff --git a/ros2rag.base/src/main/jastadd/Ros2Rag.flex b/ros2rag.base/src/main/jastadd/Ros2Rag.flex
deleted file mode 100644
index 1c0d48d60120f5c5a0afbd62ef6f677f66f86124..0000000000000000000000000000000000000000
--- a/ros2rag.base/src/main/jastadd/Ros2Rag.flex
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.jastadd.ros2rag.scanner;
-
-import org.jastadd.ros2rag.parser.Ros2RagParser.Terminals;
-
-%%
-
-%public
-%final
-%class Ros2RagScanner
-%extends beaver.Scanner
-
-%type beaver.Symbol
-%function nextToken
-%yylexthrow beaver.Scanner.Exception
-%scanerror Ros2RagScanner.ScannerError
-
-%line
-%column
-%{
-  private StringBuilder stringLitSb = new StringBuilder();
-
-  private beaver.Symbol sym(short id) {
-    return new beaver.Symbol(id, yyline + 1, yycolumn + 1, yylength(), yytext());
-  }
-
-  private beaver.Symbol sym(short id, String text) {
-    return new beaver.Symbol(id, yyline + 1, yycolumn + 1, yylength(), text);
-  }
-
-
-  public static class ScannerError extends Error {
-    public ScannerError(String message) {
-      super(message);
-    }
-  }
-%}
-
-WhiteSpace = [ ] | \t | \f | \n | \r | \r\n
-TraditionalComment   = [/][*][^*]*[*]+([^*/][^*]*[*]+)*[/]
-EndOfLineComment = "//" [^\n\r]*
-Comment = {TraditionalComment} | {EndOfLineComment}
-
-MappingContent = [{][:][^:]*[:]+([^:}][^:]*[:]+)*[}]
-
-ID = [a-zA-Z$_][a-zA-Z0-9$_]*
-
-%%
-{WhiteSpace} { /* ignore */ }
-{Comment}    { return sym(Terminals.COMMENT); }
-{MappingContent} { return sym(Terminals.MAPPING_CONTENT); }
-
-"abstract"   { return sym(Terminals.ABSTRACT); }
-"rel"        { return sym(Terminals.RELATION); }
-
-"read"       { return sym(Terminals.READ); }
-"write"      { return sym(Terminals.WRITE); }
-"using"      { return sym(Terminals.USING); }
-"canDependOn" { return sym(Terminals.CAN_DEPEND_ON); }
-"maps"       { return sym(Terminals.MAPS); }
-"to"         { return sym(Terminals.TO); }
-"as"         { return sym(Terminals.AS); }
-"with"       { return sym(Terminals.WITH); }
-
-";"          { return sym(Terminals.SCOL); }
-":"          { return sym(Terminals.COL); }
-"::="        { 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.LBRACKET); }
-"]"          { return sym(Terminals.RBRACKET); }
-"/"          { return sym(Terminals.SLASH); }
-"?"          { return sym(Terminals.QUESTION_MARK); }
-"->"         { return sym(Terminals.RIGHT); }
-"<-"         { return sym(Terminals.LEFT); }
-"<->"        { return sym(Terminals.BIDIRECTIONAL); }
-
-// ID
-{ID}         { return sym(Terminals.ID); }
-<<EOF>>      { return sym(Terminals.EOF); }
-
-[^]            { throw new ScannerError((yyline+1) +"," + (yycolumn+1) + ": Illegal character <"+yytext()+">"); }
diff --git a/ros2rag.base/src/main/jastadd/Preamble.parser b/ros2rag.base/src/main/jastadd/parser/Preamble.parser
similarity index 100%
rename from ros2rag.base/src/main/jastadd/Preamble.parser
rename to ros2rag.base/src/main/jastadd/parser/Preamble.parser
diff --git a/ros2rag.base/src/main/jastadd/Ros2Rag.parser b/ros2rag.base/src/main/jastadd/parser/Ros2Rag.parser
similarity index 100%
rename from ros2rag.base/src/main/jastadd/Ros2Rag.parser
rename to ros2rag.base/src/main/jastadd/parser/Ros2Rag.parser
diff --git a/ros2rag.base/src/main/jastadd/scanner/Header.flex b/ros2rag.base/src/main/jastadd/scanner/Header.flex
new file mode 100644
index 0000000000000000000000000000000000000000..974aa01fe70d15edbd4c80ac67169a18fe95f9e8
--- /dev/null
+++ b/ros2rag.base/src/main/jastadd/scanner/Header.flex
@@ -0,0 +1,17 @@
+package org.jastadd.ros2rag.scanner;
+
+import org.jastadd.ros2rag.parser.Ros2RagParser.Terminals;
+%%
+
+%public
+%final
+%class Ros2RagScanner
+%extends beaver.Scanner
+
+%type beaver.Symbol
+%function nextToken
+%yylexthrow beaver.Scanner.Exception
+%scanerror Ros2RagScanner.ScannerError
+
+%line
+%column
diff --git a/ros2rag.base/src/main/jastadd/scanner/Keywords.flex b/ros2rag.base/src/main/jastadd/scanner/Keywords.flex
new file mode 100644
index 0000000000000000000000000000000000000000..a570b82747b98ca71c71aa7a38d008164746b265
--- /dev/null
+++ b/ros2rag.base/src/main/jastadd/scanner/Keywords.flex
@@ -0,0 +1,8 @@
+"read"       { return sym(Terminals.READ); }
+"write"      { return sym(Terminals.WRITE); }
+"using"      { return sym(Terminals.USING); }
+"canDependOn" { return sym(Terminals.CAN_DEPEND_ON); }
+"maps"       { return sym(Terminals.MAPS); }
+"to"         { return sym(Terminals.TO); }
+"as"         { return sym(Terminals.AS); }
+"with"       { return sym(Terminals.WITH); }
diff --git a/ros2rag.base/src/main/jastadd/scanner/Macros.flex b/ros2rag.base/src/main/jastadd/scanner/Macros.flex
new file mode 100644
index 0000000000000000000000000000000000000000..08bb629fe2f9c10db42ab6e4587918447e330a63
--- /dev/null
+++ b/ros2rag.base/src/main/jastadd/scanner/Macros.flex
@@ -0,0 +1 @@
+MappingContent = [{][:][^:]*[:]+([^:}][^:]*[:]+)*[}]
diff --git a/ros2rag.base/src/main/jastadd/scanner/MappingContent.flex b/ros2rag.base/src/main/jastadd/scanner/MappingContent.flex
new file mode 100644
index 0000000000000000000000000000000000000000..fdf3f205113e79a007bc7f5bb9d5f28433f7f387
--- /dev/null
+++ b/ros2rag.base/src/main/jastadd/scanner/MappingContent.flex
@@ -0,0 +1 @@
+{MappingContent} { return sym(Terminals.MAPPING_CONTENT); }