Make equality, comparison and 'in' operators not associative.

I'm not using a --incompatible-change flag because it's not available in the
parser. We could pass it, but I think this is trivial to fix and unlikely to
happen in real code (if it does, there was most likely a bug).

RELNOTES[INC]:
  Operators for equality, comparison, 'in' and 'not in' are no longer associative,
  e.g.  x < y < z  is now a syntax error. Before, it was parsed as:  (x < y) < z.

PiperOrigin-RevId: 159422042
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
index ed23432..46de9a9 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -950,6 +950,7 @@
     Expression expr = parseNonTupleExpression(prec + 1);
     // The loop is not strictly needed, but it prevents risks of stack overflow. Depth is
     // limited to number of different precedence levels (operatorPrecedence.size()).
+    Operator lastOp = null;
     for (;;) {
 
       if (token.kind == TokenKind.NOT) {
@@ -967,10 +968,21 @@
       if (!operatorPrecedence.get(prec).contains(operator)) {
         return expr;
       }
+
+      // Operator '==' and other operators of the same precedence (e.g. '<', 'in')
+      // are not associative.
+      if (lastOp != null && operatorPrecedence.get(prec).contains(Operator.EQUALS_EQUALS)) {
+        reportError(
+            lexer.createLocation(token.left, token.right),
+            String.format("Operator '%s' is not associative with operator '%s'. Use parens.",
+                lastOp, operator));
+      }
+
       nextToken();
       Expression secondary = parseNonTupleExpression(prec + 1);
       expr = optimizeBinOpExpression(operator, expr, secondary);
       setLocation(expr, start, secondary);
+      lastOp = operator;
     }
   }