anchor.diff:     | 'null'
      ;
   
  +arr
  +   : '[' value (',' value)* ','? ']'
  +   | '[' ']'
  +   ;
  +
  +// Lexer
  +
   SINGLE_LINE_COMMENT
  -   : '//' ~[\r\n\u2028\u2029]* -> skip
  +   : '//' .*? (NEWLINE | EOF) -> skip
      ;
   
   MULTI_LINE_COMMENT
  
positive.code:    | '\u200D'
     ;
  
  fragment DOUBLE_QUOTE_CHAR
     : '\\' ["\\/bfnrt\n]
     | ~ ["\\\u0000-\u001F]
     | UNICODE_ESC
     ;
  
  fragment SINGLE_QUOTE_CHAR
     : '\\' ['\\/bfnrt\n]
     | ~ ['\\\u0000-\u001F]
     | UNICODE_ESC
     ;
  
  fragment UNICODE_ESC
     : '\\u' HEX HEX HEX HEX
     ;
  
  fragment HEX
     : [0-9a-fA-F]
     ;
  
  
  fragment SAFECODEPOINT
     : ~ ["\\\u0000-\u001F]
     ;
  
  number
     : DECNUM
     | HEXNUM
     | INFINITY
     | NAN
     ;
  
  DECNUM
     : [+-]? INT ('.' [0-9]*)? EXP?
     | [+-]? '.' [0-9]+ EXP?
     ;
  
  HEXNUM
     : [+-]? '0' [xX] HEX+
     ;
  
  INFINITY
     : [+-]? 'Infinity'
     ;
  NAN
     : 'NaN'
     ;
  
  fragment INT
     : '0' | [1-9] [0-9]*
     ;
  
  // no leading zeros
  
  fragment EXP
     : [Ee] [+\-]? INT
     ;
  
  // \- since - means "range" inside [...]
  
  WS
     : [ \t\n\r] + -> skip
  
negative.code: grammar JSON5;
  
  json5
     : value? EOF
     ;
  
  obj
  