fix unary precedence
This commit is contained in:
parent
704979f9bb
commit
ea9b427363
80
parser.c
80
parser.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user