Merge tag 'block-5.9-2020-08-14' of git://git.kernel.dk/linux-block
[linux/fpc-iii.git] / tools / perf / util / expr.l
blob13e5e3c75f5630ce1be8f99921024cbb56c2ddf7
1 %option prefix="expr_"
2 %option reentrant
3 %option bison-bridge
5 %{
6 #include <linux/compiler.h>
7 #include "expr.h"
8 #include "expr-bison.h"
10 char *expr_get_text(yyscan_t yyscanner);
11 YYSTYPE *expr_get_lval(yyscan_t yyscanner);
13 static double __value(YYSTYPE *yylval, char *str, int token)
15         double num;
17         errno = 0;
18         num = strtod(str, NULL);
19         if (errno)
20                 return EXPR_ERROR;
22         yylval->num = num;
23         return token;
26 static int value(yyscan_t scanner)
28         YYSTYPE *yylval = expr_get_lval(scanner);
29         char *text = expr_get_text(scanner);
31         return __value(yylval, text, NUMBER);
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)
40         char *ret = str;
41         char *dst = str;
43         while (*str) {
44                 if (*str == '@')
45                         *dst++ = '/';
46                 else if (*str == '\\')
47                         *dst++ = *++str;
48                  else if (*str == '?') {
49                         char *paramval;
50                         int i = 0;
51                         int size = asprintf(&paramval, "%d", runtime);
53                         if (size < 0)
54                                 *dst++ = '0';
55                         else {
56                                 while (i < size)
57                                         *dst++ = paramval[i++];
58                                 free(paramval);
59                         }
60                 }
61                 else
62                         *dst++ = *str;
63                 str++;
64         }
66         *dst = 0x0;
67         return ret;
70 static int str(yyscan_t scanner, int token, int runtime)
72         YYSTYPE *yylval = expr_get_lval(scanner);
73         char *text = expr_get_text(scanner);
75         yylval->str = normalize(strdup(text), runtime);
76         if (!yylval->str)
77                 return EXPR_ERROR;
79         yylval->str = normalize(yylval->str, runtime);
80         return token;
84 number          ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+)
86 sch             [-,=]
87 spec            \\{sch}
88 sym             [0-9a-zA-Z_\.:@?]+
89 symbol          ({spec}|{sym})+
92         struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner);
94         {
95                 int start_token = sctx->start_token;
97                 if (sctx->start_token) {
98                         sctx->start_token = 0;
99                         return start_token;
100                 }
101         }
103 d_ratio         { return D_RATIO; }
104 max             { return MAX; }
105 min             { return MIN; }
106 if              { return IF; }
107 else            { return ELSE; }
108 #smt_on         { return SMT_ON; }
109 {number}        { return value(yyscanner); }
110 {symbol}        { return str(yyscanner, ID, sctx->runtime); }
111 "|"             { return '|'; }
112 "^"             { return '^'; }
113 "&"             { return '&'; }
114 "<"             { return '<'; }
115 ">"             { return '>'; }
116 "-"             { return '-'; }
117 "+"             { return '+'; }
118 "*"             { return '*'; }
119 "/"             { return '/'; }
120 "%"             { return '%'; }
121 "("             { return '('; }
122 ")"             { return ')'; }
123 ","             { return ','; }
124 .               { }
127 int expr_wrap(void *scanner __maybe_unused)
129         return 1;