Commit | Line | Data |
---|---|---|
07516736 AK |
1 | /* Simple expression parser */ |
2 | %{ | |
26226a97 | 3 | #define YYDEBUG 1 |
edfe7f55 | 4 | #include <math.h> |
07516736 | 5 | #include "util/debug.h" |
7f8fdcbb | 6 | #include "smt.h" |
07516736 AK |
7 | #define IN_EXPR_Y 1 |
8 | #include "expr.h" | |
07516736 AK |
9 | %} |
10 | ||
fc8c0a99 JO |
11 | %define api.pure full |
12 | ||
07516736 | 13 | %parse-param { double *final_val } |
aecce63e | 14 | %parse-param { struct expr_parse_ctx *ctx } |
26226a97 JO |
15 | %parse-param {void *scanner} |
16 | %lex-param {void* scanner} | |
07516736 AK |
17 | |
18 | %union { | |
26226a97 JO |
19 | double num; |
20 | char *str; | |
07516736 AK |
21 | } |
22 | ||
aed0d6f8 | 23 | %token ID NUMBER MIN MAX IF ELSE SMT_ON D_RATIO EXPR_ERROR EXPR_PARSE EXPR_OTHER |
d73bad06 | 24 | %left MIN MAX IF |
07516736 AK |
25 | %left '|' |
26 | %left '^' | |
27 | %left '&' | |
ff1a12f9 | 28 | %left '<' '>' |
07516736 AK |
29 | %left '-' '+' |
30 | %left '*' '/' '%' | |
31 | %left NEG NOT | |
aed0d6f8 IR |
32 | %type <num> NUMBER |
33 | %type <str> ID | |
34 | %destructor { free ($$); } <str> | |
d73bad06 | 35 | %type <num> expr if_expr |
07516736 AK |
36 | |
37 | %{ | |
26226a97 | 38 | static void expr_error(double *final_val __maybe_unused, |
aecce63e | 39 | struct expr_parse_ctx *ctx __maybe_unused, |
26226a97 | 40 | void *scanner, |
07516736 AK |
41 | const char *s) |
42 | { | |
43 | pr_debug("%s\n", s); | |
44 | } | |
45 | ||
07516736 AK |
46 | %} |
47 | %% | |
48 | ||
26226a97 JO |
49 | start: |
50 | EXPR_PARSE all_expr | |
51 | | | |
52 | EXPR_OTHER all_other | |
53 | ||
54 | all_other: all_other other | |
55 | | | |
56 | ||
57 | other: ID | |
58 | { | |
332603c2 | 59 | expr__add_id(ctx, $1); |
26226a97 JO |
60 | } |
61 | | | |
cb59fa79 | 62 | MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')' | ',' |
3e21a28a | 63 | | |
ff1a12f9 | 64 | '<' | '>' | D_RATIO |
26226a97 | 65 | |
d73bad06 AK |
66 | all_expr: if_expr { *final_val = $1; } |
67 | ; | |
68 | ||
69 | if_expr: | |
70 | expr IF expr ELSE expr { $$ = $3 ? $1 : $5; } | |
71 | | expr | |
07516736 AK |
72 | ; |
73 | ||
74 | expr: NUMBER | |
5c5f5e83 JO |
75 | | ID { |
76 | struct expr_id_data *data; | |
77 | ||
edfe7f55 IR |
78 | $$ = NAN; |
79 | if (expr__resolve_id(ctx, $1, &data) == 0) | |
80 | $$ = expr_id_data__value(data); | |
acf71b05 | 81 | |
63657578 | 82 | free($1); |
07516736 | 83 | } |
d73bad06 AK |
84 | | expr '|' expr { $$ = (long)$1 | (long)$3; } |
85 | | expr '&' expr { $$ = (long)$1 & (long)$3; } | |
86 | | expr '^' expr { $$ = (long)$1 ^ (long)$3; } | |
ff1a12f9 IR |
87 | | expr '<' expr { $$ = $1 < $3; } |
88 | | expr '>' expr { $$ = $1 > $3; } | |
07516736 AK |
89 | | expr '+' expr { $$ = $1 + $3; } |
90 | | expr '-' expr { $$ = $1 - $3; } | |
91 | | expr '*' expr { $$ = $1 * $3; } | |
9be27a5d IR |
92 | | expr '/' expr { if ($3 == 0) { |
93 | pr_debug("division by zero\n"); | |
94 | YYABORT; | |
95 | } | |
96 | $$ = $1 / $3; | |
97 | } | |
98 | | expr '%' expr { if ((long)$3 == 0) { | |
99 | pr_debug("division by zero\n"); | |
100 | YYABORT; | |
101 | } | |
102 | $$ = (long)$1 % (long)$3; | |
103 | } | |
07516736 | 104 | | '-' expr %prec NEG { $$ = -$2; } |
d73bad06 AK |
105 | | '(' if_expr ')' { $$ = $2; } |
106 | | MIN '(' expr ',' expr ')' { $$ = $3 < $5 ? $3 : $5; } | |
107 | | MAX '(' expr ',' expr ')' { $$ = $3 > $5 ? $3 : $5; } | |
108 | | SMT_ON { $$ = smt_on() > 0; } | |
7f8fdcbb IR |
109 | | D_RATIO '(' expr ',' expr ')' { if ($5 == 0) { |
110 | $$ = 0; | |
111 | } else { | |
112 | $$ = $3 / $5; | |
113 | } | |
114 | } | |
07516736 AK |
115 | ; |
116 | ||
117 | %% |