Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 8255)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 8256)
@@ -618,4 +618,14 @@
 
         /**
+         * Determines if the objects {@code a} and {@code b} are not equal.
+         * @param a First object
+         * @param b Second object
+         * @return {@code false} if objects are equal, {@code true} otherwise
+         * @see Object#equals(Object)
+         */
+        public static boolean not_equal(Object a, Object b) {
+            return !equal(a,b);
+        }
+        /**
          * Determines whether the JOSM search with {@code searchStr} applies to the object.
          * @param env the environment
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 8255)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 8256)
@@ -10,4 +10,6 @@
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
@@ -854,7 +856,149 @@
 }
 
-Expression expression():
-{
-    List<Expression> args = new ArrayList<Expression>();
+/**
+ * General expression.
+ * Separate production rule for each level of operator precedence (recursive descent).
+ */
+Expression expression() :
+{
+    Expression e;
+}
+{
+    e=conditional_expression()
+    {
+        return e;
+    }
+}
+
+Expression conditional_expression() :
+{
+    Expression e, e1, e2;
+    String op = null;
+}
+{
+    e=or_expression()
+    (
+        <QUESTION> w()
+        e1=conditional_expression()
+        <COLON> w()
+        e2=conditional_expression()
+        {
+            e = ExpressionFactory.createFunctionExpression("cond", Arrays.asList(e, e1, e2));
+        }
+    )?
+    {
+        return e;
+    }
+}
+
+Expression or_expression() :
+{
+    Expression e, e2;
+    String op = null;
+}
+{
+    e=and_expression()
+    (
+        <PIPE> <PIPE> w()
+        e2=and_expression()
+        {
+            e = ExpressionFactory.createFunctionExpression("or", Arrays.asList(e, e2));
+        }
+    )*
+    {
+        return e;
+    }
+}
+
+Expression and_expression() :
+{
+    Expression e, e2;
+    String op = null;
+}
+{
+    e=relational_expression()
+    (
+        <AMPERSAND> <AMPERSAND> w()
+        e2=relational_expression()
+        {
+            e = ExpressionFactory.createFunctionExpression("and", Arrays.asList(e, e2));
+        }
+    )*
+    {
+        return e;
+    }
+}
+
+Expression relational_expression() :
+{
+    Expression e, e2;
+    String op = null;
+}
+{
+    e=additive_expression()
+    (
+        (
+            <GREATER_EQUAL> { op = "greater_equal"; }
+            |
+            <LESS_EQUAL> { op = "less_equal"; }
+            |
+            <GREATER> { op = "greater"; }
+            |
+            <LESS> { op = "less"; }
+            |
+            <EQUAL> ( <EQUAL> )? { op = "equal"; }
+            |
+            <EXCLAMATION> <EQUAL> { op = "not_equal"; }
+        ) w()
+        e2=additive_expression()
+        {
+            e = ExpressionFactory.createFunctionExpression(op, Arrays.asList(e, e2));
+        }
+    )?
+    {
+        return e;
+    }
+}
+
+Expression additive_expression() :
+{
+    Expression e, e2;
+    String op = null;
+}
+{
+    e=multiplicative_expression()
+    (
+        ( <PLUS> { op = "plus"; } | <MINUS> { op = "minus"; } ) w()
+        e2=multiplicative_expression()
+        {
+            e = ExpressionFactory.createFunctionExpression(op, Arrays.asList(e, e2));
+        }
+    )*
+    {
+        return e;
+    }
+}
+
+Expression multiplicative_expression() :
+{
+    Expression e, e2;
+    String op = null;
+}
+{
+    e=unary_expression()
+    (
+        ( <STAR> { op = "times"; } | <SLASH> { op = "divided_by"; } ) w()
+        e2=unary_expression()
+        {
+            e = ExpressionFactory.createFunctionExpression(op, Arrays.asList(e, e2));
+        }
+    )*
+    {
+        return e;
+    }
+}
+
+Expression unary_expression() :
+{
     Expression e;
     String op = null;
@@ -862,42 +1006,13 @@
 {
     (
-        <EXCLAMATION> { op = "not"; } w() e=primary() { args.add(e); } w()
-    |
-        <MINUS> { op = "minus"; } w() e=primary() { args.add(e); } w()
-    |
-
-        (
-            e=primary() { args.add(e); } w()
-            (
-                    ( <PLUS> { op = "plus"; } w() e=primary() { args.add(e); } w() )+
-                |
-                    ( <STAR> { op = "times"; } w() e=primary() { args.add(e); } w() )+
-                |
-                    ( <MINUS> { op = "minus"; } w() e=primary() { args.add(e); } w() )+
-                |
-                    ( <SLASH> { op = "divided_by"; } w() e=primary() { args.add(e); } w() )+
-                |
-                    <GREATER_EQUAL> { op = "greater_equal"; } w() e=primary() { args.add(e); } w()
-                |
-                    <LESS_EQUAL> { op = "less_equal"; } w() e=primary() { args.add(e); } w()
-                |
-                    <GREATER> { op = "greater"; } w() e=primary() { args.add(e); } w()
-                |
-                    <EQUAL> ( <EQUAL> )? { op = "equal"; } w() e=primary() { args.add(e); } w()
-                |
-                    <LESS> { op = "less"; } w() e=primary() { args.add(e); } w()
-                |
-                    <AMPERSAND> <AMPERSAND> { op = "and"; } w() e=primary() { args.add(e); } w()
-                |
-                    <PIPE> <PIPE> { op = "or"; } w() e=primary() { args.add(e); } w()
-                |
-                    <QUESTION> { op = "cond"; } w() e=primary() { args.add(e); } w() <COLON> w() e=primary() { args.add(e); } w()
-            )?
-        )
-    )
+        <MINUS> { op = "minus"; } w()
+    |
+        <EXCLAMATION> { op = "not"; } w()
+    )?
+    e=primary() w()
     {
         if (op == null)
-            return args.get(0);
-        return ExpressionFactory.createFunctionExpression(op, args);
+            return e;
+        return ExpressionFactory.createFunctionExpression(op, Collections.singletonList(e));
     }
 }
