xref: /openbmc/linux/tools/perf/util/parse-events.y (revision 861e10be)
1 %pure-parser
2 %parse-param {void *_data}
3 %parse-param {void *scanner}
4 %lex-param {void* scanner}
5 
6 %{
7 
8 #define YYDEBUG 1
9 
10 #include <linux/compiler.h>
11 #include <linux/list.h>
12 #include "types.h"
13 #include "util.h"
14 #include "parse-events.h"
15 #include "parse-events-bison.h"
16 
17 extern int parse_events_lex (YYSTYPE* lvalp, void* scanner);
18 
19 #define ABORT_ON(val) \
20 do { \
21 	if (val) \
22 		YYABORT; \
23 } while (0)
24 
25 static inc_group_count(struct list_head *list,
26 		       struct parse_events_evlist *data)
27 {
28 	/* Count groups only have more than 1 members */
29 	if (!list_is_last(list->next, list))
30 		data->nr_groups++;
31 }
32 
33 %}
34 
35 %token PE_START_EVENTS PE_START_TERMS
36 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
37 %token PE_EVENT_NAME
38 %token PE_NAME
39 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
40 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
41 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
42 %token PE_ERROR
43 %type <num> PE_VALUE
44 %type <num> PE_VALUE_SYM_HW
45 %type <num> PE_VALUE_SYM_SW
46 %type <num> PE_RAW
47 %type <num> PE_TERM
48 %type <str> PE_NAME
49 %type <str> PE_NAME_CACHE_TYPE
50 %type <str> PE_NAME_CACHE_OP_RESULT
51 %type <str> PE_MODIFIER_EVENT
52 %type <str> PE_MODIFIER_BP
53 %type <str> PE_EVENT_NAME
54 %type <num> value_sym
55 %type <head> event_config
56 %type <term> event_term
57 %type <head> event_pmu
58 %type <head> event_legacy_symbol
59 %type <head> event_legacy_cache
60 %type <head> event_legacy_mem
61 %type <head> event_legacy_tracepoint
62 %type <head> event_legacy_numeric
63 %type <head> event_legacy_raw
64 %type <head> event_def
65 %type <head> event_mod
66 %type <head> event_name
67 %type <head> event
68 %type <head> events
69 %type <head> group_def
70 %type <head> group
71 %type <head> groups
72 
73 %union
74 {
75 	char *str;
76 	u64 num;
77 	struct list_head *head;
78 	struct parse_events_term *term;
79 }
80 %%
81 
82 start:
83 PE_START_EVENTS start_events
84 |
85 PE_START_TERMS  start_terms
86 
87 start_events: groups
88 {
89 	struct parse_events_evlist *data = _data;
90 
91 	parse_events_update_lists($1, &data->list);
92 }
93 
94 groups:
95 groups ',' group
96 {
97 	struct list_head *list  = $1;
98 	struct list_head *group = $3;
99 
100 	parse_events_update_lists(group, list);
101 	$$ = list;
102 }
103 |
104 groups ',' event
105 {
106 	struct list_head *list  = $1;
107 	struct list_head *event = $3;
108 
109 	parse_events_update_lists(event, list);
110 	$$ = list;
111 }
112 |
113 group
114 |
115 event
116 
117 group:
118 group_def ':' PE_MODIFIER_EVENT
119 {
120 	struct list_head *list = $1;
121 
122 	ABORT_ON(parse_events__modifier_group(list, $3));
123 	$$ = list;
124 }
125 |
126 group_def
127 
128 group_def:
129 PE_NAME '{' events '}'
130 {
131 	struct list_head *list = $3;
132 
133 	inc_group_count(list, _data);
134 	parse_events__set_leader($1, list);
135 	$$ = list;
136 }
137 |
138 '{' events '}'
139 {
140 	struct list_head *list = $2;
141 
142 	inc_group_count(list, _data);
143 	parse_events__set_leader(NULL, list);
144 	$$ = list;
145 }
146 
147 events:
148 events ',' event
149 {
150 	struct list_head *event = $3;
151 	struct list_head *list  = $1;
152 
153 	parse_events_update_lists(event, list);
154 	$$ = list;
155 }
156 |
157 event
158 
159 event: event_mod
160 
161 event_mod:
162 event_name PE_MODIFIER_EVENT
163 {
164 	struct list_head *list = $1;
165 
166 	/*
167 	 * Apply modifier on all events added by single event definition
168 	 * (there could be more events added for multiple tracepoint
169 	 * definitions via '*?'.
170 	 */
171 	ABORT_ON(parse_events__modifier_event(list, $2, false));
172 	$$ = list;
173 }
174 |
175 event_name
176 
177 event_name:
178 PE_EVENT_NAME event_def
179 {
180 	ABORT_ON(parse_events_name($2, $1));
181 	free($1);
182 	$$ = $2;
183 }
184 |
185 event_def
186 
187 event_def: event_pmu |
188 	   event_legacy_symbol |
189 	   event_legacy_cache sep_dc |
190 	   event_legacy_mem |
191 	   event_legacy_tracepoint sep_dc |
192 	   event_legacy_numeric sep_dc |
193 	   event_legacy_raw sep_dc
194 
195 event_pmu:
196 PE_NAME '/' event_config '/'
197 {
198 	struct parse_events_evlist *data = _data;
199 	struct list_head *list = NULL;
200 
201 	ABORT_ON(parse_events_add_pmu(&list, &data->idx, $1, $3));
202 	parse_events__free_terms($3);
203 	$$ = list;
204 }
205 
206 value_sym:
207 PE_VALUE_SYM_HW
208 |
209 PE_VALUE_SYM_SW
210 
211 event_legacy_symbol:
212 value_sym '/' event_config '/'
213 {
214 	struct parse_events_evlist *data = _data;
215 	struct list_head *list = NULL;
216 	int type = $1 >> 16;
217 	int config = $1 & 255;
218 
219 	ABORT_ON(parse_events_add_numeric(&list, &data->idx,
220 					  type, config, $3));
221 	parse_events__free_terms($3);
222 	$$ = list;
223 }
224 |
225 value_sym sep_slash_dc
226 {
227 	struct parse_events_evlist *data = _data;
228 	struct list_head *list = NULL;
229 	int type = $1 >> 16;
230 	int config = $1 & 255;
231 
232 	ABORT_ON(parse_events_add_numeric(&list, &data->idx,
233 					  type, config, NULL));
234 	$$ = list;
235 }
236 
237 event_legacy_cache:
238 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
239 {
240 	struct parse_events_evlist *data = _data;
241 	struct list_head *list = NULL;
242 
243 	ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, $5));
244 	$$ = list;
245 }
246 |
247 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
248 {
249 	struct parse_events_evlist *data = _data;
250 	struct list_head *list = NULL;
251 
252 	ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, NULL));
253 	$$ = list;
254 }
255 |
256 PE_NAME_CACHE_TYPE
257 {
258 	struct parse_events_evlist *data = _data;
259 	struct list_head *list = NULL;
260 
261 	ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, NULL, NULL));
262 	$$ = list;
263 }
264 
265 event_legacy_mem:
266 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
267 {
268 	struct parse_events_evlist *data = _data;
269 	struct list_head *list = NULL;
270 
271 	ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
272 					     (void *) $2, $4));
273 	$$ = list;
274 }
275 |
276 PE_PREFIX_MEM PE_VALUE sep_dc
277 {
278 	struct parse_events_evlist *data = _data;
279 	struct list_head *list = NULL;
280 
281 	ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
282 					     (void *) $2, NULL));
283 	$$ = list;
284 }
285 
286 event_legacy_tracepoint:
287 PE_NAME ':' PE_NAME
288 {
289 	struct parse_events_evlist *data = _data;
290 	struct list_head *list = NULL;
291 
292 	ABORT_ON(parse_events_add_tracepoint(&list, &data->idx, $1, $3));
293 	$$ = list;
294 }
295 
296 event_legacy_numeric:
297 PE_VALUE ':' PE_VALUE
298 {
299 	struct parse_events_evlist *data = _data;
300 	struct list_head *list = NULL;
301 
302 	ABORT_ON(parse_events_add_numeric(&list, &data->idx, (u32)$1, $3, NULL));
303 	$$ = list;
304 }
305 
306 event_legacy_raw:
307 PE_RAW
308 {
309 	struct parse_events_evlist *data = _data;
310 	struct list_head *list = NULL;
311 
312 	ABORT_ON(parse_events_add_numeric(&list, &data->idx,
313 					  PERF_TYPE_RAW, $1, NULL));
314 	$$ = list;
315 }
316 
317 start_terms: event_config
318 {
319 	struct parse_events_terms *data = _data;
320 	data->terms = $1;
321 }
322 
323 event_config:
324 event_config ',' event_term
325 {
326 	struct list_head *head = $1;
327 	struct parse_events_term *term = $3;
328 
329 	ABORT_ON(!head);
330 	list_add_tail(&term->list, head);
331 	$$ = $1;
332 }
333 |
334 event_term
335 {
336 	struct list_head *head = malloc(sizeof(*head));
337 	struct parse_events_term *term = $1;
338 
339 	ABORT_ON(!head);
340 	INIT_LIST_HEAD(head);
341 	list_add_tail(&term->list, head);
342 	$$ = head;
343 }
344 
345 event_term:
346 PE_NAME '=' PE_NAME
347 {
348 	struct parse_events_term *term;
349 
350 	ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
351 					$1, $3));
352 	$$ = term;
353 }
354 |
355 PE_NAME '=' PE_VALUE
356 {
357 	struct parse_events_term *term;
358 
359 	ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
360 					$1, $3));
361 	$$ = term;
362 }
363 |
364 PE_NAME '=' PE_VALUE_SYM_HW
365 {
366 	struct parse_events_term *term;
367 	int config = $3 & 255;
368 
369 	ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
370 	$$ = term;
371 }
372 |
373 PE_NAME
374 {
375 	struct parse_events_term *term;
376 
377 	ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
378 					$1, 1));
379 	$$ = term;
380 }
381 |
382 PE_VALUE_SYM_HW
383 {
384 	struct parse_events_term *term;
385 	int config = $1 & 255;
386 
387 	ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
388 	$$ = term;
389 }
390 |
391 PE_TERM '=' PE_NAME
392 {
393 	struct parse_events_term *term;
394 
395 	ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3));
396 	$$ = term;
397 }
398 |
399 PE_TERM '=' PE_VALUE
400 {
401 	struct parse_events_term *term;
402 
403 	ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3));
404 	$$ = term;
405 }
406 |
407 PE_TERM
408 {
409 	struct parse_events_term *term;
410 
411 	ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1));
412 	$$ = term;
413 }
414 
415 sep_dc: ':' |
416 
417 sep_slash_dc: '/' | ':' |
418 
419 %%
420 
421 void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused,
422 			char const *msg __maybe_unused)
423 {
424 }
425