anchor.diff:  
   constant : INTEGER_CONSTANT | FLOAT_CONSTANT | BOOLEAN_CONSTANT | STRING_CONSTANT | NULL_CONSTANT;
   
  -IDENTIFIER:LETTER(LETTER|'_'|'0'..'9')* ;
  -
  -INTEGER_CONSTANT  : DIGIT+;
  -BOOLEAN_CONSTANT  : 'true' | 'false' ;
  -STRING_CONSTANT   :'"' (~'"')* '"';
  -
  -FLOAT_CONSTANT    : (DIGIT)+ '.' (DIGIT)* FLOATEXP?
  -                  | (DIGIT)+ FLOATEXP
  -                  ;
  -
  -NULL_CONSTANT     : 'null';
  -
  -
  -PLUS : '+';
  -MINUS : '-';
  -
  -fragment DIGIT    : '0'..'9' ;
  -fragment FLOATEXP : ('e'|'E')(PLUS|MINUS)?('0'..'9')+;
  -fragment LETTER   : 'A'..'Z' | 'a'..'z';
   
   clauseExpression      : '[' clause ']' ;
   
  
positive.code:                | CROSS  joinParam  #joinDefinitionCross ;
  
  joinParam : varID (',' varID )* ( 'on' dimensionExpression (',' dimensionExpression )* )? ;
  
  joinBody : joinClause (',' joinClause)* ;
  
  
negative.code: OUTER : 'outer' ;
  CROSS : 'cross' ;
  
  IDENTIFIER:LETTER(LETTER|'_'|DIGIT)* ;
  
  INTEGER_CONSTANT  : DIGIT+;
  BOOLEAN_CONSTANT  : 'true' | 'false' ;
  STRING_CONSTANT   :'"' (~'"')* '"';
  
  FLOAT_CONSTANT    : (DIGIT)+ '.' (DIGIT)* FLOATEXP?
                    | (DIGIT)+ FLOATEXP
                    ;
  
  NULL_CONSTANT     : 'null';
  
  PLUS : '+';
  MINUS : '-';
  
  fragment DIGIT    : '0'..'9' ;
  fragment FLOATEXP : ('e'|'E')(PLUS|MINUS)?('0'..'9')+;
  fragment LETTER   : 'A'..'Z' | 'a'..'z';
  
  WS : [ \n\r\t\u000C] -> skip ;
  COMMENT : '/*' .*? '*/' -> skip;
  
  