The parsnip library looks nice, but I am unable two combine two types.
At this moment I have the calculator, allowing numeric expressions.
I also made a bool calculator, allowing boolean expressions.
But what I want to do is something like:
if (4*2>8)||(4/2<6)
the tricky point is in the < or the > operator. The prototype for those functions is something like
"bool greater(int, int)", and when used in a op_table()->infix_left(.) a function is expected with the same return type as the arguments.
How can I solve this?
Jaap
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
First implement a expr_num, in the same way as in the sample in the original sources.
Then implement a expr_bool, supporting && || == !=
But for the term_bool do the following:
You would also need to add these functions outside main:
---------------------------------------------------
bool logical_or (bool p, bool q) { return p || q; }
bool logical_and(bool p, bool q) { return p && q; }
bool greater(double x, double y) { return x > y; }
bool less(double x, double y) { return x < y; }
---------------------------------------------------
The main drawback to this approach is that you can't yet easily parse a prefix not operator. That's a limit of the OpTable parser that I plan on fixing in the future.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The parsnip library looks nice, but I am unable two combine two types.
At this moment I have the calculator, allowing numeric expressions.
I also made a bool calculator, allowing boolean expressions.
But what I want to do is something like:
if (4*2>8)||(4/2<6)
the tricky point is in the < or the > operator. The prototype for those functions is something like
"bool greater(int, int)", and when used in a op_table()->infix_left(.) a function is expected with the same return type as the arguments.
How can I solve this?
Jaap
Ok, I figured it out myself already:
First implement a expr_num, in the same way as in the sample in the original sources.
Then implement a expr_bool, supporting && || == !=
But for the term_bool do the following:
const StrParser num_operator = token(
str("==") | str("!=")|
str(">=") | str("<=")|
ch('>') | ch('<')
) >>= "num_operator";
BoolParser term_bool =
call0(fn_true, token_str("true")) |
call0(fn_false, token_str("false")) |
call3(fn_numcmp, expr_num >> num_operator >> expr_num) |
skip_ch('(') >> op_self_bool >> skip_ch(')')
;
where fn_numcmp is:
bool fn_numcmp(int x, std::string token, int y)
{
if (token == ">") return (x > y);
if (token == "<") return (x < y);
if (token == ">=") return (x >= y);
if (token == "<=") return (x <= y);
if (token == "==") return (x == y);
if (token == "!=") return (x != y);
return false;
}
it works perfect
Hi Jaap,
To cut down on string comparisons I would just use two optables.
--------------------------------------------------
BoolParser bool_term = skip_token_str("true") >> succeed(true) |
skip_token_str("false") >> succeed(false)|
call2(greater, expr >> skip_token_str(">") >> expr) |
call2(less, expr >> skip_token_str("<") >> expr);
BoolParser bool_ops = op_table(bool_term)
->infix_left("&&", 10, logical_and)
->infix_left("||", 10, logical_or);
BoolParser bool_expr = bool_ops | bool_term;
---------------------------------------------------
You would also need to add these functions outside main:
---------------------------------------------------
bool logical_or (bool p, bool q) { return p || q; }
bool logical_and(bool p, bool q) { return p && q; }
bool greater(double x, double y) { return x > y; }
bool less(double x, double y) { return x < y; }
---------------------------------------------------
The main drawback to this approach is that you can't yet easily parse a prefix not operator. That's a limit of the OpTable parser that I plan on fixing in the future.