expr.y (e80b500370e71b8cd7dd64be4080cee0a3e5068f) expr.y (4a4a9bf9075fbc753ab20f05347fd1482d4801e4)
1/* Simple expression parser */
2%{
3#define YYDEBUG 1
4#include <assert.h>
5#include <math.h>
6#include <stdlib.h>
7#include "util/debug.h"
8#define IN_EXPR_Y 1

--- 23 unchanged lines hidden (view full) ---

32 * creating ids the value is either a constant or BOTTOM. NAN is
33 * used as the special BOTTOM value, representing a "set of all
34 * values" case.
35 */
36 double val;
37 } ids;
38}
39
1/* Simple expression parser */
2%{
3#define YYDEBUG 1
4#include <assert.h>
5#include <math.h>
6#include <stdlib.h>
7#include "util/debug.h"
8#define IN_EXPR_Y 1

--- 23 unchanged lines hidden (view full) ---

32 * creating ids the value is either a constant or BOTTOM. NAN is
33 * used as the special BOTTOM value, representing a "set of all
34 * values" case.
35 */
36 double val;
37 } ids;
38}
39
40%token ID NUMBER MIN MAX IF ELSE LITERAL D_RATIO SOURCE_COUNT EXPR_ERROR
40%token ID NUMBER MIN MAX IF ELSE LITERAL D_RATIO SOURCE_COUNT HAS_EVENT EXPR_ERROR
41%left MIN MAX IF
42%left '|'
43%left '^'
44%left '&'
45%left '<' '>'
46%left '-' '+'
47%left '*' '/' '%'
48%left NEG NOT

--- 69 unchanged lines hidden (view full) ---

118 return result;
119}
120
121/*
122 * If we're not computing ids or $1 and $3 are constants, compute the new
123 * constant value using OP. Its invariant that there are no ids. If computing
124 * ids for non-constants union the set of IDs that must be computed.
125 */
41%left MIN MAX IF
42%left '|'
43%left '^'
44%left '&'
45%left '<' '>'
46%left '-' '+'
47%left '*' '/' '%'
48%left NEG NOT

--- 69 unchanged lines hidden (view full) ---

118 return result;
119}
120
121/*
122 * If we're not computing ids or $1 and $3 are constants, compute the new
123 * constant value using OP. Its invariant that there are no ids. If computing
124 * ids for non-constants union the set of IDs that must be computed.
125 */
126#define BINARY_LONG_OP(RESULT, OP, LHS, RHS) \
127 if (!compute_ids || (is_const(LHS.val) && is_const(RHS.val))) { \
128 assert(LHS.ids == NULL); \
129 assert(RHS.ids == NULL); \
130 if (isnan(LHS.val) || isnan(RHS.val)) { \
131 RESULT.val = NAN; \
132 } else { \
133 RESULT.val = (long)LHS.val OP (long)RHS.val; \
134 } \
135 RESULT.ids = NULL; \
136 } else { \
137 RESULT = union_expr(LHS, RHS); \
138 }
139
140#define BINARY_OP(RESULT, OP, LHS, RHS) \
141 if (!compute_ids || (is_const(LHS.val) && is_const(RHS.val))) { \
142 assert(LHS.ids == NULL); \
143 assert(RHS.ids == NULL); \
144 if (isnan(LHS.val) || isnan(RHS.val)) { \
145 RESULT.val = NAN; \
146 } else { \
147 RESULT.val = LHS.val OP RHS.val; \

--- 60 unchanged lines hidden (view full) ---

208
209expr: NUMBER
210{
211 $$.val = $1;
212 $$.ids = NULL;
213}
214| ID { $$ = handle_id(ctx, $1, compute_ids, /*source_count=*/false); }
215| SOURCE_COUNT '(' ID ')' { $$ = handle_id(ctx, $3, compute_ids, /*source_count=*/true); }
126#define BINARY_OP(RESULT, OP, LHS, RHS) \
127 if (!compute_ids || (is_const(LHS.val) && is_const(RHS.val))) { \
128 assert(LHS.ids == NULL); \
129 assert(RHS.ids == NULL); \
130 if (isnan(LHS.val) || isnan(RHS.val)) { \
131 RESULT.val = NAN; \
132 } else { \
133 RESULT.val = LHS.val OP RHS.val; \

--- 60 unchanged lines hidden (view full) ---

194
195expr: NUMBER
196{
197 $$.val = $1;
198 $$.ids = NULL;
199}
200| ID { $$ = handle_id(ctx, $1, compute_ids, /*source_count=*/false); }
201| SOURCE_COUNT '(' ID ')' { $$ = handle_id(ctx, $3, compute_ids, /*source_count=*/true); }
216| expr '|' expr { BINARY_LONG_OP($$, |, $1, $3); }
217| expr '&' expr { BINARY_LONG_OP($$, &, $1, $3); }
218| expr '^' expr { BINARY_LONG_OP($$, ^, $1, $3); }
202| HAS_EVENT '(' ID ')'
203{
204 $$.val = expr__has_event(ctx, compute_ids, $3);
205 $$.ids = NULL;
206 free($3);
207}
208| expr '|' expr
209{
210 if (is_const($1.val) && is_const($3.val)) {
211 assert($1.ids == NULL);
212 assert($3.ids == NULL);
213 $$.ids = NULL;
214 $$.val = (fpclassify($1.val) == FP_ZERO && fpclassify($3.val) == FP_ZERO) ? 0 : 1;
215 } else if (is_const($1.val)) {
216 assert($1.ids == NULL);
217 if (fpclassify($1.val) == FP_ZERO) {
218 $$ = $3;
219 } else {
220 $$.val = 1;
221 $$.ids = NULL;
222 ids__free($3.ids);
223 }
224 } else if (is_const($3.val)) {
225 assert($3.ids == NULL);
226 if (fpclassify($3.val) == FP_ZERO) {
227 $$ = $1;
228 } else {
229 $$.val = 1;
230 $$.ids = NULL;
231 ids__free($1.ids);
232 }
233 } else {
234 $$ = union_expr($1, $3);
235 }
236}
237| expr '&' expr
238{
239 if (is_const($1.val) && is_const($3.val)) {
240 assert($1.ids == NULL);
241 assert($3.ids == NULL);
242 $$.val = (fpclassify($1.val) != FP_ZERO && fpclassify($3.val) != FP_ZERO) ? 1 : 0;
243 $$.ids = NULL;
244 } else if (is_const($1.val)) {
245 assert($1.ids == NULL);
246 if (fpclassify($1.val) != FP_ZERO) {
247 $$ = $3;
248 } else {
249 $$.val = 0;
250 $$.ids = NULL;
251 ids__free($3.ids);
252 }
253 } else if (is_const($3.val)) {
254 assert($3.ids == NULL);
255 if (fpclassify($3.val) != FP_ZERO) {
256 $$ = $1;
257 } else {
258 $$.val = 0;
259 $$.ids = NULL;
260 ids__free($1.ids);
261 }
262 } else {
263 $$ = union_expr($1, $3);
264 }
265}
266| expr '^' expr
267{
268 if (is_const($1.val) && is_const($3.val)) {
269 assert($1.ids == NULL);
270 assert($3.ids == NULL);
271 $$.val = (fpclassify($1.val) == FP_ZERO) != (fpclassify($3.val) == FP_ZERO) ? 1 : 0;
272 $$.ids = NULL;
273 } else {
274 $$ = union_expr($1, $3);
275 }
276}
219| expr '<' expr { BINARY_OP($$, <, $1, $3); }
220| expr '>' expr { BINARY_OP($$, >, $1, $3); }
221| expr '+' expr { BINARY_OP($$, +, $1, $3); }
222| expr '-' expr { BINARY_OP($$, -, $1, $3); }
223| expr '*' expr { BINARY_OP($$, *, $1, $3); }
224| expr '/' expr
225{
226 if (fpclassify($3.val) == FP_ZERO) {

--- 87 unchanged lines hidden ---
277| expr '<' expr { BINARY_OP($$, <, $1, $3); }
278| expr '>' expr { BINARY_OP($$, >, $1, $3); }
279| expr '+' expr { BINARY_OP($$, +, $1, $3); }
280| expr '-' expr { BINARY_OP($$, -, $1, $3); }
281| expr '*' expr { BINARY_OP($$, *, $1, $3); }
282| expr '/' expr
283{
284 if (fpclassify($3.val) == FP_ZERO) {

--- 87 unchanged lines hidden ---