fix unary precedence

This commit is contained in:
tovjemam 2024-10-13 21:42:01 +02:00
parent 704979f9bb
commit ea9b427363

View File

@ -28,14 +28,14 @@ static void error_expected_one_of(struct lexer *lex, const int expected[], enum
"lexer error", "lexer error",
"constant", "constant",
"+", "+",
"-", "-",
"*", "*",
"/", "/",
"^", "^",
"x", "x",
"function name", "function name",
"(", "(",
")" ")"
}; };
int separate = 0; int separate = 0;
@ -56,16 +56,16 @@ static void error_expected_one_of(struct lexer *lex, const int expected[], enum
lex_print_position(lex); lex_print_position(lex);
} }
static void error_expected_single(struct lexer *lex, enum token_type expected, enum token_type got) { static void error_expected_single(struct lexer* lex, enum token_type expected, enum token_type got) {
static int expected_arr[] = { -1, -1 }; static int expected_arr[] = { -1, -1 };
expected_arr[0] = expected; expected_arr[0] = expected;
error_expected_one_of(lex, expected_arr, got); error_expected_one_of(lex, expected_arr, got);
} }
struct expr_node *parse_subexpression(struct lexer *lex); struct expr_node* parse_subexpression(struct lexer* lex);
static struct expr_node *parse_bracketed(struct lexer* lex) { static struct expr_node* parse_bracketed(struct lexer* lex) {
struct expr_node *node; struct expr_node* node;
if (!accept(lex, TOK_LEFT_PAREN)) { if (!accept(lex, TOK_LEFT_PAREN)) {
error_expected_single(lex, TOK_LEFT_PAREN, lex_token(lex)->type); error_expected_single(lex, TOK_LEFT_PAREN, lex_token(lex)->type);
@ -84,8 +84,8 @@ static struct expr_node *parse_bracketed(struct lexer* lex) {
return node; return node;
} }
static struct expr_node *parse_base(struct lexer *lex) { static struct expr_node* parse_base(struct lexer* lex) {
struct expr_node *inner; struct expr_node* inner;
if (token_is(lex, TOK_NUMBER)) { if (token_is(lex, TOK_NUMBER)) {
double val = token_num(lex); double val = token_num(lex);
@ -119,32 +119,15 @@ static struct expr_node *parse_base(struct lexer *lex) {
return NULL; return NULL;
} }
static struct expr_node* parse_unary(struct lexer *lex) { static struct expr_node* parse_unary(struct lexer* lex);
if (accept(lex, TOK_MINUS)) {
struct expr_node *node, *inner;
if (!(inner = parse_base(lex))) static struct expr_node* parse_factor(struct lexer* lex) {
return NULL; struct expr_node* node, * new_node, * inner;
if (!(node = node_create_neg(inner))) { if (!(node = parse_base(lex)))
node_free(inner);
return NULL;
}
return node;
}
accept(lex, TOK_PLUS);
return parse_base(lex);
}
static struct expr_node *parse_factor(struct lexer *lex) {
struct expr_node *node, *new_node, *inner;
if (!(node = parse_unary(lex)))
return NULL; return NULL;
while (accept(lex, TOK_POWER)) { if (accept(lex, TOK_POWER)) {
if (!(inner = parse_unary(lex))) { if (!(inner = parse_unary(lex))) {
node_free(node); node_free(node);
return NULL; return NULL;
@ -156,16 +139,35 @@ static struct expr_node *parse_factor(struct lexer *lex) {
return NULL; return NULL;
} }
node = new_node; return new_node;
} }
return node; return node;
} }
static struct expr_node* parse_unary(struct lexer *lex) {
if (accept(lex, TOK_MINUS)) {
struct expr_node *node, *inner;
if (!(inner = parse_factor(lex)))
return NULL;
if (!(node = node_create_neg(inner))) {
node_free(inner);
return NULL;
}
return node;
}
accept(lex, TOK_PLUS);
return parse_factor(lex);
}
static struct expr_node *parse_term(struct lexer *lex) { static struct expr_node *parse_term(struct lexer *lex) {
struct expr_node *node, *new_node, *inner; struct expr_node *node, *new_node, *inner;
if (!(node = parse_factor(lex))) if (!(node = parse_unary(lex)))
return NULL; return NULL;
while (1) { while (1) {
@ -178,7 +180,7 @@ static struct expr_node *parse_term(struct lexer *lex) {
else else
break; break;
if (!(inner = parse_factor(lex))) { if (!(inner = parse_unary(lex))) {
node_free(node); node_free(node);
return NULL; return NULL;
} }