anchor.diff:  //
   // Whitespace, line escape and comments
   //
  -WS  :  ([ \t\u000C]+ | LineEscape+)     -> skip
  -    ;
  -
  +WS  : ([ \t\u000C]+ | LineEscape+) -> skip
  +    ;
   
   // Inside (...) and [...] but not {...}, ignore newlines.
   NL  : LineTerminator   { this.ignoreTokenInsideParens(); }
  
positive.code:     ;
  
  fragment
  JavaLetterInGString
      :   [a-zA-Z_] // these are the "java letters" below 0x7F, except for $
      |   // covers all characters above 0x7F which are not a surrogate
          ~[\u0000-\u007F\uD800-\uDBFF]
          {Character.isJavaIdentifierStart(_input.LA(-1))}?
      |   // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
          [\uD800-\uDBFF] [\uDC00-\uDFFF]
          {Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
      ;
  
  fragment
  JavaLetterOrDigitInGString
      :   [a-zA-Z0-9_] // these are the "java letters or digits" below 0x7F, except for $
      |   // covers all characters above 0x7F which are not a surrogate
          ~[\u0000-\u007F\uD800-\uDBFF]
          {Character.isJavaIdentifierPart(_input.LA(-1))}?
      |   // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
          [\uD800-\uDBFF] [\uDC00-\uDFFF]
          {Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
      ;
  
  
  fragment
  JavaLetter
      :   [a-zA-Z$_] // these are the "java letters" below 0x7F
      |   // covers all characters above 0x7F which are not a surrogate
          ~[\u0000-\u007F\uD800-\uDBFF]
          {Character.isJavaIdentifierStart(_input.LA(-1))}?
      |   // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
          [\uD800-\uDBFF] [\uDC00-\uDFFF]
          {Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}?
      ;
  
  fragment
  
negative.code: // Unexpected characters will be handled by groovy parser later.
  UNEXPECTED_CHAR
      :   .
      ;