-#define CREATE_BINEXPR_PARSER(token_type, binexpression_type, sfunc, lr) \
-static expression_t *parse_##binexpression_type(unsigned precedence, \
- expression_t *left) \
-{ \
- expression_t *binexpr = allocate_expression_zero(binexpression_type); \
- binexpr->base.source_position = *HERE; \
- binexpr->binary.left = left; \
- eat(token_type); \
- \
- expression_t *right = parse_sub_expression(precedence + lr); \
- \
- binexpr->binary.right = right; \
- sfunc(&binexpr->binary); \
- \
- return binexpr; \
-}
-
-CREATE_BINEXPR_PARSER(',', EXPR_BINARY_COMMA, semantic_comma, 1)
-CREATE_BINEXPR_PARSER('*', EXPR_BINARY_MUL, semantic_binexpr_arithmetic, 1)
-CREATE_BINEXPR_PARSER('/', EXPR_BINARY_DIV, semantic_divmod_arithmetic, 1)
-CREATE_BINEXPR_PARSER('%', EXPR_BINARY_MOD, semantic_divmod_arithmetic, 1)
-CREATE_BINEXPR_PARSER('+', EXPR_BINARY_ADD, semantic_add, 1)
-CREATE_BINEXPR_PARSER('-', EXPR_BINARY_SUB, semantic_sub, 1)
-CREATE_BINEXPR_PARSER('<', EXPR_BINARY_LESS, semantic_comparison, 1)
-CREATE_BINEXPR_PARSER('>', EXPR_BINARY_GREATER, semantic_comparison, 1)
-CREATE_BINEXPR_PARSER('=', EXPR_BINARY_ASSIGN, semantic_binexpr_assign, 0)
-
-CREATE_BINEXPR_PARSER(T_EQUALEQUAL, EXPR_BINARY_EQUAL,
- semantic_comparison, 1)
-CREATE_BINEXPR_PARSER(T_EXCLAMATIONMARKEQUAL, EXPR_BINARY_NOTEQUAL,
- semantic_comparison, 1)
-CREATE_BINEXPR_PARSER(T_LESSEQUAL, EXPR_BINARY_LESSEQUAL,
- semantic_comparison, 1)
-CREATE_BINEXPR_PARSER(T_GREATEREQUAL, EXPR_BINARY_GREATEREQUAL,
- semantic_comparison, 1)
-
-CREATE_BINEXPR_PARSER('&', EXPR_BINARY_BITWISE_AND,
- semantic_binexpr_arithmetic, 1)
-CREATE_BINEXPR_PARSER('|', EXPR_BINARY_BITWISE_OR,
- semantic_binexpr_arithmetic, 1)
-CREATE_BINEXPR_PARSER('^', EXPR_BINARY_BITWISE_XOR,
- semantic_binexpr_arithmetic, 1)
-CREATE_BINEXPR_PARSER(T_ANDAND, EXPR_BINARY_LOGICAL_AND,
- semantic_logical_op, 1)
-CREATE_BINEXPR_PARSER(T_PIPEPIPE, EXPR_BINARY_LOGICAL_OR,
- semantic_logical_op, 1)
-CREATE_BINEXPR_PARSER(T_LESSLESS, EXPR_BINARY_SHIFTLEFT,
- semantic_shift_op, 1)
-CREATE_BINEXPR_PARSER(T_GREATERGREATER, EXPR_BINARY_SHIFTRIGHT,
- semantic_shift_op, 1)
-CREATE_BINEXPR_PARSER(T_PLUSEQUAL, EXPR_BINARY_ADD_ASSIGN,
- semantic_arithmetic_addsubb_assign, 0)
-CREATE_BINEXPR_PARSER(T_MINUSEQUAL, EXPR_BINARY_SUB_ASSIGN,
- semantic_arithmetic_addsubb_assign, 0)
-CREATE_BINEXPR_PARSER(T_ASTERISKEQUAL, EXPR_BINARY_MUL_ASSIGN,
- semantic_arithmetic_assign, 0)
-CREATE_BINEXPR_PARSER(T_SLASHEQUAL, EXPR_BINARY_DIV_ASSIGN,
- semantic_divmod_assign, 0)
-CREATE_BINEXPR_PARSER(T_PERCENTEQUAL, EXPR_BINARY_MOD_ASSIGN,
- semantic_divmod_assign, 0)
-CREATE_BINEXPR_PARSER(T_LESSLESSEQUAL, EXPR_BINARY_SHIFTLEFT_ASSIGN,
- semantic_arithmetic_assign, 0)
-CREATE_BINEXPR_PARSER(T_GREATERGREATEREQUAL, EXPR_BINARY_SHIFTRIGHT_ASSIGN,
- semantic_arithmetic_assign, 0)
-CREATE_BINEXPR_PARSER(T_ANDEQUAL, EXPR_BINARY_BITWISE_AND_ASSIGN,
- semantic_arithmetic_assign, 0)
-CREATE_BINEXPR_PARSER(T_PIPEEQUAL, EXPR_BINARY_BITWISE_OR_ASSIGN,
- semantic_arithmetic_assign, 0)
-CREATE_BINEXPR_PARSER(T_CARETEQUAL, EXPR_BINARY_BITWISE_XOR_ASSIGN,
- semantic_arithmetic_assign, 0)
-
-static expression_t *parse_sub_expression(unsigned precedence)
+/**
+ * @param prec_r precedence of the right operand
+ */
+#define CREATE_BINEXPR_PARSER(token_type, binexpression_type, prec_r, sfunc) \
+static expression_t *parse_##binexpression_type(expression_t *left) \
+{ \
+ expression_t *binexpr = allocate_expression_zero(binexpression_type); \
+ binexpr->base.source_position = *HERE; \
+ binexpr->binary.left = left; \
+ eat(token_type); \
+ \
+ expression_t *right = parse_sub_expression(prec_r); \
+ \
+ binexpr->binary.right = right; \
+ sfunc(&binexpr->binary); \
+ \
+ return binexpr; \
+}
+
+CREATE_BINEXPR_PARSER('*', EXPR_BINARY_MUL, PREC_CAST, semantic_binexpr_arithmetic)
+CREATE_BINEXPR_PARSER('/', EXPR_BINARY_DIV, PREC_CAST, semantic_divmod_arithmetic)
+CREATE_BINEXPR_PARSER('%', EXPR_BINARY_MOD, PREC_CAST, semantic_divmod_arithmetic)
+CREATE_BINEXPR_PARSER('+', EXPR_BINARY_ADD, PREC_MULTIPLICATIVE, semantic_add)
+CREATE_BINEXPR_PARSER('-', EXPR_BINARY_SUB, PREC_MULTIPLICATIVE, semantic_sub)
+CREATE_BINEXPR_PARSER(T_LESSLESS, EXPR_BINARY_SHIFTLEFT, PREC_ADDITIVE, semantic_shift_op)
+CREATE_BINEXPR_PARSER(T_GREATERGREATER, EXPR_BINARY_SHIFTRIGHT, PREC_ADDITIVE, semantic_shift_op)
+CREATE_BINEXPR_PARSER('<', EXPR_BINARY_LESS, PREC_SHIFT, semantic_comparison)
+CREATE_BINEXPR_PARSER('>', EXPR_BINARY_GREATER, PREC_SHIFT, semantic_comparison)
+CREATE_BINEXPR_PARSER(T_LESSEQUAL, EXPR_BINARY_LESSEQUAL, PREC_SHIFT, semantic_comparison)
+CREATE_BINEXPR_PARSER(T_GREATEREQUAL, EXPR_BINARY_GREATEREQUAL, PREC_SHIFT, semantic_comparison)
+CREATE_BINEXPR_PARSER(T_EXCLAMATIONMARKEQUAL, EXPR_BINARY_NOTEQUAL, PREC_RELATIONAL, semantic_comparison)
+CREATE_BINEXPR_PARSER(T_EQUALEQUAL, EXPR_BINARY_EQUAL, PREC_RELATIONAL, semantic_comparison)
+CREATE_BINEXPR_PARSER('&', EXPR_BINARY_BITWISE_AND, PREC_EQUALITY, semantic_binexpr_arithmetic)
+CREATE_BINEXPR_PARSER('^', EXPR_BINARY_BITWISE_XOR, PREC_AND, semantic_binexpr_arithmetic)
+CREATE_BINEXPR_PARSER('|', EXPR_BINARY_BITWISE_OR, PREC_XOR, semantic_binexpr_arithmetic)
+CREATE_BINEXPR_PARSER(T_ANDAND, EXPR_BINARY_LOGICAL_AND, PREC_OR, semantic_logical_op)
+CREATE_BINEXPR_PARSER(T_PIPEPIPE, EXPR_BINARY_LOGICAL_OR, PREC_LOGICAL_AND, semantic_logical_op)
+CREATE_BINEXPR_PARSER('=', EXPR_BINARY_ASSIGN, PREC_ASSIGNMENT, semantic_binexpr_assign)
+CREATE_BINEXPR_PARSER(T_PLUSEQUAL, EXPR_BINARY_ADD_ASSIGN, PREC_ASSIGNMENT, semantic_arithmetic_addsubb_assign)
+CREATE_BINEXPR_PARSER(T_MINUSEQUAL, EXPR_BINARY_SUB_ASSIGN, PREC_ASSIGNMENT, semantic_arithmetic_addsubb_assign)
+CREATE_BINEXPR_PARSER(T_ASTERISKEQUAL, EXPR_BINARY_MUL_ASSIGN, PREC_ASSIGNMENT, semantic_arithmetic_assign)
+CREATE_BINEXPR_PARSER(T_SLASHEQUAL, EXPR_BINARY_DIV_ASSIGN, PREC_ASSIGNMENT, semantic_divmod_assign)
+CREATE_BINEXPR_PARSER(T_PERCENTEQUAL, EXPR_BINARY_MOD_ASSIGN, PREC_ASSIGNMENT, semantic_divmod_assign)
+CREATE_BINEXPR_PARSER(T_LESSLESSEQUAL, EXPR_BINARY_SHIFTLEFT_ASSIGN, PREC_ASSIGNMENT, semantic_arithmetic_assign)
+CREATE_BINEXPR_PARSER(T_GREATERGREATEREQUAL, EXPR_BINARY_SHIFTRIGHT_ASSIGN, PREC_ASSIGNMENT, semantic_arithmetic_assign)
+CREATE_BINEXPR_PARSER(T_ANDEQUAL, EXPR_BINARY_BITWISE_AND_ASSIGN, PREC_ASSIGNMENT, semantic_arithmetic_assign)
+CREATE_BINEXPR_PARSER(T_PIPEEQUAL, EXPR_BINARY_BITWISE_OR_ASSIGN, PREC_ASSIGNMENT, semantic_arithmetic_assign)
+CREATE_BINEXPR_PARSER(T_CARETEQUAL, EXPR_BINARY_BITWISE_XOR_ASSIGN, PREC_ASSIGNMENT, semantic_arithmetic_assign)
+CREATE_BINEXPR_PARSER(',', EXPR_BINARY_COMMA, PREC_ASSIGNMENT, semantic_comma)
+
+
+static expression_t *parse_sub_expression(precedence_t precedence)