anchor.diff:  // the parser can distinguish between a textual '#', comments and directives
   mode HASH_SEEN ;
   
  -SINGLE_LINE_COMMENT : '#' ~('\r' | '\n')* NEWLINE? -> type(COMMENT), popMode;
  -BLOCK_COMMENT_START : '*' -> mode(BLOCK_COMMENT) ;
  +SINGLE_LINE_COMMENT : '#' ~('\r' | '\n')* NEWLINE? -> type(COMMENT), mode(DEFAULT_MODE);
  +//Need to switch to default mode before pushing so that when the the matching end tag pops, we end back in text mode.
  +BLOCK_COMMENT_START : '*' -> mode(DEFAULT_MODE), pushMode(BLOCK_COMMENT) ;
   DOLLAR2 : '$' ->  mode(REFERENCE), type(DOLLAR) ;
  -DIRECTIVE_TEXT : . -> type(TEXT), popMode ;
  +DIRECTIVE_TEXT : . -> type(TEXT), mode(DEFAULT_MODE) ;
   
   
   //===================================
  
positive.code: SILENT : '!' ;
  FORMAL_START : '{' -> mode(REFERENCE_FORMAL);
  // "$!!" should be considered as text
  TEXT_REFERENCE : (. | '!!') -> type(TEXT), popMode ;
  
  
  //===================================
  
negative.code: 
  REFERENCE_MEMBER_MEMBER_INVOCATION : '.' -> type(MEMBER_INVOCATION), mode(REFERENCE_POSSIBLE_MEMBER) ;
  METHOD_ARGUMENTS_START : '(' -> pushMode(ARGUMENTS) ;
  REFERENCE_MEMBER_FORMAL_END : '}' -> type(FORMAL_END), mode(DEFAULT_MODE);
  DOLLAR6 : '$' -> type(DOLLAR), mode(REFERENCE) ;
  HASH5 : '#' -> mode(HASH_SEEN), type(HASH);
  TEXT5 : (. | '..')  -> type(TEXT), mode(DEFAULT_MODE) ;
  
  mode ARGUMENTS ;
  METHOD_ARGUMENTS_END : ')' -> popMode ;
  