Don't evaluate short-circuited preprocessor expressions

Resubmit with clang build issue fixed. The result of a short-circuited
operation is now either 0 or 1.

ESSL 3.00 spec section 3.4 mentions that the second operand in a logical
&& or || preprocessor operation is evaluated only if the first operand
doesn't short-circuit the expression. The non-evaluated part of a
preprocessor expression may also have undefined identifiers.

Make the expression parser follow the spec by ignoring errors that are
generated inside short-circuited expressions. This includes undefined
identifiers and divide by zero.

BUG=angleproject:347
TEST=dEQP-GLES3.functional.shaders.preprocessor.undefined_identifiers.*
     angle_unittests

Change-Id: I4163f96ec46d40ac859ffb39d91b89490041e44d
Reviewed-on: https://chromium-review.googlesource.com/297252
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/preprocessor/ExpressionParser.cpp b/src/compiler/preprocessor/ExpressionParser.cpp
index 683195c..27dc626 100644
--- a/src/compiler/preprocessor/ExpressionParser.cpp
+++ b/src/compiler/preprocessor/ExpressionParser.cpp
@@ -122,6 +122,13 @@
     pp::Lexer* lexer;
     pp::Token* token;
     int* result;
+
+    void startIgnoreErrors() { ++ignoreErrors; }
+    void endIgnoreErrors() { --ignoreErrors; }
+
+    bool isIgnoringErrors() { return ignoreErrors > 0; }
+
+    int ignoreErrors;
 };
 }  // namespace
 
@@ -162,15 +169,16 @@
   enum yytokentype
   {
     TOK_CONST_INT = 258,
-    TOK_OP_OR = 259,
-    TOK_OP_AND = 260,
-    TOK_OP_EQ = 261,
-    TOK_OP_NE = 262,
-    TOK_OP_LE = 263,
-    TOK_OP_GE = 264,
-    TOK_OP_LEFT = 265,
-    TOK_OP_RIGHT = 266,
-    TOK_UNARY = 267
+    TOK_IDENTIFIER = 259,
+    TOK_OP_OR = 260,
+    TOK_OP_AND = 261,
+    TOK_OP_EQ = 262,
+    TOK_OP_NE = 263,
+    TOK_OP_LE = 264,
+    TOK_OP_GE = 265,
+    TOK_OP_LEFT = 266,
+    TOK_OP_RIGHT = 267,
+    TOK_UNARY = 268
   };
 #endif
 
@@ -429,23 +437,23 @@
 #endif /* !YYCOPY_NEEDED */
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  14
+#define YYFINAL  15
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   175
+#define YYLAST   176
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  27
+#define YYNTOKENS  28
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  3
+#define YYNNTS  5
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  26
+#define YYNRULES  29
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  52
+#define YYNSTATES  55
 
 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
    by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   267
+#define YYMAXUTOK   268
 
 #define YYTRANSLATE(YYX)                                                \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -457,16 +465,16 @@
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,    23,     2,     2,     2,    21,     8,     2,
-      25,    26,    19,    17,     2,    18,     2,    20,     2,     2,
+       2,     2,     2,    24,     2,     2,     2,    22,     9,     2,
+      26,    27,    20,    18,     2,    19,     2,    21,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      11,     2,    12,     2,     2,     2,     2,     2,     2,     2,
+      12,     2,    13,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     7,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     8,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     6,     2,    24,     2,     2,     2,
+       2,     2,     2,     2,     7,     2,    25,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -480,16 +488,16 @@
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     9,    10,    13,    14,    15,    16,    22
+       5,     6,    10,    11,    14,    15,    16,    17,    23
 };
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_uint8 yyrline[] =
+static const yytype_uint16 yyrline[] =
 {
-       0,    97,    97,   104,   105,   108,   111,   114,   117,   120,
-     123,   126,   129,   132,   135,   138,   141,   144,   147,   150,
-     163,   176,   179,   182,   185,   188,   191
+       0,   105,   105,   111,   112,   118,   118,   139,   139,   160,
+     163,   166,   169,   172,   175,   178,   181,   184,   187,   190,
+     193,   196,   199,   222,   245,   248,   251,   254,   257,   260
 };
 #endif
 
@@ -498,11 +506,11 @@
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
 {
-  "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_OP_OR",
-  "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE", "'<'",
-  "'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT", "'+'",
-  "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('", "')'",
-  "$accept", "input", "expression", YY_NULLPTR
+  "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_IDENTIFIER",
+  "TOK_OP_OR", "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_EQ", "TOK_OP_NE",
+  "'<'", "'>'", "TOK_OP_LE", "TOK_OP_GE", "TOK_OP_LEFT", "TOK_OP_RIGHT",
+  "'+'", "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('",
+  "')'", "$accept", "input", "expression", "$@1", "$@2", YY_NULLPTR
 };
 #endif
 
@@ -511,16 +519,16 @@
    (internal) symbol number NUM (which must be that of a token).  */
 static const yytype_uint16 yytoknum[] =
 {
-       0,   256,   257,   258,   259,   260,   124,    94,    38,   261,
-     262,    60,    62,   263,   264,   265,   266,    43,    45,    42,
-      47,    37,   267,    33,   126,    40,    41
+       0,   256,   257,   258,   259,   260,   261,   124,    94,    38,
+     262,   263,    60,    62,   264,   265,   266,   267,    43,    45,
+      42,    47,    37,   268,    33,   126,    40,    41
 };
 # endif
 
-#define YYPACT_NINF -11
+#define YYPACT_NINF -12
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-11)))
+  (!!((Yystate) == (-12)))
 
 #define YYTABLE_NINF -1
 
@@ -531,12 +539,12 @@
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-      46,   -11,    46,    46,    46,    46,    46,    12,    68,   -11,
-     -11,   -11,   -11,    27,   -11,    46,    46,    46,    46,    46,
-      46,    46,    46,    46,    46,    46,    46,    46,    46,    46,
-      46,    46,    46,   -11,    85,   101,   116,   130,   143,   154,
-     154,   -10,   -10,   -10,   -10,    37,    37,    31,    31,   -11,
-     -11,   -11
+      31,   -12,   -12,    31,    31,    31,    31,    31,    51,    76,
+     -12,   -12,   -12,   -12,    53,   -12,   -12,   -12,    31,    31,
+      31,    31,    31,    31,    31,    31,    31,    31,    31,    31,
+      31,    31,    31,    31,   -12,    31,    31,   124,   138,    26,
+     149,   149,   -11,   -11,   -11,   -11,   154,   154,    -8,    -8,
+     -12,   -12,   -12,    93,   109
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -544,24 +552,24 @@
      means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       0,     3,     0,     0,     0,     0,     0,     0,     2,    25,
-      24,    22,    23,     0,     1,     0,     0,     0,     0,     0,
+       0,     3,     4,     0,     0,     0,     0,     0,     0,     2,
+      28,    27,    25,    26,     0,     1,     5,     7,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    26,     4,     5,     6,     7,     8,    10,
-       9,    14,    13,    12,    11,    16,    15,    18,    17,    21,
-      20,    19
+       0,     0,     0,     0,    29,     0,     0,     9,    10,    11,
+      13,    12,    17,    16,    15,    14,    19,    18,    21,    20,
+      24,    23,    22,     6,     8
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-     -11,   -11,    -2
+     -12,   -12,    -3,   -12,   -12
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
-      -1,     7,     8
+      -1,     8,     9,    35,    36
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -569,74 +577,74 @@
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_uint8 yytable[] =
 {
-       9,    10,    11,    12,    13,    26,    27,    28,    29,    30,
-      31,    32,    14,    34,    35,    36,    37,    38,    39,    40,
-      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,
-      51,    15,    16,    17,    18,    19,    20,    21,    22,    23,
-      24,    25,    26,    27,    28,    29,    30,    31,    32,     1,
-      30,    31,    32,    33,    28,    29,    30,    31,    32,     0,
-       0,     0,     0,     2,     3,     0,     0,     0,     0,     4,
-       5,     6,    15,    16,    17,    18,    19,    20,    21,    22,
+      10,    11,    12,    13,    14,    27,    28,    29,    30,    31,
+      32,    33,    31,    32,    33,    37,    38,    39,    40,    41,
+      42,    43,    44,    45,    46,    47,    48,    49,    50,    51,
+      52,     0,    53,    54,     1,     2,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,     3,
+       4,    15,     0,     0,     0,     5,     6,     7,    16,    17,
+      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    33,     0,     0,     0,     0,
+      34,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    17,
+      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    33,    18,    19,    20,    21,
+      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    33,    19,    20,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    20,    21,    22,
       23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
-      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
-      26,    27,    28,    29,    30,    31,    32,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    19,    20,
-      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
-      31,    32,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    31,    32,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,    31,    32
+      33,    23,    24,    25,    26,    27,    28,    29,    30,    31,
+      32,    33,    29,    30,    31,    32,    33
 };
 
 static const yytype_int8 yycheck[] =
 {
-       2,     3,     4,     5,     6,    15,    16,    17,    18,    19,
-      20,    21,     0,    15,    16,    17,    18,    19,    20,    21,
-      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
-      32,     4,     5,     6,     7,     8,     9,    10,    11,    12,
-      13,    14,    15,    16,    17,    18,    19,    20,    21,     3,
-      19,    20,    21,    26,    17,    18,    19,    20,    21,    -1,
-      -1,    -1,    -1,    17,    18,    -1,    -1,    -1,    -1,    23,
-      24,    25,     4,     5,     6,     7,     8,     9,    10,    11,
+       3,     4,     5,     6,     7,    16,    17,    18,    19,    20,
+      21,    22,    20,    21,    22,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,    -1,    35,    36,     3,     4,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,    18,
+      19,     0,    -1,    -1,    -1,    24,    25,    26,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    -1,    -1,    -1,    -1,
+      27,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,     8,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,     9,    10,    11,
       12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,     6,     7,     8,
-       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,     7,     8,     9,    10,    11,    12,    13,
-      14,    15,    16,    17,    18,    19,    20,    21,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,     9,    10,    11,    12,    13,    14,    15,    16,
-      17,    18,    19,    20,    21,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    20,    21
+      22,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    18,    19,    20,    21,    22
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     3,    17,    18,    23,    24,    25,    28,    29,    29,
-      29,    29,    29,    29,     0,     4,     5,     6,     7,     8,
+       0,     3,     4,    18,    19,    24,    25,    26,    29,    30,
+      30,    30,    30,    30,    30,     0,     5,     6,     7,     8,
        9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-      19,    20,    21,    26,    29,    29,    29,    29,    29,    29,
-      29,    29,    29,    29,    29,    29,    29,    29,    29,    29,
-      29,    29
+      19,    20,    21,    22,    27,    31,    32,    30,    30,    30,
+      30,    30,    30,    30,    30,    30,    30,    30,    30,    30,
+      30,    30,    30,    30,    30
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    27,    28,    29,    29,    29,    29,    29,    29,    29,
-      29,    29,    29,    29,    29,    29,    29,    29,    29,    29,
-      29,    29,    29,    29,    29,    29,    29
+       0,    28,    29,    30,    30,    31,    30,    32,    30,    30,
+      30,    30,    30,    30,    30,    30,    30,    30,    30,    30,
+      30,    30,    30,    30,    30,    30,    30,    30,    30,    30
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
-       0,     2,     1,     1,     3,     3,     3,     3,     3,     3,
+       0,     2,     1,     1,     1,     0,     4,     0,     4,     3,
        3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       3,     3,     2,     2,     2,     2,     3
+       3,     3,     3,     3,     3,     2,     2,     2,     2,     3
 };
 
 
@@ -1322,7 +1330,6 @@
 
     {
         *(context->result) = static_cast<int>((yyvsp[0]));
-        YYACCEPT;
     }
 
     break;
@@ -1330,7 +1337,10 @@
   case 4:
 
     {
-        (yyval) = (yyvsp[-2]) || (yyvsp[0]);
+        if (!context->isIgnoringErrors())
+        {
+            YYABORT;
+        }
     }
 
     break;
@@ -1338,7 +1348,15 @@
   case 5:
 
     {
-        (yyval) = (yyvsp[-2]) && (yyvsp[0]);
+        if ((yyvsp[-1]) != 0)
+        {
+            // Ignore errors in the short-circuited part of the expression.
+            // ESSL3.00 section 3.4:
+            // If an operand is not evaluated, the presence of undefined identifiers
+            // in the operand will not cause an error.
+            // Unevaluated division by zero should not cause an error either.
+            context->startIgnoreErrors();
+        }
     }
 
     break;
@@ -1346,7 +1364,15 @@
   case 6:
 
     {
-        (yyval) = (yyvsp[-2]) | (yyvsp[0]);
+        if ((yyvsp[-3]) != 0)
+        {
+            context->endIgnoreErrors();
+            (yyval) = static_cast<YYSTYPE>(1);
+        }
+        else
+        {
+            (yyval) = (yyvsp[-3]) || (yyvsp[0]);
+        }
     }
 
     break;
@@ -1354,7 +1380,15 @@
   case 7:
 
     {
-        (yyval) = (yyvsp[-2]) ^ (yyvsp[0]);
+        if ((yyvsp[-1]) == 0)
+        {
+            // Ignore errors in the short-circuited part of the expression.
+            // ESSL3.00 section 3.4:
+            // If an operand is not evaluated, the presence of undefined identifiers
+            // in the operand will not cause an error.
+            // Unevaluated division by zero should not cause an error either.
+            context->startIgnoreErrors();
+        }
     }
 
     break;
@@ -1362,7 +1396,15 @@
   case 8:
 
     {
-        (yyval) = (yyvsp[-2]) & (yyvsp[0]);
+        if ((yyvsp[-3]) == 0)
+        {
+            context->endIgnoreErrors();
+            (yyval) = static_cast<YYSTYPE>(0);
+        }
+        else
+        {
+            (yyval) = (yyvsp[-3]) && (yyvsp[0]);
+        }
     }
 
     break;
@@ -1370,7 +1412,7 @@
   case 9:
 
     {
-        (yyval) = (yyvsp[-2]) != (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) | (yyvsp[0]);
     }
 
     break;
@@ -1378,7 +1420,7 @@
   case 10:
 
     {
-        (yyval) = (yyvsp[-2]) == (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) ^ (yyvsp[0]);
     }
 
     break;
@@ -1386,7 +1428,7 @@
   case 11:
 
     {
-        (yyval) = (yyvsp[-2]) >= (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) & (yyvsp[0]);
     }
 
     break;
@@ -1394,7 +1436,7 @@
   case 12:
 
     {
-        (yyval) = (yyvsp[-2]) <= (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) != (yyvsp[0]);
     }
 
     break;
@@ -1402,7 +1444,7 @@
   case 13:
 
     {
-        (yyval) = (yyvsp[-2]) > (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) == (yyvsp[0]);
     }
 
     break;
@@ -1410,7 +1452,7 @@
   case 14:
 
     {
-        (yyval) = (yyvsp[-2]) < (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) >= (yyvsp[0]);
     }
 
     break;
@@ -1418,7 +1460,7 @@
   case 15:
 
     {
-        (yyval) = (yyvsp[-2]) >> (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) <= (yyvsp[0]);
     }
 
     break;
@@ -1426,7 +1468,7 @@
   case 16:
 
     {
-        (yyval) = (yyvsp[-2]) << (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) > (yyvsp[0]);
     }
 
     break;
@@ -1434,7 +1476,7 @@
   case 17:
 
     {
-        (yyval) = (yyvsp[-2]) - (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) < (yyvsp[0]);
     }
 
     break;
@@ -1442,7 +1484,7 @@
   case 18:
 
     {
-        (yyval) = (yyvsp[-2]) + (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) >> (yyvsp[0]);
     }
 
     break;
@@ -1450,17 +1492,7 @@
   case 19:
 
     {
-        if ((yyvsp[0]) == 0) {
-            std::ostringstream stream;
-            stream << (yyvsp[-2]) << " % " << (yyvsp[0]);
-            std::string text = stream.str();
-            context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
-                                         context->token->location,
-                                         text.c_str());
-            YYABORT;
-        } else {
-            (yyval) = (yyvsp[-2]) % (yyvsp[0]);
-        }
+        (yyval) = (yyvsp[-2]) << (yyvsp[0]);
     }
 
     break;
@@ -1468,17 +1500,7 @@
   case 20:
 
     {
-        if ((yyvsp[0]) == 0) {
-            std::ostringstream stream;
-            stream << (yyvsp[-2]) << " / " << (yyvsp[0]);
-            std::string text = stream.str();
-            context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
-                                         context->token->location,
-                                         text.c_str());
-            YYABORT;
-        } else {
-            (yyval) = (yyvsp[-2]) / (yyvsp[0]);
-        }
+        (yyval) = (yyvsp[-2]) - (yyvsp[0]);
     }
 
     break;
@@ -1486,7 +1508,7 @@
   case 21:
 
     {
-        (yyval) = (yyvsp[-2]) * (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) + (yyvsp[0]);
     }
 
     break;
@@ -1494,7 +1516,27 @@
   case 22:
 
     {
-        (yyval) = ! (yyvsp[0]);
+        if ((yyvsp[0]) == 0)
+        {
+            if (context->isIgnoringErrors())
+            {
+                (yyval) = static_cast<YYSTYPE>(0);
+            }
+            else
+            {
+                std::ostringstream stream;
+                stream << (yyvsp[-2]) << " % " << (yyvsp[0]);
+                std::string text = stream.str();
+                context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
+                                             context->token->location,
+                                             text.c_str());
+                YYABORT;
+            }
+        }
+        else
+        {
+            (yyval) = (yyvsp[-2]) % (yyvsp[0]);
+        }
     }
 
     break;
@@ -1502,7 +1544,27 @@
   case 23:
 
     {
-        (yyval) = ~ (yyvsp[0]);
+        if ((yyvsp[0]) == 0)
+        {
+            if (context->isIgnoringErrors())
+            {
+                (yyval) = static_cast<YYSTYPE>(0);
+            }
+            else
+            {
+                std::ostringstream stream;
+                stream << (yyvsp[-2]) << " / " << (yyvsp[0]);
+                std::string text = stream.str();
+                context->diagnostics->report(pp::Diagnostics::PP_DIVISION_BY_ZERO,
+                                            context->token->location,
+                                            text.c_str());
+                YYABORT;
+            }
+        }
+        else
+        {
+            (yyval) = (yyvsp[-2]) / (yyvsp[0]);
+        }
     }
 
     break;
@@ -1510,7 +1572,7 @@
   case 24:
 
     {
-        (yyval) = - (yyvsp[0]);
+        (yyval) = (yyvsp[-2]) * (yyvsp[0]);
     }
 
     break;
@@ -1518,7 +1580,7 @@
   case 25:
 
     {
-        (yyval) = + (yyvsp[0]);
+        (yyval) = ! (yyvsp[0]);
     }
 
     break;
@@ -1526,6 +1588,30 @@
   case 26:
 
     {
+        (yyval) = ~ (yyvsp[0]);
+    }
+
+    break;
+
+  case 27:
+
+    {
+        (yyval) = - (yyvsp[0]);
+    }
+
+    break;
+
+  case 28:
+
+    {
+        (yyval) = + (yyvsp[0]);
+    }
+
+    break;
+
+  case 29:
+
+    {
         (yyval) = (yyvsp[-1]);
     }
 
@@ -1781,6 +1867,15 @@
         type = TOK_CONST_INT;
         break;
       }
+      case pp::Token::IDENTIFIER:
+        if (!context->isIgnoringErrors())
+        {
+            context->diagnostics->report(pp::Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN,
+                                         token->location, token->text);
+        }
+        *lvalp = static_cast<YYSTYPE>(-1);
+        type = TOK_IDENTIFIER;
+        break;
       case pp::Token::OP_OR:
         type = TOK_OP_OR;
         break;
@@ -1855,6 +1950,7 @@
     context.lexer = mLexer;
     context.token = token;
     context.result = result;
+    context.ignoreErrors = 0;
     int ret = yyparse(&context);
     switch (ret)
     {