expr.y 2.4 KB
Newer Older
1 2
/* Simple expression parser */
%{
J
Jiri Olsa 已提交
3 4
#define YYDEBUG 1
#include <stdio.h>
5 6
#include "util.h"
#include "util/debug.h"
7
#include <stdlib.h> // strtod()
8 9
#define IN_EXPR_Y 1
#include "expr.h"
10
#include "smt.h"
11 12
#include <string.h>

I
Ian Rogers 已提交
13 14 15 16 17 18 19 20
static double d_ratio(double val0, double val1)
{
	if (val1 == 0) {
		return 0;
	}
	return  val0 / val1;
}

21 22
%}

23 24
%define api.pure full

25
%parse-param { double *final_val }
26
%parse-param { struct expr_parse_ctx *ctx }
J
Jiri Olsa 已提交
27 28
%parse-param {void *scanner}
%lex-param {void* scanner}
29 30

%union {
J
Jiri Olsa 已提交
31 32
	double	 num;
	char	*str;
33 34
}

J
Jiri Olsa 已提交
35
%token EXPR_PARSE EXPR_OTHER EXPR_ERROR
36
%token <num> NUMBER
J
Jiri Olsa 已提交
37
%token <str> ID
38
%destructor { free ($$); } <str>
I
Ian Rogers 已提交
39
%token MIN MAX IF ELSE SMT_ON D_RATIO
40
%left MIN MAX IF
41 42 43
%left '|'
%left '^'
%left '&'
I
Ian Rogers 已提交
44
%left '<' '>'
45 46 47
%left '-' '+'
%left '*' '/' '%'
%left NEG NOT
48
%type <num> expr if_expr
49 50

%{
J
Jiri Olsa 已提交
51
static void expr_error(double *final_val __maybe_unused,
52
		       struct expr_parse_ctx *ctx __maybe_unused,
J
Jiri Olsa 已提交
53
		       void *scanner,
54 55 56 57 58 59 60 61
		       const char *s)
{
	pr_debug("%s\n", s);
}

%}
%%

J
Jiri Olsa 已提交
62 63 64 65 66 67 68 69 70 71
start:
EXPR_PARSE all_expr
|
EXPR_OTHER all_other

all_other: all_other other
|

other: ID
{
72
	expr__add_id_val(ctx, $1, 0.0);
J
Jiri Olsa 已提交
73 74
}
|
75
MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')' | ','
I
Ian Rogers 已提交
76
|
I
Ian Rogers 已提交
77
'<' | '>' | D_RATIO
J
Jiri Olsa 已提交
78

79 80 81 82 83 84
all_expr: if_expr			{ *final_val = $1; }
	;

if_expr:
	expr IF expr ELSE expr { $$ = $3 ? $1 : $5; }
	| expr
85 86 87
	;

expr:	  NUMBER
88
	| ID			{ if (expr__get_id(ctx, $1, &$$)) {
89
					pr_debug("%s not found\n", $1);
90
					free($1);
91 92
					YYABORT;
				  }
93
				  free($1);
94
				}
95 96 97
	| expr '|' expr		{ $$ = (long)$1 | (long)$3; }
	| expr '&' expr		{ $$ = (long)$1 & (long)$3; }
	| expr '^' expr		{ $$ = (long)$1 ^ (long)$3; }
I
Ian Rogers 已提交
98 99
	| expr '<' expr		{ $$ = $1 < $3; }
	| expr '>' expr		{ $$ = $1 > $3; }
100 101 102
	| expr '+' expr		{ $$ = $1 + $3; }
	| expr '-' expr		{ $$ = $1 - $3; }
	| expr '*' expr		{ $$ = $1 * $3; }
103 104 105 106 107 108 109 110 111 112 113 114
	| expr '/' expr		{ if ($3 == 0) {
					pr_debug("division by zero\n");
					YYABORT;
				  }
				  $$ = $1 / $3;
	                        }
	| expr '%' expr		{ if ((long)$3 == 0) {
					pr_debug("division by zero\n");
					YYABORT;
				  }
				  $$ = (long)$1 % (long)$3;
	                        }
115
	| '-' expr %prec NEG	{ $$ = -$2; }
116 117 118 119
	| '(' if_expr ')'	{ $$ = $2; }
	| MIN '(' expr ',' expr ')' { $$ = $3 < $5 ? $3 : $5; }
	| MAX '(' expr ',' expr ')' { $$ = $3 > $5 ? $3 : $5; }
	| SMT_ON		 { $$ = smt_on() > 0; }
I
Ian Rogers 已提交
120
	| D_RATIO '(' expr ',' expr ')' { $$ = d_ratio($3,$5); }
121 122 123
	;

%%