anchor.diff:             ( escaped=ESC {lBuf.append(getText());} |
                normal=~('\''|'\\'|'\n'|'\r')     {lBuf.appendCodePoint(normal);} )*
              ( SingleQuote {setText(lBuf.toString());} 
  -           | ( '\n' | '\r')  {wibble("Found newline in string "+lBuf.toString(), input, tok, false);})
  +           | ( '\n' | '\r')  {error("Found newline in string "+lBuf.toString(), input, tok, false);})
              
       ;
   
  
positive.code: 
  comparator 
    : Is (Equals | NEquals | GTEquals | LTEquals | GT | LT) expression
    | Is Assign { wibble("Assignment found where comparator expected", input, $Is); } expression 
    | Is (Or | And | Excl | Add | Subtract | Multiply | Divide | Modulus) { wibble("Comparator expected", input, $Is); } expression 
    ;
  
  // SWITCH requires constants as case values
  
negative.code: 
  // Without this a semicolon after end causes really unhelpful error messages
  End      : 'end'
           | 'end' {error("Unexpected semicolon", input, null, true)}? SColon
           ;
  
  In       : 'in';
  