anchor.diff:          return false;
       }
   }
  +
  +private static boolean isBinaryOperator(Token op) {
  +    switch(op.getType()) {
  +    case AT:
  +    case COLON:
  +    case DOT:
  +    case PLUS:
  +    case MINUS:
  +    case MTIMES:
  +    case ETIMES:
  +    case MDIV:
  +    case EDIV:
  +    case MLDIV:
  +    case ELDIV:
  +    case MPOW:
  +    case EPOW:
  +    case LE:
  +    case GE:
  +    case LT:
  +    case GT:
  +    case EQ:
  +    case NE:
  +    case AND:
  +    case OR:
  +    case SHORTAND:
  +    case SHORTOR:
  +        return true;
  +    default:
  +        return false;
  +    }
  +}
  +
  +private static boolean isPrefixOperator(Token op) {
  +    switch(op.getType()) {
  +    case PLUS:
  +    case MINUS:
  +    case NOT:
  +    case AT:
  +        return true;
  +    default:
  +        return false;
  +    }
  +}
  +
  +private static boolean isPostfixOperator(Token op) {
  +    switch(op.getType()) {
  +    case MTRANSPOSE:
  +    case ARRAYTRANSPOSE:
  +        return true;
  +    default:
  +        return false;
  +    }
  +}
  +
  +private static boolean isLBracket(Token op) {
  +    switch(op.getType()) {
  +    case LPAREN:
  +    case LSQUARE:
  +    case LCURLY:
  +        return true;
  +    default:
  +        return false;
  +    }
  +}
  +
  +private static boolean isRBracket(Token op) {
  +    switch(op.getType()) {
  +    case RPAREN:
  +    case RSQUARE:
  +    case RCURLY:
  +        return true;
  +    default:
  +        return false;
  +    }
  +}
  +
  +private boolean isElementSeparator() {
  +    Token prevToken = input.LT(-1);
  +    Token nextToken = input.LT(1);
  +    return !(isBinaryOperator(prevToken) || isBinaryOperator(nextToken) || 
  +             isPrefixOperator(prevToken) || isPostfixOperator(nextToken) || 
  +             isLBracket(prevToken) || isRBracket(nextToken));
  +}
  +
  +private final java.util.Stack<Integer> bracketStack = new java.util.Stack<Integer>();
   }
   
   @lexer::header {
  
positive.code: //AC: keep the lexer and the parser together for now because that's the default Antlr layout
  
  options {
  	output = template;
  	rewrite = true;
  }
  
  @parser::header {
  
negative.code:   ;
  
  access :
       cell_access (({bracketStack.peek() == LPAREN}? FILLER?) lparen FILLER? (arg_list FILLER?)? rparen)?
    ;
  
  cell_access :
       (var_access) (({bracketStack.peek() == LPAREN}? FILLER?) lcurly FILLER? arg_list FILLER? rcurly)*
    |  {bracketStack.peek() == LPAREN}? name FILLER? AT FILLER? name
    |  name AT name
    ;
    
  var_access :
       (name) (FILLER? DOT FILLER? name)*
    ;
  
  arg_list :  
       (arg) (FILLER? COMMA FILLER? arg)*
    ;
    
  