]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - tools/perf/util/parse-events.y
perf/tool: Make the event parser re-entrant
[mirror_ubuntu-artful-kernel.git] / tools / perf / util / parse-events.y
1 %pure-parser
2 %name-prefix "parse_events_"
3 %parse-param {void *_data}
4 %parse-param {void *scanner}
5 %lex-param {void* scanner}
6
7 %{
8
9 #define YYDEBUG 1
10
11 #include <linux/compiler.h>
12 #include <linux/list.h>
13 #include "types.h"
14 #include "util.h"
15 #include "parse-events.h"
16 #include "parse-events-bison.h"
17
18 extern int parse_events_lex (YYSTYPE* lvalp, void* scanner);
19
20 #define ABORT_ON(val) \
21 do { \
22 if (val) \
23 YYABORT; \
24 } while (0)
25
26 %}
27
28 %token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM
29 %token PE_NAME
30 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
31 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
32 %token PE_PREFIX_MEM PE_PREFIX_RAW
33 %token PE_ERROR
34 %type <num> PE_VALUE
35 %type <num> PE_VALUE_SYM
36 %type <num> PE_RAW
37 %type <num> PE_TERM
38 %type <str> PE_NAME
39 %type <str> PE_NAME_CACHE_TYPE
40 %type <str> PE_NAME_CACHE_OP_RESULT
41 %type <str> PE_MODIFIER_EVENT
42 %type <str> PE_MODIFIER_BP
43 %type <head> event_config
44 %type <term> event_term
45 %type <head> event_pmu
46 %type <head> event_legacy_symbol
47 %type <head> event_legacy_cache
48 %type <head> event_legacy_mem
49 %type <head> event_legacy_tracepoint
50 %type <head> event_legacy_numeric
51 %type <head> event_legacy_raw
52 %type <head> event_def
53
54 %union
55 {
56 char *str;
57 unsigned long num;
58 struct list_head *head;
59 struct parse_events__term *term;
60 }
61 %%
62
63 events:
64 events ',' event | event
65
66 event:
67 event_def PE_MODIFIER_EVENT
68 {
69 struct parse_events_data__events *data = _data;
70
71 /*
72 * Apply modifier on all events added by single event definition
73 * (there could be more events added for multiple tracepoint
74 * definitions via '*?'.
75 */
76 ABORT_ON(parse_events_modifier($1, $2));
77 parse_events_update_lists($1, &data->list);
78 }
79 |
80 event_def
81 {
82 struct parse_events_data__events *data = _data;
83
84 parse_events_update_lists($1, &data->list);
85 }
86
87 event_def: event_pmu |
88 event_legacy_symbol |
89 event_legacy_cache sep_dc |
90 event_legacy_mem |
91 event_legacy_tracepoint sep_dc |
92 event_legacy_numeric sep_dc |
93 event_legacy_raw sep_dc
94
95 event_pmu:
96 PE_NAME '/' event_config '/'
97 {
98 struct parse_events_data__events *data = _data;
99 struct list_head *list = NULL;
100
101 ABORT_ON(parse_events_add_pmu(&list, &data->idx, $1, $3));
102 parse_events__free_terms($3);
103 $$ = list;
104 }
105
106 event_legacy_symbol:
107 PE_VALUE_SYM '/' event_config '/'
108 {
109 struct parse_events_data__events *data = _data;
110 struct list_head *list = NULL;
111 int type = $1 >> 16;
112 int config = $1 & 255;
113
114 ABORT_ON(parse_events_add_numeric(&list, &data->idx,
115 type, config, $3));
116 parse_events__free_terms($3);
117 $$ = list;
118 }
119 |
120 PE_VALUE_SYM sep_slash_dc
121 {
122 struct parse_events_data__events *data = _data;
123 struct list_head *list = NULL;
124 int type = $1 >> 16;
125 int config = $1 & 255;
126
127 ABORT_ON(parse_events_add_numeric(&list, &data->idx,
128 type, config, NULL));
129 $$ = list;
130 }
131
132 event_legacy_cache:
133 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
134 {
135 struct parse_events_data__events *data = _data;
136 struct list_head *list = NULL;
137
138 ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, $5));
139 $$ = list;
140 }
141 |
142 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
143 {
144 struct parse_events_data__events *data = _data;
145 struct list_head *list = NULL;
146
147 ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, NULL));
148 $$ = list;
149 }
150 |
151 PE_NAME_CACHE_TYPE
152 {
153 struct parse_events_data__events *data = _data;
154 struct list_head *list = NULL;
155
156 ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, NULL, NULL));
157 $$ = list;
158 }
159
160 event_legacy_mem:
161 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
162 {
163 struct parse_events_data__events *data = _data;
164 struct list_head *list = NULL;
165
166 ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
167 (void *) $2, $4));
168 $$ = list;
169 }
170 |
171 PE_PREFIX_MEM PE_VALUE sep_dc
172 {
173 struct parse_events_data__events *data = _data;
174 struct list_head *list = NULL;
175
176 ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
177 (void *) $2, NULL));
178 $$ = list;
179 }
180
181 event_legacy_tracepoint:
182 PE_NAME ':' PE_NAME
183 {
184 struct parse_events_data__events *data = _data;
185 struct list_head *list = NULL;
186
187 ABORT_ON(parse_events_add_tracepoint(&list, &data->idx, $1, $3));
188 $$ = list;
189 }
190
191 event_legacy_numeric:
192 PE_VALUE ':' PE_VALUE
193 {
194 struct parse_events_data__events *data = _data;
195 struct list_head *list = NULL;
196
197 ABORT_ON(parse_events_add_numeric(&list, &data->idx, $1, $3, NULL));
198 $$ = list;
199 }
200
201 event_legacy_raw:
202 PE_RAW
203 {
204 struct parse_events_data__events *data = _data;
205 struct list_head *list = NULL;
206
207 ABORT_ON(parse_events_add_numeric(&list, &data->idx,
208 PERF_TYPE_RAW, $1, NULL));
209 $$ = list;
210 }
211
212 event_config:
213 event_config ',' event_term
214 {
215 struct list_head *head = $1;
216 struct parse_events__term *term = $3;
217
218 ABORT_ON(!head);
219 list_add_tail(&term->list, head);
220 $$ = $1;
221 }
222 |
223 event_term
224 {
225 struct list_head *head = malloc(sizeof(*head));
226 struct parse_events__term *term = $1;
227
228 ABORT_ON(!head);
229 INIT_LIST_HEAD(head);
230 list_add_tail(&term->list, head);
231 $$ = head;
232 }
233
234 event_term:
235 PE_NAME '=' PE_NAME
236 {
237 struct parse_events__term *term;
238
239 ABORT_ON(parse_events__term_str(&term, PARSE_EVENTS__TERM_TYPE_USER,
240 $1, $3));
241 $$ = term;
242 }
243 |
244 PE_NAME '=' PE_VALUE
245 {
246 struct parse_events__term *term;
247
248 ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER,
249 $1, $3));
250 $$ = term;
251 }
252 |
253 PE_NAME
254 {
255 struct parse_events__term *term;
256
257 ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER,
258 $1, 1));
259 $$ = term;
260 }
261 |
262 PE_TERM '=' PE_NAME
263 {
264 struct parse_events__term *term;
265
266 ABORT_ON(parse_events__term_str(&term, $1, NULL, $3));
267 $$ = term;
268 }
269 |
270 PE_TERM '=' PE_VALUE
271 {
272 struct parse_events__term *term;
273
274 ABORT_ON(parse_events__term_num(&term, $1, NULL, $3));
275 $$ = term;
276 }
277 |
278 PE_TERM
279 {
280 struct parse_events__term *term;
281
282 ABORT_ON(parse_events__term_num(&term, $1, NULL, 1));
283 $$ = term;
284 }
285
286 sep_dc: ':' |
287
288 sep_slash_dc: '/' | ':' |
289
290 %%
291
292 void parse_events_error(void *data __used, void *scanner __used,
293 char const *msg __used)
294 {
295 }