anchor.diff:   : '\\Q' .* '\\E' {setText($text.substring(2, $text.length() - 2));}
    ;
   
  -PosixCharacterClass
  - : Escape 'p{' ( 'Lower'  {$type=PosixCharacterClassLower;}
  -               | 'Upper'  {$type=PosixCharacterClassUpper;}
  -               | 'ASCII'  {$type=PosixCharacterClassASCII;}
  -               | 'Alpha'  {$type=PosixCharacterClassAlpha;}
  -               | 'Digit'  {$type=PosixCharacterClassDigit;}
  -               | 'Alnum'  {$type=PosixCharacterClassAlnum;}
  -               | 'Punct'  {$type=PosixCharacterClassPunct;}
  -               | 'Graph'  {$type=PosixCharacterClassGraph;}
  -               | 'Print'  {$type=PosixCharacterClassPrint;}
  -               | 'Blank'  {$type=PosixCharacterClassBlank;}
  -               | 'Cntrl'  {$type=PosixCharacterClassCntrl;}
  -               | 'XDigit' {$type=PosixCharacterClassXDigit;}
  -               | 'Space'  {$type=PosixCharacterClassSpace;}
  -               )
  -          '}'
  - ;
  -
  -ShorthandCharacterClass
  - : Escape ( 'd' {$type=ShorthandCharacterClassDigit;}
  -          | 'D' {$type=ShorthandCharacterClassNonDigit;}
  -          | 's' {$type=ShorthandCharacterClassSpace;}
  -          | 'S' {$type=ShorthandCharacterClassNonSpace;}
  -          | 'w' {$type=ShorthandCharacterClassWord;}
  -          | 'W' {$type=ShorthandCharacterClassNonWord;}
  -          )
  - ;
  -
  -BoundaryMatch
  - : Escape ( 'b' {$type=WordBoundary;}
  -          | 'B' {$type=NonWordBoundary;}
  -          | 'A' {$type=StartInput;}
  -          | 'Z' {$type=EndInputBeforeFinalTerminator;}
  -          | 'z' {$type=EndInput;}
  -          | 'G' {$type=EndPreviousMatch;}
  -          )
  - ;
  +PosixCharacterClassLower  : 'p{Lower}';
  +PosixCharacterClassUpper  : 'p{Upper}';
  +PosixCharacterClassASCII  : 'p{ASCII}';
  +PosixCharacterClassAlpha  : 'p{Alpha}';
  +PosixCharacterClassDigit  : 'p{Digit}';
  +PosixCharacterClassAlnum  : 'p{Alnum}';
  +PosixCharacterClassPunct  : 'p{Punct}';
  +PosixCharacterClassGraph  : 'p{Graph}';
  +PosixCharacterClassPrint  : 'p{Print}';
  +PosixCharacterClassBlank  : 'p{Blank}';
  +PosixCharacterClassCntrl  : 'p{Cntrl}';
  +PosixCharacterClassXDigit : 'p{XDigit}';
  +PosixCharacterClassSpace  : 'p{Space}';
  +
  +ShorthandCharacterClassDigit    : '\\d';
  +ShorthandCharacterClassNonDigit : '\\D';
  +ShorthandCharacterClassSpace    : '\\s';
  +ShorthandCharacterClassNonSpace : '\\S';
  +ShorthandCharacterClassWord     : '\\w';
  +ShorthandCharacterClassNonWord  : '\\W';
  +
  +WordBoundary                  : '\\b';
  +NonWordBoundary               : '\\B';
  +StartInput                    : '\\A';
  +EndInputBeforeFinalTerminator : '\\Z';
  +EndInput                      : '\\z';
  +EndPreviousMatch              : '\\G';
   
   OctalChar
    : Escape '0' ('0'..'3' OctDigit OctDigit | OctDigit? OctDigit)
  
positive.code:   package pcreparser;
  }
  
  // parser rules
  parse
   : regexAlts EOF -> ^(REGEX regexAlts)
  
negative.code: fragment NonAlphaNum : ~('a'..'z' | 'A'..'Z' | '0'..'9');
  fragment OctDigit    : '0'..'7';
  fragment HexDigit    : ('0'..'9' | 'a'..'f' | 'A'..'F');
  