anchor.diff:      ;
   
   fragment
  -LCLETTER:   'a'..'z'
  -    ;
  -
  -fragment
  -UCLETTER:   'A'..'Z'
  -    ;
  -
  -// UPPERCASE for format name
  -
  +LCLETTER
  +    :   'a'..'z'
  +    ;
  +
  +fragment
  +UCLETTER
  +    :   'A'..'Z'
  +    ;
  +
  +// format name (this identifies the file extension)
   FORMATNAME
  -    :   UCLETTER (UCLETTER | DIGITS)*
  +    :   (UCLETTER | DIGITS | '_')+
       ;
   
   // lower_case_with_underscores for variable names (e.g. fields)
  
positive.code:     ;
  
  typeblock
      :   TYPE blockbegin typedefine+ blockend
      ;
  
  parameterblock
      :   PARAMETER blockbegin fielddefine+ blockend
      ;
  
  classblock
      :   longdoc CLASS TYPENAME blockbegin declarations class_fielddefines blockend
      ;
  
  blockbegin
  
negative.code: 
  typedefine
      :   longdoc TYPENAME shortdoc // basic type
          -> ^(TYPE ^(DOC longdoc shortdoc) TYPENAME)
      |   longdoc alias=TYPENAME '=' orig=TYPENAME shortdoc // alias
          -> ^(TYPE ^(DOC longdoc shortdoc) $alias $orig)
      ;
  
  fielddefine
      :   longdoc TYPENAME VARIABLENAME fieldparameters? shortdoc
          -> ^(FIELD ^(DOC longdoc shortdoc) TYPENAME VARIABLENAME fieldparameters?)
      ;
  
  class_fielddefines_ifelifelse_fragment
      :
          IF ifexp=expression blockbegin ifdefines=class_fielddefines blockend
          (ELIF elifexp=expression blockbegin elifdefines=class_fielddefines blockend)*
          (ELSE blockbegin elsedefines=class_fielddefines blockend)?
          -> ^(IF $ifexp $ifdefines ^(ELIF $elifexp $elifdefines) ^(ELSE $elsedefines))
      ;
  
  class_fielddefines
  