1 /* Simple expression parser */
6 #include "util/debug.h"
7 #include <stdlib.h> // strtod()
17 %parse
-param
{ double *final_val
}
18 %parse
-param
{ struct parse_ctx
*ctx
}
19 %parse
-param
{void *scanner
}
20 %lex
-param
{void* scanner
}
27 %token EXPR_PARSE EXPR_OTHER EXPR_ERROR
30 %token MIN MAX IF ELSE SMT_ON
38 %type
<num
> expr if_expr
41 static void expr_error
(double *final_val __maybe_unused
,
42 struct parse_ctx
*ctx __maybe_unused
,
49 static int lookup_id
(struct parse_ctx
*ctx
, char *id
, double *val
)
53 for
(i
= 0; i
< ctx
->num_ids
; i
++) {
54 if
(!strcasecmp
(ctx
->ids
[i
].name
, id
)) {
55 *val
= ctx
->ids
[i
].val
;
70 all_other: all_other other
75 if
(ctx
->num_ids
+ 1 >= EXPR_MAX_OTHER
) {
76 pr_err
("failed: way too many variables");
80 ctx
->ids
[ctx
->num_ids
++].name
= $1;
83 MIN | MAX | IF | ELSE | SMT_ON | NUMBER |
'|' |
'^' |
'&' |
'-' |
'+' |
'*' |
'/' |
'%' |
'(' |
')'
86 all_expr: if_expr
{ *final_val
= $1; }
90 expr IF expr ELSE expr
{ $$
= $3 ?
$1 : $5; }
95 | ID
{ if
(lookup_id
(ctx
, $1, &$$
) < 0) {
96 pr_debug
("%s not found\n", $1);
100 | expr
'|' expr
{ $$
= (long)$1 |
(long)$3; }
101 | expr
'&' expr
{ $$
= (long)$1 & (long)$3; }
102 | expr
'^' expr
{ $$
= (long)$1 ^
(long)$3; }
103 | expr
'+' expr
{ $$
= $1 + $3; }
104 | expr
'-' expr
{ $$
= $1 - $3; }
105 | expr
'*' expr
{ $$
= $1 * $3; }
106 | expr
'/' expr
{ if
($3 == 0) YYABORT; $$
= $1 / $3; }
107 | expr
'%' expr
{ if
((long)$3 == 0) YYABORT; $$
= (long)$1 %
(long)$3; }
108 |
'-' expr %prec NEG
{ $$
= -$2; }
109 |
'(' if_expr
')' { $$
= $2; }
110 | MIN
'(' expr
',' expr
')' { $$
= $3 < $5 ?
$3 : $5; }
111 | MAX
'(' expr
',' expr
')' { $$
= $3 > $5 ?
$3 : $5; }
112 | SMT_ON
{ $$
= smt_on
() > 0; }