anchor.diff:    | KW_TRUE
     | KW_FALSE
     | (ID LPAREN) => call_tail -> ^(SimpleCall call_tail)
  +  | indexed_variable
     ;
   
   call_tail
     : ID LPAREN (expr (COMMA expr)*)? RPAREN ->
       ^(Name ID) ^(LPAREN (expr+)?) ;
   
  -variable
  +indexed_variable
  +  : variable_name variable_index* -> ^(VARIABLE variable_name variable_index*)
  +  ;
  +
  +variable_index
  +  : LBRACKET expr RBRACKET -> expr
  +  | LBRACKET RBRACKET -> ARRAY_END
  +  | LBRACE expr RBRACE -> expr
  +  ;
  +
  +variable_name
     : DOLLAR^ ID
  -  | DOLLAR^ variable
  +  | DOLLAR^ variable_name
     | DOLLAR^ LBRACE! expr RBRACE!
     ;
   
  
positive.code: RPAREN: ')' ;
  LBRACE: '{' ;
  RBRACE: '}' ;
  DOLLAR: '$' ;
  COLON: ':' ;
  SEMICOLON: ';' ;
  
negative.code: 
  expr_assign
    : logical_or
    | (variable_name (PLUS_EQ | MINUS_EQ | MUL_EQ | DIV_EQ | DOT_EQ | MOD_EQ |
                      AND_EQ | OR_EQ | XOR_EQ | SHL_EQ | SHR_EQ)) =>
       variable_name op=(PLUS_EQ | MINUS_EQ | MUL_EQ | DIV_EQ | DOT_EQ | MOD_EQ |
                        AND_EQ | OR_EQ | XOR_EQ | SHL_EQ | SHR_EQ) expr_assign
        -> ^($op variable_name expr_assign)
    ;
  
  logical_or
  