expr.y 2.3 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 44 45 46
%left '|'
%left '^'
%left '&'
%left '-' '+'
%left '*' '/' '%'
%left NEG NOT
47
%type <num> expr if_expr
48 49

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

%}
%%

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

all_other: all_other other
|

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

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

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

expr:	  NUMBER
87
	| ID			{ if (expr__get_id(ctx, $1, &$$)) {
88
					pr_debug("%s not found\n", $1);
89
					free($1);
90 91
					YYABORT;
				  }
92
				  free($1);
93
				}
94 95 96
	| expr '|' expr		{ $$ = (long)$1 | (long)$3; }
	| expr '&' expr		{ $$ = (long)$1 & (long)$3; }
	| expr '^' expr		{ $$ = (long)$1 ^ (long)$3; }
97 98 99
	| expr '+' expr		{ $$ = $1 + $3; }
	| expr '-' expr		{ $$ = $1 - $3; }
	| expr '*' expr		{ $$ = $1 * $3; }
100 101 102 103 104 105 106 107 108 109 110 111
	| 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;
	                        }
112
	| '-' expr %prec NEG	{ $$ = -$2; }
113 114 115 116
	| '(' 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 已提交
117
	| D_RATIO '(' expr ',' expr ')' { $$ = d_ratio($3,$5); }
118 119 120
	;

%%