xref: /openbmc/linux/tools/perf/util/expr.l (revision 165f2d28)
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 int __value(YYSTYPE *yylval, char *str, int base, int token)
14 {
15 	u64 num;
16 
17 	errno = 0;
18 	num = strtoull(str, NULL, base);
19 	if (errno)
20 		return EXPR_ERROR;
21 
22 	yylval->num = num;
23 	return token;
24 }
25 
26 static int value(yyscan_t scanner, int base)
27 {
28 	YYSTYPE *yylval = expr_get_lval(scanner);
29 	char *text = expr_get_text(scanner);
30 
31 	return __value(yylval, text, base, 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)
39 {
40 	char *ret = str;
41 	char *dst = str;
42 
43 	while (*str) {
44 		if (*str == '@')
45 			*dst++ = '/';
46 		else if (*str == '\\')
47 			*dst++ = *++str;
48 		else
49 			*dst++ = *str;
50 		str++;
51 	}
52 
53 	*dst = 0x0;
54 	return ret;
55 }
56 
57 static int str(yyscan_t scanner, int token)
58 {
59 	YYSTYPE *yylval = expr_get_lval(scanner);
60 	char *text = expr_get_text(scanner);
61 
62 	yylval->str = normalize(strdup(text));
63 	if (!yylval->str)
64 		return EXPR_ERROR;
65 
66 	yylval->str = normalize(yylval->str);
67 	return token;
68 }
69 %}
70 
71 number		[0-9]+
72 
73 sch		[-,=]
74 spec		\\{sch}
75 sym		[0-9a-zA-Z_\.:@]+
76 symbol		{spec}*{sym}*{spec}*{sym}*
77 
78 %%
79 	{
80 		int start_token;
81 
82 		start_token = expr_get_extra(yyscanner);
83 
84 		if (start_token) {
85 			expr_set_extra(NULL, yyscanner);
86 			return start_token;
87 		}
88 	}
89 
90 max		{ return MAX; }
91 min		{ return MIN; }
92 if		{ return IF; }
93 else		{ return ELSE; }
94 #smt_on		{ return SMT_ON; }
95 {number}	{ return value(yyscanner, 10); }
96 {symbol}	{ return str(yyscanner, ID); }
97 "|"		{ return '|'; }
98 "^"		{ return '^'; }
99 "&"		{ return '&'; }
100 "-"		{ return '-'; }
101 "+"		{ return '+'; }
102 "*"		{ return '*'; }
103 "/"		{ return '/'; }
104 "%"		{ return '%'; }
105 "("		{ return '('; }
106 ")"		{ return ')'; }
107 ","		{ return ','; }
108 .		{ }
109 %%
110 
111 int expr_wrap(void *scanner __maybe_unused)
112 {
113 	return 1;
114 }
115