xref: /linux-6.15/tools/perf/util/expr.l (revision 871f9f59)
126226a97SJiri Olsa %option prefix="expr_"
226226a97SJiri Olsa %option reentrant
326226a97SJiri Olsa %option bison-bridge
426226a97SJiri Olsa 
526226a97SJiri Olsa %{
626226a97SJiri Olsa #include <linux/compiler.h>
726226a97SJiri Olsa #include "expr.h"
826226a97SJiri Olsa #include "expr-bison.h"
926226a97SJiri Olsa 
1026226a97SJiri Olsa char *expr_get_text(yyscan_t yyscanner);
1126226a97SJiri Olsa YYSTYPE *expr_get_lval(yyscan_t yyscanner);
1226226a97SJiri Olsa 
1326226a97SJiri Olsa static int __value(YYSTYPE *yylval, char *str, int base, int token)
1426226a97SJiri Olsa {
1526226a97SJiri Olsa 	u64 num;
1626226a97SJiri Olsa 
1726226a97SJiri Olsa 	errno = 0;
1826226a97SJiri Olsa 	num = strtoull(str, NULL, base);
1926226a97SJiri Olsa 	if (errno)
2026226a97SJiri Olsa 		return EXPR_ERROR;
2126226a97SJiri Olsa 
2226226a97SJiri Olsa 	yylval->num = num;
2326226a97SJiri Olsa 	return token;
2426226a97SJiri Olsa }
2526226a97SJiri Olsa 
2626226a97SJiri Olsa static int value(yyscan_t scanner, int base)
2726226a97SJiri Olsa {
2826226a97SJiri Olsa 	YYSTYPE *yylval = expr_get_lval(scanner);
2926226a97SJiri Olsa 	char *text = expr_get_text(scanner);
3026226a97SJiri Olsa 
3126226a97SJiri Olsa 	return __value(yylval, text, base, NUMBER);
3226226a97SJiri Olsa }
3326226a97SJiri Olsa 
3426226a97SJiri Olsa /*
3526226a97SJiri Olsa  * Allow @ instead of / to be able to specify pmu/event/ without
3626226a97SJiri Olsa  * conflicts with normal division.
3726226a97SJiri Olsa  */
3826226a97SJiri Olsa static char *normalize(char *str)
3926226a97SJiri Olsa {
4026226a97SJiri Olsa 	char *ret = str;
4126226a97SJiri Olsa 	char *dst = str;
4226226a97SJiri Olsa 
4326226a97SJiri Olsa 	while (*str) {
4426226a97SJiri Olsa 		if (*str == '@')
4526226a97SJiri Olsa 			*dst++ = '/';
4626226a97SJiri Olsa 		else if (*str == '\\')
4726226a97SJiri Olsa 			*dst++ = *++str;
4826226a97SJiri Olsa 		else
4926226a97SJiri Olsa 			*dst++ = *str;
5026226a97SJiri Olsa 		str++;
5126226a97SJiri Olsa 	}
5226226a97SJiri Olsa 
5326226a97SJiri Olsa 	*dst = 0x0;
5426226a97SJiri Olsa 	return ret;
5526226a97SJiri Olsa }
5626226a97SJiri Olsa 
5726226a97SJiri Olsa static int str(yyscan_t scanner, int token)
5826226a97SJiri Olsa {
5926226a97SJiri Olsa 	YYSTYPE *yylval = expr_get_lval(scanner);
6026226a97SJiri Olsa 	char *text = expr_get_text(scanner);
6126226a97SJiri Olsa 
6226226a97SJiri Olsa 	yylval->str = normalize(strdup(text));
6326226a97SJiri Olsa 	if (!yylval->str)
6426226a97SJiri Olsa 		return EXPR_ERROR;
6526226a97SJiri Olsa 
6626226a97SJiri Olsa 	yylval->str = normalize(yylval->str);
6726226a97SJiri Olsa 	return token;
6826226a97SJiri Olsa }
6926226a97SJiri Olsa %}
7026226a97SJiri Olsa 
7126226a97SJiri Olsa number		[0-9]+
7226226a97SJiri Olsa 
7326226a97SJiri Olsa sch		[-,=]
7426226a97SJiri Olsa spec		\\{sch}
7526226a97SJiri Olsa sym		[0-9a-zA-Z_\.:@]+
7626226a97SJiri Olsa symbol		{spec}*{sym}*{spec}*{sym}*
7726226a97SJiri Olsa 
7826226a97SJiri Olsa %%
79*871f9f59SJiri Olsa 	struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
80*871f9f59SJiri Olsa 
8126226a97SJiri Olsa 	{
82*871f9f59SJiri Olsa 		int start_token = sctx->start_token;
8326226a97SJiri Olsa 
84*871f9f59SJiri Olsa 		if (sctx->start_token) {
85*871f9f59SJiri Olsa 			sctx->start_token = 0;
8626226a97SJiri Olsa 			return start_token;
8726226a97SJiri Olsa 		}
8826226a97SJiri Olsa 	}
8926226a97SJiri Olsa 
9026226a97SJiri Olsa max		{ return MAX; }
9126226a97SJiri Olsa min		{ return MIN; }
9226226a97SJiri Olsa if		{ return IF; }
9326226a97SJiri Olsa else		{ return ELSE; }
9426226a97SJiri Olsa #smt_on		{ return SMT_ON; }
9526226a97SJiri Olsa {number}	{ return value(yyscanner, 10); }
9626226a97SJiri Olsa {symbol}	{ return str(yyscanner, ID); }
9726226a97SJiri Olsa "|"		{ return '|'; }
9826226a97SJiri Olsa "^"		{ return '^'; }
9926226a97SJiri Olsa "&"		{ return '&'; }
10026226a97SJiri Olsa "-"		{ return '-'; }
10126226a97SJiri Olsa "+"		{ return '+'; }
10226226a97SJiri Olsa "*"		{ return '*'; }
10326226a97SJiri Olsa "/"		{ return '/'; }
10426226a97SJiri Olsa "%"		{ return '%'; }
10526226a97SJiri Olsa "("		{ return '('; }
10626226a97SJiri Olsa ")"		{ return ')'; }
10726226a97SJiri Olsa ","		{ return ','; }
10826226a97SJiri Olsa .		{ }
10926226a97SJiri Olsa %%
11026226a97SJiri Olsa 
11126226a97SJiri Olsa int expr_wrap(void *scanner __maybe_unused)
11226226a97SJiri Olsa {
11326226a97SJiri Olsa 	return 1;
11426226a97SJiri Olsa }
115