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