xref: /openbmc/linux/tools/perf/util/expr.l (revision c4a11bf4)
1 %option prefix="expr_"
2 %option reentrant
3 %option bison-bridge
4 
5 %{
6 #include <linux/compiler.h>
7 #include "expr.h"
8 #include "expr-bison.h"
9 
10 char *expr_get_text(yyscan_t yyscanner);
11 YYSTYPE *expr_get_lval(yyscan_t yyscanner);
12 
13 static double __value(YYSTYPE *yylval, char *str, int token)
14 {
15 	double num;
16 
17 	errno = 0;
18 	num = strtod(str, NULL);
19 	if (errno)
20 		return EXPR_ERROR;
21 
22 	yylval->num = num;
23 	return token;
24 }
25 
26 static int value(yyscan_t scanner)
27 {
28 	YYSTYPE *yylval = expr_get_lval(scanner);
29 	char *text = expr_get_text(scanner);
30 
31 	return __value(yylval, text, NUMBER);
32 }
33 
34 /*
35  * Allow @ instead of / to be able to specify pmu/event/ without
36  * conflicts with normal division.
37  */
38 static char *normalize(char *str, int runtime)
39 {
40 	char *ret = str;
41 	char *dst = str;
42 
43 	while (*str) {
44 		if (*str == '\\')
45 			*dst++ = *++str;
46 		else if (*str == '?') {
47 			char *paramval;
48 			int i = 0;
49 			int size = asprintf(&paramval, "%d", runtime);
50 
51 			if (size < 0)
52 				*dst++ = '0';
53 			else {
54 				while (i < size)
55 					*dst++ = paramval[i++];
56 				free(paramval);
57 			}
58 		}
59 		else
60 			*dst++ = *str;
61 		str++;
62 	}
63 
64 	*dst = 0x0;
65 	return ret;
66 }
67 
68 static int str(yyscan_t scanner, int token, int runtime)
69 {
70 	YYSTYPE *yylval = expr_get_lval(scanner);
71 	char *text = expr_get_text(scanner);
72 
73 	yylval->str = normalize(strdup(text), runtime);
74 	if (!yylval->str)
75 		return EXPR_ERROR;
76 
77 	yylval->str = normalize(yylval->str, runtime);
78 	return token;
79 }
80 %}
81 
82 number		([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+)
83 
84 sch		[-,=]
85 spec		\\{sch}
86 sym		[0-9a-zA-Z_\.:@?]+
87 symbol		({spec}|{sym})+
88 
89 %%
90 	struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
91 
92 d_ratio		{ return D_RATIO; }
93 max		{ return MAX; }
94 min		{ return MIN; }
95 if		{ return IF; }
96 else		{ return ELSE; }
97 #smt_on		{ return SMT_ON; }
98 {number}	{ return value(yyscanner); }
99 {symbol}	{ return str(yyscanner, ID, sctx->runtime); }
100 "|"		{ return '|'; }
101 "^"		{ return '^'; }
102 "&"		{ return '&'; }
103 "<"		{ return '<'; }
104 ">"		{ return '>'; }
105 "-"		{ return '-'; }
106 "+"		{ return '+'; }
107 "*"		{ return '*'; }
108 "/"		{ return '/'; }
109 "%"		{ return '%'; }
110 "("		{ return '('; }
111 ")"		{ return ')'; }
112 ","		{ return ','; }
113 .		{ }
114 %%
115 
116 int expr_wrap(void *scanner __maybe_unused)
117 {
118 	return 1;
119 }
120