mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-14 05:06:13 +07:00
26226a9772
Adding expr flex code instead of the manual parser code. So it's easily extensible in upcoming changes. The new flex code is in flex.l object and gets compiled like all the other flexers we use. It's defined as flex reentrant parser. It's used by both expr__parse and expr__find_other interfaces by separating the starting point. There's no intended change of functionality ;-) the test expr is passing. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Reviewed-by: Andi Kleen <ak@linux.intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: John Garry <john.garry@huawei.com> Cc: Kajol Jain <kjain@linux.ibm.com> Cc: Michael Petlan <mpetlan@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com> Link: http://lore.kernel.org/lkml/20200228093616.67125-3-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
115 lines
1.9 KiB
Plaintext
115 lines
1.9 KiB
Plaintext
%option prefix="expr_"
|
|
%option reentrant
|
|
%option bison-bridge
|
|
|
|
%{
|
|
#include <linux/compiler.h>
|
|
#include "expr.h"
|
|
#include "expr-bison.h"
|
|
|
|
char *expr_get_text(yyscan_t yyscanner);
|
|
YYSTYPE *expr_get_lval(yyscan_t yyscanner);
|
|
|
|
static int __value(YYSTYPE *yylval, char *str, int base, int token)
|
|
{
|
|
u64 num;
|
|
|
|
errno = 0;
|
|
num = strtoull(str, NULL, base);
|
|
if (errno)
|
|
return EXPR_ERROR;
|
|
|
|
yylval->num = num;
|
|
return token;
|
|
}
|
|
|
|
static int value(yyscan_t scanner, int base)
|
|
{
|
|
YYSTYPE *yylval = expr_get_lval(scanner);
|
|
char *text = expr_get_text(scanner);
|
|
|
|
return __value(yylval, text, base, NUMBER);
|
|
}
|
|
|
|
/*
|
|
* Allow @ instead of / to be able to specify pmu/event/ without
|
|
* conflicts with normal division.
|
|
*/
|
|
static char *normalize(char *str)
|
|
{
|
|
char *ret = str;
|
|
char *dst = str;
|
|
|
|
while (*str) {
|
|
if (*str == '@')
|
|
*dst++ = '/';
|
|
else if (*str == '\\')
|
|
*dst++ = *++str;
|
|
else
|
|
*dst++ = *str;
|
|
str++;
|
|
}
|
|
|
|
*dst = 0x0;
|
|
return ret;
|
|
}
|
|
|
|
static int str(yyscan_t scanner, int token)
|
|
{
|
|
YYSTYPE *yylval = expr_get_lval(scanner);
|
|
char *text = expr_get_text(scanner);
|
|
|
|
yylval->str = normalize(strdup(text));
|
|
if (!yylval->str)
|
|
return EXPR_ERROR;
|
|
|
|
yylval->str = normalize(yylval->str);
|
|
return token;
|
|
}
|
|
%}
|
|
|
|
number [0-9]+
|
|
|
|
sch [-,=]
|
|
spec \\{sch}
|
|
sym [0-9a-zA-Z_\.:@]+
|
|
symbol {spec}*{sym}*{spec}*{sym}*
|
|
|
|
%%
|
|
{
|
|
int start_token;
|
|
|
|
start_token = parse_events_get_extra(yyscanner);
|
|
|
|
if (start_token) {
|
|
parse_events_set_extra(NULL, yyscanner);
|
|
return start_token;
|
|
}
|
|
}
|
|
|
|
max { return MAX; }
|
|
min { return MIN; }
|
|
if { return IF; }
|
|
else { return ELSE; }
|
|
#smt_on { return SMT_ON; }
|
|
{number} { return value(yyscanner, 10); }
|
|
{symbol} { return str(yyscanner, ID); }
|
|
"|" { return '|'; }
|
|
"^" { return '^'; }
|
|
"&" { return '&'; }
|
|
"-" { return '-'; }
|
|
"+" { return '+'; }
|
|
"*" { return '*'; }
|
|
"/" { return '/'; }
|
|
"%" { return '%'; }
|
|
"(" { return '('; }
|
|
")" { return ')'; }
|
|
"," { return ','; }
|
|
. { }
|
|
%%
|
|
|
|
int expr_wrap(void *scanner __maybe_unused)
|
|
{
|
|
return 1;
|
|
}
|