diff --git a/src/main/grammar/RelAstGrammar.bnf b/src/main/grammar/RelAstGrammar.bnf
index 61f75224407a992a644067159b7b81c373e25a24..cf66ba0d2edb46dc0defec346c70c135ebdd801e 100644
--- a/src/main/grammar/RelAstGrammar.bnf
+++ b/src/main/grammar/RelAstGrammar.bnf
@@ -13,8 +13,26 @@
   tokenTypeClass="org.jastadd.tooling.parser.RelAstGrammarTokenType"
 }
 
-simpleFile ::= item_*
+relAstGrammarFile ::= comment* declaration*
 
-private item_ ::= (property|COMMENT|CRLF)
+declaration ::= (type_decl | relation) comment*
 
-property ::= (KEY? SEPARATOR VALUE?) | KEY
+comment ::= (WHITESPACE | MULTILINECOMMENT | DOCCOMMENT | SINGLELINECOMMENT)
+
+type_decl ::= ABSTRACT? ID (COL ID)? (ASSIGN component*)? SCOL
+
+component ::= (SLASH actual_component SLASH) | actual_component
+
+actual_component ::= (ID (COL ID)? STAR?) | (LBRACKET ID (COL ID)? RBRACKET) | (LT ID (COL (ID | java_type_use))? GT)
+
+java_type_use ::=  parameterized_java_type_use | simple_java_type_use
+
+parameterized_java_type_use ::= simple_java_type_use LT java_type_use (COMMA java_type_use)* GT
+
+simple_java_type_use ::=  ID (DOT ID)*
+
+relation ::=  REL ((unnamed_role LEFT navigable_role) | (navigable_role RIGHT unnamed_role) | (navigable_role BIDIRECTIONAL navigable_role)) SCOL
+
+unnamed_role ::= ID | navigable_role
+
+navigable_role ::= ID DOT ID (STAR | QUESTION_MARK)?
diff --git a/src/main/grammar/RelAstGrammar.flex b/src/main/grammar/RelAstGrammar.flex
index aaa8d1f466a2230397651a97184bdb1a15b83c45..27f0f9403ce13616436fe42caa257f3d0f39b5ff 100644
--- a/src/main/grammar/RelAstGrammar.flex
+++ b/src/main/grammar/RelAstGrammar.flex
@@ -16,30 +16,51 @@ import com.intellij.psi.TokenType;
 %eof{  return;
 %eof}
 
-CRLF=\R
-WHITE_SPACE=[\ \n\t\f]
-FIRST_VALUE_CHARACTER=[^ \n\f\\] | "\\"{CRLF} | "\\".
-VALUE_CHARACTER=[^\n\f\\] | "\\"{CRLF} | "\\".
-END_OF_LINE_COMMENT=("#"|"!")[^\r\n]*
-SEPARATOR=[:=]
-KEY_CHARACTER=[^:=\ \n\t\f\\] | "\\ "
 
-%state WAITING_VALUE
+WhiteSpace        = [ ] | \t | \f | \n | \r | \r\n
+ID                = [a-zA-Z$_][a-zA-Z0-9$_]*
+MultiLineComment  = [/][*][^*]+[*]+([^*/][^*]*[*]+)*[/]
+DocComment        = [/][*][*][^*]*[*]+([^*/][^*]*[*]+)*[/]
+SingleLineComment = [/][/] [^\n\r]* (\n | \r | \r\n)
 
-%%
-
-<YYINITIAL> {END_OF_LINE_COMMENT}                           { yybegin(YYINITIAL); return RelAstGrammarTypes.COMMENT; }
-
-<YYINITIAL> {KEY_CHARACTER}+                                { yybegin(YYINITIAL); return RelAstGrammarTypes.KEY; }
 
-<YYINITIAL> {SEPARATOR}                                     { yybegin(WAITING_VALUE); return RelAstGrammarTypes.SEPARATOR; }
+%xstate COMMENT
+%state DECLARATION
 
-<WAITING_VALUE> {CRLF}({CRLF}|{WHITE_SPACE})+               { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; }
-
-<WAITING_VALUE> {WHITE_SPACE}+                              { yybegin(WAITING_VALUE); return TokenType.WHITE_SPACE; }
+%%
 
-<WAITING_VALUE> {FIRST_VALUE_CHARACTER}{VALUE_CHARACTER}*   { yybegin(YYINITIAL); return RelAstGrammarTypes.VALUE; }
+<DECLARATION> {
+  {WhiteSpace}          { return TokenType.WHITE_SPACE; } // maybe ignore this
+  {MultiLineComment}    { return RelAstGrammarTypes.MULTILINECOMMENT; } // maybe ignore this
+  {DocComment}          { return RelAstGrammarTypes.DOCCOMMENT; } // maybe ignore this
+  {SingleLineComment}   { return RelAstGrammarTypes.SINGLELINECOMMENT; } // maybe ignore this
+}
 
-({CRLF}|{WHITE_SPACE})+                                     { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; }
+<YYINITIAL,COMMENT> {
+  {WhiteSpace}+         { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; }
+  {MultiLineComment}    { yybegin(YYINITIAL); return RelAstGrammarTypes.MULTILINECOMMENT; }
+  {DocComment}          { yybegin(YYINITIAL); return RelAstGrammarTypes.DOCCOMMENT; }
+  {SingleLineComment}   { yybegin(YYINITIAL); return RelAstGrammarTypes.SINGLELINECOMMENT; }
+}
 
-[^]                                                         { return TokenType.BAD_CHARACTER; }
+<YYINITIAL,DECLARATION> {
+  "abstract"            { yybegin(DECLARATION); return RelAstGrammarTypes.ABSTRACT; }
+  "rel"                 { yybegin(DECLARATION); return RelAstGrammarTypes.REL; }
+  ";"                   { yybegin(COMMENT);     return RelAstGrammarTypes.SCOL; }
+  ":"                   { yybegin(DECLARATION); return RelAstGrammarTypes.COL; }
+  "::="                 { yybegin(DECLARATION); return RelAstGrammarTypes.ASSIGN; }
+  "*"                   { yybegin(DECLARATION); return RelAstGrammarTypes.STAR; }
+  "."                   { yybegin(DECLARATION); return RelAstGrammarTypes.DOT; }
+  ","                   { yybegin(DECLARATION); return RelAstGrammarTypes.COMMA; }
+  "<"                   { yybegin(DECLARATION); return RelAstGrammarTypes.LT; }
+  ">"                   { yybegin(DECLARATION); return RelAstGrammarTypes.GT; }
+  "["                   { yybegin(DECLARATION); return RelAstGrammarTypes.LBRACKET; }
+  "]"                   { yybegin(DECLARATION); return RelAstGrammarTypes.RBRACKET; }
+  "/"                   { yybegin(DECLARATION); return RelAstGrammarTypes.SLASH; }
+  "?"                   { yybegin(DECLARATION); return RelAstGrammarTypes.QUESTION_MARK; }
+  "->"                  { yybegin(DECLARATION); return RelAstGrammarTypes.RIGHT; }
+  "<-"                  { yybegin(DECLARATION); return RelAstGrammarTypes.LEFT; }
+  "<->"                 { yybegin(DECLARATION); return RelAstGrammarTypes.BIDIRECTIONAL; }
+  {ID}                  { yybegin(DECLARATION); return RelAstGrammarTypes.ID; }
+  [^]                   { return TokenType.BAD_CHARACTER; }
+}