]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.graph.compiler/src/org/simantics/graph/compiler/internal/parsing/Graph.g
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.graph.compiler / src / org / simantics / graph / compiler / internal / parsing / Graph.g
index 995960f94b5019322e562cf8accc10a68cd229b5..5f32abbc191c471f1303b1d2d7d3a0e4a5e4f75b 100644 (file)
-grammar Graph;\r
-\r
-options {\r
-  language = Java;\r
-  output = AST;\r
-  ASTLabelType=CommonTree;\r
-}\r
-\r
-tokens {\r
-    // lexer\r
-    INDENT;\r
-    DEDENT;\r
-    \r
-    // graph\r
-    FILE;\r
-    RESOURCE;\r
-    PROPERTY;\r
-    VARIABLE;\r
-    EMBEDDED_VALUE;\r
-    EMBEDDED_TYPE;\r
-    TEMPLATE_INSTANCE;\r
-    TEMPLATE_DEFINITION;\r
-    \r
-    BLANK;\r
-    REF;\r
-    \r
-    EQUALS;\r
-    INSTANCE_OF;\r
-    INHERITS;\r
-    SUBRELATION_OF;\r
-    HAS_DOMAIN;\r
-    HAS_RANGE;\r
-    DOMAIN_OF;\r
-    REQUIRES_VALUE_TYPE;\r
-\r
-    // data\r
-    TYPE_DEFINITIONS;\r
-    TYPE_DEFINITION;    \r
-\r
-    UNION_TYPE;    \r
-    RECORD_TYPE;\r
-    TUPLE_TYPE;\r
-    ARRAY_TYPE;\r
-    TYPE_REFERENCE;\r
-    TYPE_ANNOTATION;    \r
-    TYPE_COMPONENT;\r
-    \r
-    VALUE_DEFINITIONS;\r
-    VALUE_DEFINITION;\r
-\r
-    NO_VALUE;    \r
-    VARIANT;\r
-    ARRAY;\r
-    TUPLE;\r
-    TAGGED_VALUE;\r
-    RECORD;\r
-    MAP;\r
-    ASSIGNMENT;\r
-    TRUE;\r
-    FALSE;\r
-}\r
-\r
-@parser::header { package org.simantics.graph.compiler.internal.parsing; }\r
-@lexer::header { package org.simantics.graph.compiler.internal.parsing; \r
-\r
-import gnu.trove.list.array.*;\r
-}\r
-\r
-@lexer::members {\r
-int inParen = 0;\r
-\r
-TIntArrayList iStack = new TIntArrayList();\r
-{ iStack.add(0); }\r
-\r
-List tokens = new ArrayList();\r
-public void emit(Token token) {\r
-    state.token = token;\r
-    tokens.add(token);\r
-}\r
-public Token nextToken() {\r
-    if(tokens.isEmpty()) {\r
-        super.nextToken();\r
-        if ( tokens.isEmpty() ) {\r
-            /* When end-of-file is encountered, we \r
-               emit balancing number of DEDENT tokens.\r
-            */\r
-            if(iStack.size() <= 1)\r
-                return getEOFToken();\r
-            else {                \r
-                while(iStack.size() > 1) {\r
-                    iStack.removeAt(iStack.size()-1);\r
-                    state.type = DEDENT;\r
-                    emit();\r
-                }\r
-                iStack.clear();\r
-            }\r
-        } \r
-    }\r
-    return (Token)tokens.remove(0);\r
-}\r
-\r
-}\r
-\r
-// ------------------------------------------------------------------\r
-// LEXER\r
-// ------------------------------------------------------------------\r
-\r
-ID  : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*\r
-    ;\r
-\r
-COMMENT\r
-    :   '//' ~('\n')* {$channel=HIDDEN;}\r
-    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}\r
-    ;\r
-\r
-WS  : ( ' '\r
-      | '\t'\r
-      | '\r'\r
-      ) {$channel=HIDDEN;}\r
-    ;\r
-    \r
-LPAREN    : '(' { ++ inParen; } ;\r
-RPAREN    : ')' { -- inParen; } ;    \r
-LBRACKET  : '[' { ++ inParen; } ;\r
-RBRACKET  : ']' { -- inParen; } ;\r
-LCURLY    : '{' { ++ inParen; } ;\r
-RCURLY    : '}' { -- inParen; } ;\r
-\r
-INT_RANGE : INT '..' INT?\r
-          | '..' INT\r
-          ;\r
-RANGE     : FLOAT '..' (FLOAT | INT)?\r
-          | '..' FLOAT\r
-          | INT '..' FLOAT\r
-          ;\r
-\r
-NEWLINE\r
-@init { int spaces = 0; } \r
-    : '\n'\r
-      ( ' ' { ++spaces; } \r
-      | '//' ~('\n')* '\n' { spaces = 0; } \r
-      | '/*' ( options {greedy=false;} : . )* '*/'\r
-      | '\r'\r
-      | '\n' { spaces = 0; }\r
-      )*\r
-      { \r
-          int c = input.LA(1);\r
-          \r
-          if(inParen > 0) {\r
-              $channel = HIDDEN;\r
-          }\r
-          else if(c == EOF) {\r
-              while(iStack.size() > 1) {\r
-                  iStack.removeAt(iStack.size()-1);\r
-                  state.type = DEDENT;\r
-                  emit();\r
-              }\r
-              $channel = HIDDEN;\r
-              iStack.clear();\r
-          }\r
-          else {\r
-              int stackTop = iStack.get(iStack.size()-1);\r
-              if(spaces > stackTop) {\r
-                  iStack.add(spaces);\r
-                  $type = INDENT;\r
-              }\r
-              else if(spaces < stackTop) {\r
-                  while(spaces < iStack.get(iStack.size()-1)) {\r
-                      iStack.removeAt(iStack.size()-1);\r
-                      state.type = DEDENT;\r
-                      emit();\r
-                  }\r
-                  state.type = NEWLINE;\r
-                  emit();\r
-                  // TODO check that spaces == iStack.get(iStack.size()-1)\r
-              }\r
-          }\r
-      }\r
-    ;\r
-  \r
-INDENT: { false }?=> 'INDENT' ;\r
-DEDENT: { false }?=> 'DEDENT' ;  \r
-    \r
-INT : '-'? '0'..'9'+\r
-    ;\r
-\r
-FLOAT\r
-    : '-'? \r
-    ( ('0'..'9')+ '.' ('0'..'9')* EXPONENT?\r
-    | ('0'..'9')+ EXPONENT\r
-    )\r
-    ;\r
-  \r
-STRING\r
-    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'\r
-    |  '"""' ( ~('"') | '"' ~('"') | '""' ~('"') )* '"""'\r
-    ;\r
-\r
-URI\r
-    :  '<http:' ( ~('>') )* '>'\r
-    ;\r
-\r
-fragment\r
-EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;\r
-\r
-fragment\r
-HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;\r
-\r
-fragment\r
-ESC_SEQ\r
-    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')\r
-    |   UNICODE_ESC\r
-    ;\r
-\r
-fragment\r
-UNICODE_ESC\r
-    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT\r
-    ;\r
-\r
-// ------------------------------------------------------------------\r
-// STATEMENTS    \r
-// ------------------------------------------------------------------\r
-\r
-file : NEWLINE? resourceDefinitions? EOF -> ^(FILE resourceDefinitions?) ;\r
-\r
-resourceDefinitions \r
-     : resourceDefinition (NEWLINE! resourceDefinition)*\r
-     ;\r
-             \r
-resourceDefinition \r
-    : resource\r
-      localProperty*\r
-      (INDENT property (NEWLINE property)* DEDENT)?\r
-    -> ^(RESOURCE resource localProperty* property*) \r
-    | template -> ^(RESOURCE ^(BLANK template) template)\r
-    ;\r
-    \r
-localProperty\r
-    : relation resource\r
-    -> ^(PROPERTY relation ^(RESOURCE resource))\r
-    ;    \r
-\r
-property\r
-    : relation\r
-      ( resourceDefinition -> ^(PROPERTY relation resourceDefinition)\r
-      | INDENT resourceDefinitions DEDENT -> ^(PROPERTY relation resourceDefinitions)\r
-      )\r
-    | template\r
-    ;\r
-    \r
-template\r
-    : '@' \r
-    ( {input.LT(1).getText().equals("template")}?=>\r
-      ID resource+ \r
-      INDENT resourceDefinitions DEDENT\r
-      -> ^(TEMPLATE_DEFINITION resource+ resourceDefinitions)\r
-    | resource+ \r
-      (INDENT resourceDefinitions DEDENT)?\r
-      -> ^(TEMPLATE_INSTANCE resource+ resourceDefinitions?)\r
-    )\r
-    ;    \r
-\r
-// ------------------------------------------------------------------\r
-// RESOURCES\r
-// ------------------------------------------------------------------\r
-\r
-relation \r
-    : ( ID -> ID) \r
-      ('.' ID -> ^(REF $relation ID))*\r
-    | URI\r
-    | '<T' -> INHERITS\r
-    | '<R' -> SUBRELATION_OF\r
-    | '<--' -> HAS_DOMAIN\r
-    | '-->' -> HAS_RANGE\r
-    | '==>' -> REQUIRES_VALUE_TYPE\r
-    | '>--' -> DOMAIN_OF    \r
-    | ':' -> INSTANCE_OF\r
-    | '=' -> EQUALS\r
-    | '%' ID -> ^(VARIABLE ID)\r
-    ;\r
-\r
-resource\r
-    : ( {input.LT(1).getText().equals("_")}?=> ID -> ^(BLANK ID) \r
-      | ID -> ID) \r
-      ('.' (ID -> ^(REF $resource ID)\r
-           |STRING -> ^(REF $resource STRING)\r
-           )\r
-      )*\r
-    | URI\r
-    | simpleValue -> ^(EMBEDDED_VALUE simpleValue)\r
-    | '$' basicType -> ^(EMBEDDED_TYPE basicType)\r
-    | '%' ID -> ^(VARIABLE ID)\r
-    ;\r
-\r
-// ------------------------------------------------------------------\r
-// TYPE DEFINITIONS    \r
-// ------------------------------------------------------------------\r
\r
-/*typeDefinitions : typeDefinition* -> ^(TYPE_DEFINITIONS typeDefinition*);\r
-\r
-typeDefinition \r
-    : 'type' ID '=' type -> ^(TYPE_DEFINITION ID type)\r
-    ;\r
-*/\r
-  \r
-type \r
-    : arrayType\r
-    | unionType\r
-    ;      \r
-\r
-unionType\r
-    :\r
-     ('|' unionComponent)+\r
-    -> ^(UNION_TYPE unionComponent+)\r
-    ;\r
-\r
-unionComponent : ID ((arrayType) => arrayType)? -> ^(TYPE_COMPONENT ID arrayType?) ;\r
-\r
-arrayType \r
-    : (basicType -> basicType)\r
-      (LBRACKET arrayLength? RBRACKET -> ^(ARRAY_TYPE $arrayType arrayLength?))* ;\r
-\r
-arrayLength \r
-    : INT\r
-    | INT_RANGE\r
-    ;\r
-\r
-basicType \r
-    : tupleType\r
-    | recordType\r
-    | typeReference\r
-    ;\r
-    \r
-tupleType \r
-    : LPAREN (type (',' type)*)? RPAREN \r
-    -> ^(TUPLE_TYPE type*) \r
-    ;\r
-\r
-recordType \r
-    : LCURLY (component (',' component)*)? RCURLY \r
-    -> ^(RECORD_TYPE component*)\r
-    ;\r
-\r
-component \r
-    : ID ':' type \r
-    -> ^(TYPE_COMPONENT ID type) \r
-    ;\r
-\r
-typeReference \r
-    : ID ((LPAREN)=> LPAREN parameter (',' parameter)* RPAREN)? \r
-    -> ^(TYPE_REFERENCE ID parameter*)\r
-    ;\r
-\r
-parameter \r
-    : ID '=' parameterValue -> ^(TYPE_ANNOTATION ID parameterValue)\r
-    | type \r
-    ;\r
-\r
-parameterValue \r
-    : string\r
-    | boolean_\r
-    | number\r
-    | rangePar -> ^(RANGE rangePar)    \r
-    ;\r
-    \r
-rangePar : (LBRACKET | LPAREN) range (RBRACKET | RPAREN) ;    \r
-    \r
-range\r
-    : number\r
-    | RANGE\r
-    | INT_RANGE    \r
-    ;    \r
-    \r
-number\r
-    : INT\r
-    | FLOAT\r
-    ;\r
-\r
-string\r
-    : STRING\r
-    ;\r
-    \r
-boolean_\r
-    : 'true' -> TRUE\r
-    | 'false' -> FALSE\r
-    ;\r
-\r
-// ------------------------------------------------------------------\r
-// VALUE DEFINITIONS    \r
-// ------------------------------------------------------------------\r
-\r
-valueDefinitions : valueDefinition* -> ^(VALUE_DEFINITIONS valueDefinition*);\r
-\r
-valueDefinition \r
-    : ID ':' type '=' value\r
-    -> ^(VALUE_DEFINITION ID type value) \r
-    ;\r
-\r
-value \r
-    : (basicValue -> basicValue)\r
-      (':' type -> ^(VARIANT type $value))* \r
-    ;\r
-\r
-basicValue \r
-    : simpleValue\r
-    | map\r
-    | {input.LT(1).getText().equals("null")}? ID -> NO_VALUE\r
-    | taggedValue    \r
-    ;\r
-    \r
-simpleValue\r
-    : string\r
-    | number\r
-    | boolean_\r
-    | array\r
-    | tuple\r
-    | record\r
-    ;   \r
-\r
-array \r
-    : LBRACKET (value (',' value)*)? RBRACKET\r
-    -> ^(ARRAY value*) \r
-    ;\r
-\r
-tuple \r
-    : LPAREN (value (',' value)*)? RPAREN\r
-    -> ^(TUPLE value*) \r
-    ;\r
-\r
-taggedValue \r
-    : ID simpleValue?\r
-    -> ^(TAGGED_VALUE ID simpleValue?) \r
-    ;\r
-\r
-record \r
-    : LCURLY (recordAssignment (',' recordAssignment)*)? RCURLY\r
-    -> ^(RECORD recordAssignment*) \r
-    ;\r
-\r
-recordAssignment \r
-    : ID '=' value\r
-    -> ^(ASSIGNMENT ID value)\r
-    ;\r
-\r
-map : {input.LT(1).getText().equals("map")}?=> ID LCURLY (mapAssignment (',' mapAssignment)*)? RCURLY\r
-    -> ^(MAP mapAssignment*) \r
-    ;\r
-\r
-mapAssignment \r
-    : value '=' value\r
-    -> ^(ASSIGNMENT value*) \r
-    ;\r
-        \r
+grammar Graph;
+
+options {
+  language = Java;
+  output = AST;
+  ASTLabelType=CommonTree;
+}
+
+tokens {
+    // lexer
+    INDENT;
+    DEDENT;
+    
+    // graph
+    FILE;
+    RESOURCE;
+    PROPERTY;
+    VARIABLE;
+    EMBEDDED_VALUE;
+    EMBEDDED_TYPE;
+    TEMPLATE_INSTANCE;
+    TEMPLATE_DEFINITION;
+    
+    BLANK;
+    REF;
+    
+    EQUALS;
+    INSTANCE_OF;
+    INHERITS;
+    SUBRELATION_OF;
+    HAS_DOMAIN;
+    HAS_RANGE;
+    DOMAIN_OF;
+    REQUIRES_VALUE_TYPE;
+
+    // data
+    TYPE_DEFINITIONS;
+    TYPE_DEFINITION;    
+
+    UNION_TYPE;    
+    RECORD_TYPE;
+    TUPLE_TYPE;
+    ARRAY_TYPE;
+    TYPE_REFERENCE;
+    TYPE_ANNOTATION;    
+    TYPE_COMPONENT;
+    
+    VALUE_DEFINITIONS;
+    VALUE_DEFINITION;
+
+    NO_VALUE;    
+    VARIANT;
+    ARRAY;
+    TUPLE;
+    TAGGED_VALUE;
+    RECORD;
+    MAP;
+    ASSIGNMENT;
+    TRUE;
+    FALSE;
+}
+
+@parser::header { package org.simantics.graph.compiler.internal.parsing; }
+@lexer::header { package org.simantics.graph.compiler.internal.parsing; 
+
+import gnu.trove.list.array.*;
+}
+
+@lexer::members {
+int inParen = 0;
+
+TIntArrayList iStack = new TIntArrayList();
+{ iStack.add(0); }
+
+List tokens = new ArrayList();
+public void emit(Token token) {
+    state.token = token;
+    tokens.add(token);
+}
+public Token nextToken() {
+    if(tokens.isEmpty()) {
+        super.nextToken();
+        if ( tokens.isEmpty() ) {
+            /* When end-of-file is encountered, we 
+               emit balancing number of DEDENT tokens.
+            */
+            if(iStack.size() <= 1)
+                return getEOFToken();
+            else {                
+                while(iStack.size() > 1) {
+                    iStack.removeAt(iStack.size()-1);
+                    state.type = DEDENT;
+                    emit();
+                }
+                iStack.clear();
+            }
+        } 
+    }
+    return (Token)tokens.remove(0);
+}
+
+}
+
+// ------------------------------------------------------------------
+// LEXER
+// ------------------------------------------------------------------
+
+ID  : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
+    ;
+
+COMMENT
+    :   '//' ~('\n')* {$channel=HIDDEN;}
+    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
+    ;
+
+WS  : ( ' '
+      | '\t'
+      | '\r'
+      ) {$channel=HIDDEN;}
+    ;
+    
+LPAREN    : '(' { ++ inParen; } ;
+RPAREN    : ')' { -- inParen; } ;    
+LBRACKET  : '[' { ++ inParen; } ;
+RBRACKET  : ']' { -- inParen; } ;
+LCURLY    : '{' { ++ inParen; } ;
+RCURLY    : '}' { -- inParen; } ;
+
+INT_RANGE : INT '..' INT?
+          | '..' INT
+          ;
+RANGE     : FLOAT '..' (FLOAT | INT)?
+          | '..' FLOAT
+          | INT '..' FLOAT
+          ;
+
+NEWLINE
+@init { int spaces = 0; } 
+    : '\n'
+      ( ' ' { ++spaces; } 
+      | '//' ~('\n')* '\n' { spaces = 0; } 
+      | '/*' ( options {greedy=false;} : . )* '*/'
+      | '\r'
+      | '\n' { spaces = 0; }
+      )*
+      { 
+          int c = input.LA(1);
+          
+          if(inParen > 0) {
+              $channel = HIDDEN;
+          }
+          else if(c == EOF) {
+              while(iStack.size() > 1) {
+                  iStack.removeAt(iStack.size()-1);
+                  state.type = DEDENT;
+                  emit();
+              }
+              $channel = HIDDEN;
+              iStack.clear();
+          }
+          else {
+              int stackTop = iStack.get(iStack.size()-1);
+              if(spaces > stackTop) {
+                  iStack.add(spaces);
+                  $type = INDENT;
+              }
+              else if(spaces < stackTop) {
+                  while(spaces < iStack.get(iStack.size()-1)) {
+                      iStack.removeAt(iStack.size()-1);
+                      state.type = DEDENT;
+                      emit();
+                  }
+                  state.type = NEWLINE;
+                  emit();
+                  // TODO check that spaces == iStack.get(iStack.size()-1)
+              }
+          }
+      }
+    ;
+  
+INDENT: { false }?=> 'INDENT' ;
+DEDENT: { false }?=> 'DEDENT' ;  
+    
+INT : '-'? '0'..'9'+
+    ;
+
+FLOAT
+    : '-'? 
+    ( ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
+    | ('0'..'9')+ EXPONENT
+    )
+    ;
+  
+STRING
+    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
+    |  '"""' ( ~('"') | '"' ~('"') | '""' ~('"') )* '"""'
+    ;
+
+URI
+    :  '<http:' ( ~('>') )* '>'
+    ;
+
+fragment
+EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
+
+fragment
+HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
+
+fragment
+ESC_SEQ
+    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
+    |   UNICODE_ESC
+    ;
+
+fragment
+UNICODE_ESC
+    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
+    ;
+
+// ------------------------------------------------------------------
+// STATEMENTS    
+// ------------------------------------------------------------------
+
+file : NEWLINE? resourceDefinitions? EOF -> ^(FILE resourceDefinitions?) ;
+
+resourceDefinitions 
+     : resourceDefinition (NEWLINE! resourceDefinition)*
+     ;
+             
+resourceDefinition 
+    : resource
+      localProperty*
+      (INDENT property (NEWLINE property)* DEDENT)?
+    -> ^(RESOURCE resource localProperty* property*) 
+    | template -> ^(RESOURCE ^(BLANK template) template)
+    ;
+    
+localProperty
+    : relation resource
+    -> ^(PROPERTY relation ^(RESOURCE resource))
+    ;    
+
+property
+    : relation
+      ( resourceDefinition -> ^(PROPERTY relation resourceDefinition)
+      | INDENT resourceDefinitions DEDENT -> ^(PROPERTY relation resourceDefinitions)
+      )
+    | template
+    ;
+    
+template
+    : '@' 
+    ( {input.LT(1).getText().equals("template")}?=>
+      ID resource+ 
+      INDENT resourceDefinitions DEDENT
+      -> ^(TEMPLATE_DEFINITION resource+ resourceDefinitions)
+    | resource+ 
+      (INDENT resourceDefinitions DEDENT)?
+      -> ^(TEMPLATE_INSTANCE resource+ resourceDefinitions?)
+    )
+    ;    
+
+// ------------------------------------------------------------------
+// RESOURCES
+// ------------------------------------------------------------------
+
+relation 
+    : ( ID -> ID) 
+      ('.' ID -> ^(REF $relation ID))*
+    | URI
+    | '<T' -> INHERITS
+    | '<R' -> SUBRELATION_OF
+    | '<--' -> HAS_DOMAIN
+    | '-->' -> HAS_RANGE
+    | '==>' -> REQUIRES_VALUE_TYPE
+    | '>--' -> DOMAIN_OF    
+    | ':' -> INSTANCE_OF
+    | '=' -> EQUALS
+    | '%' ID -> ^(VARIABLE ID)
+    ;
+
+resource
+    : ( {input.LT(1).getText().equals("_")}?=> ID -> ^(BLANK ID) 
+      | ID -> ID) 
+      ('.' (ID -> ^(REF $resource ID)
+           |STRING -> ^(REF $resource STRING)
+           )
+      )*
+    | URI
+    | simpleValue -> ^(EMBEDDED_VALUE simpleValue)
+    | '$' basicType -> ^(EMBEDDED_TYPE basicType)
+    | '%' ID -> ^(VARIABLE ID)
+    ;
+
+// ------------------------------------------------------------------
+// TYPE DEFINITIONS    
+// ------------------------------------------------------------------
+/*typeDefinitions : typeDefinition* -> ^(TYPE_DEFINITIONS typeDefinition*);
+
+typeDefinition 
+    : 'type' ID '=' type -> ^(TYPE_DEFINITION ID type)
+    ;
+*/
+  
+type 
+    : arrayType
+    | unionType
+    ;      
+
+unionType
+    :
+     ('|' unionComponent)+
+    -> ^(UNION_TYPE unionComponent+)
+    ;
+
+unionComponent : ID ((arrayType) => arrayType)? -> ^(TYPE_COMPONENT ID arrayType?) ;
+
+arrayType 
+    : (basicType -> basicType)
+      (LBRACKET arrayLength? RBRACKET -> ^(ARRAY_TYPE $arrayType arrayLength?))* ;
+
+arrayLength 
+    : INT
+    | INT_RANGE
+    ;
+
+basicType 
+    : tupleType
+    | recordType
+    | typeReference
+    ;
+    
+tupleType 
+    : LPAREN (type (',' type)*)? RPAREN 
+    -> ^(TUPLE_TYPE type*) 
+    ;
+
+recordType 
+    : LCURLY (component (',' component)*)? RCURLY 
+    -> ^(RECORD_TYPE component*)
+    ;
+
+component 
+    : ID ':' type 
+    -> ^(TYPE_COMPONENT ID type) 
+    ;
+
+typeReference 
+    : ID ((LPAREN)=> LPAREN parameter (',' parameter)* RPAREN)? 
+    -> ^(TYPE_REFERENCE ID parameter*)
+    ;
+
+parameter 
+    : ID '=' parameterValue -> ^(TYPE_ANNOTATION ID parameterValue)
+    | type 
+    ;
+
+parameterValue 
+    : string
+    | boolean_
+    | number
+    | rangePar -> ^(RANGE rangePar)    
+    ;
+    
+rangePar : (LBRACKET | LPAREN) range (RBRACKET | RPAREN) ;    
+    
+range
+    : number
+    | RANGE
+    | INT_RANGE    
+    ;    
+    
+number
+    : INT
+    | FLOAT
+    ;
+
+string
+    : STRING
+    ;
+    
+boolean_
+    : 'true' -> TRUE
+    | 'false' -> FALSE
+    ;
+
+// ------------------------------------------------------------------
+// VALUE DEFINITIONS    
+// ------------------------------------------------------------------
+
+valueDefinitions : valueDefinition* -> ^(VALUE_DEFINITIONS valueDefinition*);
+
+valueDefinition 
+    : ID ':' type '=' value
+    -> ^(VALUE_DEFINITION ID type value) 
+    ;
+
+value 
+    : (basicValue -> basicValue)
+      (':' type -> ^(VARIANT type $value))* 
+    ;
+
+basicValue 
+    : simpleValue
+    | map
+    | {input.LT(1).getText().equals("null")}? ID -> NO_VALUE
+    | taggedValue    
+    ;
+    
+simpleValue
+    : string
+    | number
+    | boolean_
+    | array
+    | tuple
+    | record
+    ;   
+
+array 
+    : LBRACKET (value (',' value)*)? RBRACKET
+    -> ^(ARRAY value*) 
+    ;
+
+tuple 
+    : LPAREN (value (',' value)*)? RPAREN
+    -> ^(TUPLE value*) 
+    ;
+
+taggedValue 
+    : ID simpleValue?
+    -> ^(TAGGED_VALUE ID simpleValue?) 
+    ;
+
+record 
+    : LCURLY (recordAssignment (',' recordAssignment)*)? RCURLY
+    -> ^(RECORD recordAssignment*) 
+    ;
+
+recordAssignment 
+    : ID '=' value
+    -> ^(ASSIGNMENT ID value)
+    ;
+
+map : {input.LT(1).getText().equals("map")}?=> ID LCURLY (mapAssignment (',' mapAssignment)*)? RCURLY
+    -> ^(MAP mapAssignment*) 
+    ;
+
+mapAssignment 
+    : value '=' value
+    -> ^(ASSIGNMENT value*) 
+    ;
+