Fixed the operator precedence of several operators.

This commit is contained in:
John Wiegley 2009-02-09 18:02:05 -04:00
parent 47567307ce
commit 3925240c7b

View file

@ -169,6 +169,7 @@ expr_t::parser_t::parse_mul_expr(std::istream& in,
ptr_op_t node(parse_unary_expr(in, tflags));
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
while (true) {
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::STAR || tok.kind == token_t::KW_DIV) {
@ -176,12 +177,14 @@ expr_t::parser_t::parse_mul_expr(std::istream& in,
node = new op_t(tok.kind == token_t::STAR ?
op_t::O_MUL : op_t::O_DIV);
node->set_left(prev);
node->set_right(parse_mul_expr(in, tflags));
node->set_right(parse_unary_expr(in, tflags));
if (! node->right())
throw_(parse_error,
tok.symbol << " operator not followed by argument");
} else {
push_token(tok);
break;
}
}
}
@ -195,6 +198,7 @@ expr_t::parser_t::parse_add_expr(std::istream& in,
ptr_op_t node(parse_mul_expr(in, tflags));
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
while (true) {
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::PLUS ||
@ -203,12 +207,14 @@ expr_t::parser_t::parse_add_expr(std::istream& in,
node = new op_t(tok.kind == token_t::PLUS ?
op_t::O_ADD : op_t::O_SUB);
node->set_left(prev);
node->set_right(parse_add_expr(in, tflags));
node->set_right(parse_mul_expr(in, tflags));
if (! node->right())
throw_(parse_error,
tok.symbol << " operator not followed by argument");
} else {
push_token(tok);
break;
}
}
}
@ -222,6 +228,7 @@ expr_t::parser_t::parse_logic_expr(std::istream& in,
ptr_op_t node(parse_add_expr(in, tflags));
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
while (true) {
op_t::kind_t kind = op_t::LAST;
parse_flags_t _flags = tflags;
token_t& tok = next_token(in, tflags);
@ -262,7 +269,7 @@ expr_t::parser_t::parse_logic_expr(std::istream& in,
break;
default:
push_token(tok);
break;
goto exit_loop;
}
if (kind != op_t::LAST) {
@ -282,7 +289,9 @@ expr_t::parser_t::parse_logic_expr(std::istream& in,
}
}
}
}
exit_loop:
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));
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
while (true) {
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::KW_AND) {
ptr_op_t prev(node);
node = new op_t(op_t::O_AND);
node->set_left(prev);
node->set_right(parse_and_expr(in, tflags));
node->set_right(parse_logic_expr(in, tflags));
if (! node->right())
throw_(parse_error,
tok.symbol << " operator not followed by argument");
} else {
push_token(tok);
break;
}
}
}
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));
if (node && ! tflags.has_flags(PARSE_SINGLE)) {
while (true) {
token_t& tok = next_token(in, tflags);
if (tok.kind == token_t::KW_OR) {
ptr_op_t prev(node);
node = new op_t(op_t::O_OR);
node->set_left(prev);
node->set_right(parse_or_expr(in, tflags));
node->set_right(parse_and_expr(in, tflags));
if (! node->right())
throw_(parse_error,
tok.symbol << " operator not followed by argument");
} else {
push_token(tok);
break;
}
}
}
return node;