1928f2a3dddc56159b16bfab90d31ff0edcfe044
[linux-2.6-microblaze.git] / tools / perf / util / expr.l
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 = parse_events_get_extra(yyscanner);
83
84                 if (start_token) {
85                         parse_events_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 }