Forced parentheses on unclear precedence (#109)

forced parentheses to resolve issue #97
This commit is contained in:
mathis2003
2021-03-15 16:55:35 +01:00
committed by GitHub
parent 6f922b85a1
commit fe212a5a33

View File

@@ -6,6 +6,21 @@
#include "parser_internal.h"
#include "bigint.h"
#define BINOP_PREC_REQ_LEN 40
int BINOP_PREC_REQ[BINOP_PREC_REQ_LEN] = {
// bitwise operations
[BINARYOP_BIT_OR] = 1,
[BINARYOP_BIT_XOR] = 1,
[BINARYOP_BIT_AND] = 1,
// comparison operations
[BINARYOP_GT] = 2,
[BINARYOP_GE] = 2,
[BINARYOP_LT] = 2,
[BINARYOP_LE] = 2,
[BINARYOP_NE] = 2,
[BINARYOP_EQ] = 2
};
typedef Expr *(*ParseFn)(Context *context, Expr *);
@@ -367,6 +382,23 @@ static Expr *parse_failable(Context *context, Expr *left_side)
return failable;
}
bool plain_op_precedence(Expr *left_side, Expr * main_expr, Expr *right_side)
{
int precedence_main = BINOP_PREC_REQ[main_expr->binary_expr.operator];
if (left_side->expr_kind == EXPR_BINARY)
{
int precedence_left = BINOP_PREC_REQ[left_side->binary_expr.operator];
return !(precedence_left && (precedence_left == precedence_main));
}
if (right_side->expr_kind == EXPR_BINARY)
{
int precedence_right = BINOP_PREC_REQ[right_side->binary_expr.operator];
return !(precedence_right && (precedence_right == precedence_main));
}
return true;
}
static Expr *parse_binary(Context *context, Expr *left_side)
{
assert(left_side && expr_ok(left_side));
@@ -390,6 +422,13 @@ static Expr *parse_binary(Context *context, Expr *left_side)
expr->binary_expr.operator = binaryop_from_token(operator_type);
expr->binary_expr.left = left_side;
expr->binary_expr.right = right_side;
// check if both sides have a binary operation where the precedence is unclear. Example: a ^ b | c
if (!plain_op_precedence(left_side, expr, right_side))
{
SEMA_TOKEN_ERROR(context->tok, "You need to add explicit parentheses.");
}
expr->span.end_loc = right_side->span.end_loc;
return expr;
}