Fixed the operator precedence of several operators.
This commit is contained in:
parent
47567307ce
commit
3925240c7b
1 changed files with 115 additions and 100 deletions
215
src/parser.cc
215
src/parser.cc
|
|
@ -169,19 +169,22 @@ expr_t::parser_t::parse_mul_expr(std::istream& in,
|
||||||
ptr_op_t node(parse_unary_expr(in, tflags));
|
ptr_op_t node(parse_unary_expr(in, tflags));
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
token_t& tok = next_token(in, tflags);
|
while (true) {
|
||||||
|
token_t& tok = next_token(in, tflags);
|
||||||
|
|
||||||
if (tok.kind == token_t::STAR || tok.kind == token_t::KW_DIV) {
|
if (tok.kind == token_t::STAR || tok.kind == token_t::KW_DIV) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(tok.kind == token_t::STAR ?
|
node = new op_t(tok.kind == token_t::STAR ?
|
||||||
op_t::O_MUL : op_t::O_DIV);
|
op_t::O_MUL : op_t::O_DIV);
|
||||||
node->set_left(prev);
|
node->set_left(prev);
|
||||||
node->set_right(parse_mul_expr(in, tflags));
|
node->set_right(parse_unary_expr(in, tflags));
|
||||||
if (! node->right())
|
if (! node->right())
|
||||||
throw_(parse_error,
|
throw_(parse_error,
|
||||||
tok.symbol << " operator not followed by argument");
|
tok.symbol << " operator not followed by argument");
|
||||||
} else {
|
} else {
|
||||||
push_token(tok);
|
push_token(tok);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -195,20 +198,23 @@ expr_t::parser_t::parse_add_expr(std::istream& in,
|
||||||
ptr_op_t node(parse_mul_expr(in, tflags));
|
ptr_op_t node(parse_mul_expr(in, tflags));
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
token_t& tok = next_token(in, tflags);
|
while (true) {
|
||||||
|
token_t& tok = next_token(in, tflags);
|
||||||
|
|
||||||
if (tok.kind == token_t::PLUS ||
|
if (tok.kind == token_t::PLUS ||
|
||||||
tok.kind == token_t::MINUS) {
|
tok.kind == token_t::MINUS) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(tok.kind == token_t::PLUS ?
|
node = new op_t(tok.kind == token_t::PLUS ?
|
||||||
op_t::O_ADD : op_t::O_SUB);
|
op_t::O_ADD : op_t::O_SUB);
|
||||||
node->set_left(prev);
|
node->set_left(prev);
|
||||||
node->set_right(parse_add_expr(in, tflags));
|
node->set_right(parse_mul_expr(in, tflags));
|
||||||
if (! node->right())
|
if (! node->right())
|
||||||
throw_(parse_error,
|
throw_(parse_error,
|
||||||
tok.symbol << " operator not followed by argument");
|
tok.symbol << " operator not followed by argument");
|
||||||
} else {
|
} else {
|
||||||
push_token(tok);
|
push_token(tok);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,67 +228,70 @@ expr_t::parser_t::parse_logic_expr(std::istream& in,
|
||||||
ptr_op_t node(parse_add_expr(in, tflags));
|
ptr_op_t node(parse_add_expr(in, tflags));
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
op_t::kind_t kind = op_t::LAST;
|
while (true) {
|
||||||
parse_flags_t _flags = tflags;
|
op_t::kind_t kind = op_t::LAST;
|
||||||
token_t& tok = next_token(in, tflags);
|
parse_flags_t _flags = tflags;
|
||||||
bool negate = false;
|
token_t& tok = next_token(in, tflags);
|
||||||
|
bool negate = false;
|
||||||
|
|
||||||
switch (tok.kind) {
|
switch (tok.kind) {
|
||||||
case token_t::DEFINE:
|
case token_t::DEFINE:
|
||||||
kind = op_t::O_DEFINE;
|
kind = op_t::O_DEFINE;
|
||||||
break;
|
break;
|
||||||
case token_t::EQUAL:
|
case token_t::EQUAL:
|
||||||
if (tflags.has_flags(PARSE_NO_ASSIGN))
|
if (tflags.has_flags(PARSE_NO_ASSIGN))
|
||||||
tok.rewind(in);
|
tok.rewind(in);
|
||||||
else
|
else
|
||||||
|
kind = op_t::O_EQ;
|
||||||
|
break;
|
||||||
|
case token_t::NEQUAL:
|
||||||
kind = op_t::O_EQ;
|
kind = op_t::O_EQ;
|
||||||
break;
|
negate = true;
|
||||||
case token_t::NEQUAL:
|
break;
|
||||||
kind = op_t::O_EQ;
|
case token_t::MATCH:
|
||||||
negate = true;
|
kind = op_t::O_MATCH;
|
||||||
break;
|
break;
|
||||||
case token_t::MATCH:
|
case token_t::NMATCH:
|
||||||
kind = op_t::O_MATCH;
|
kind = op_t::O_MATCH;
|
||||||
break;
|
negate = true;
|
||||||
case token_t::NMATCH:
|
break;
|
||||||
kind = op_t::O_MATCH;
|
case token_t::LESS:
|
||||||
negate = true;
|
kind = op_t::O_LT;
|
||||||
break;
|
break;
|
||||||
case token_t::LESS:
|
case token_t::LESSEQ:
|
||||||
kind = op_t::O_LT;
|
kind = op_t::O_LTE;
|
||||||
break;
|
break;
|
||||||
case token_t::LESSEQ:
|
case token_t::GREATER:
|
||||||
kind = op_t::O_LTE;
|
kind = op_t::O_GT;
|
||||||
break;
|
break;
|
||||||
case token_t::GREATER:
|
case token_t::GREATEREQ:
|
||||||
kind = op_t::O_GT;
|
kind = op_t::O_GTE;
|
||||||
break;
|
break;
|
||||||
case token_t::GREATEREQ:
|
default:
|
||||||
kind = op_t::O_GTE;
|
push_token(tok);
|
||||||
break;
|
goto exit_loop;
|
||||||
default:
|
}
|
||||||
push_token(tok);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kind != op_t::LAST) {
|
if (kind != op_t::LAST) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(kind);
|
node = new op_t(kind);
|
||||||
node->set_left(prev);
|
|
||||||
node->set_right(parse_add_expr(in, _flags));
|
|
||||||
|
|
||||||
if (! node->right())
|
|
||||||
throw_(parse_error,
|
|
||||||
tok.symbol << " operator not followed by argument");
|
|
||||||
|
|
||||||
if (negate) {
|
|
||||||
prev = node;
|
|
||||||
node = new op_t(op_t::O_NOT);
|
|
||||||
node->set_left(prev);
|
node->set_left(prev);
|
||||||
|
node->set_right(parse_add_expr(in, _flags));
|
||||||
|
|
||||||
|
if (! node->right())
|
||||||
|
throw_(parse_error,
|
||||||
|
tok.symbol << " operator not followed by argument");
|
||||||
|
|
||||||
|
if (negate) {
|
||||||
|
prev = node;
|
||||||
|
node = new op_t(op_t::O_NOT);
|
||||||
|
node->set_left(prev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exit_loop:
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -293,18 +302,21 @@ expr_t::parser_t::parse_and_expr(std::istream& in,
|
||||||
ptr_op_t node(parse_logic_expr(in, tflags));
|
ptr_op_t node(parse_logic_expr(in, tflags));
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
token_t& tok = next_token(in, tflags);
|
while (true) {
|
||||||
|
token_t& tok = next_token(in, tflags);
|
||||||
|
|
||||||
if (tok.kind == token_t::KW_AND) {
|
if (tok.kind == token_t::KW_AND) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(op_t::O_AND);
|
node = new op_t(op_t::O_AND);
|
||||||
node->set_left(prev);
|
node->set_left(prev);
|
||||||
node->set_right(parse_and_expr(in, tflags));
|
node->set_right(parse_logic_expr(in, tflags));
|
||||||
if (! node->right())
|
if (! node->right())
|
||||||
throw_(parse_error,
|
throw_(parse_error,
|
||||||
tok.symbol << " operator not followed by argument");
|
tok.symbol << " operator not followed by argument");
|
||||||
} else {
|
} else {
|
||||||
push_token(tok);
|
push_token(tok);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
|
|
@ -317,18 +329,21 @@ expr_t::parser_t::parse_or_expr(std::istream& in,
|
||||||
ptr_op_t node(parse_and_expr(in, tflags));
|
ptr_op_t node(parse_and_expr(in, tflags));
|
||||||
|
|
||||||
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
|
||||||
token_t& tok = next_token(in, tflags);
|
while (true) {
|
||||||
|
token_t& tok = next_token(in, tflags);
|
||||||
|
|
||||||
if (tok.kind == token_t::KW_OR) {
|
if (tok.kind == token_t::KW_OR) {
|
||||||
ptr_op_t prev(node);
|
ptr_op_t prev(node);
|
||||||
node = new op_t(op_t::O_OR);
|
node = new op_t(op_t::O_OR);
|
||||||
node->set_left(prev);
|
node->set_left(prev);
|
||||||
node->set_right(parse_or_expr(in, tflags));
|
node->set_right(parse_and_expr(in, tflags));
|
||||||
if (! node->right())
|
if (! node->right())
|
||||||
throw_(parse_error,
|
throw_(parse_error,
|
||||||
tok.symbol << " operator not followed by argument");
|
tok.symbol << " operator not followed by argument");
|
||||||
} else {
|
} else {
|
||||||
push_token(tok);
|
push_token(tok);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue