xref: /linux/tools/perf/util/parse-events.y (revision 95e9fd10f06cb5642028b6b851e32b8c8afb4571)
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_START_EVENTS PE_START_TERMS
29 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
30 %token PE_NAME
31 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
32 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
33 %token PE_PREFIX_MEM PE_PREFIX_RAW
34 %token PE_ERROR
35 %type <num> PE_VALUE
36 %type <num> PE_VALUE_SYM_HW
37 %type <num> PE_VALUE_SYM_SW
38 %type <num> PE_RAW
39 %type <num> PE_TERM
40 %type <str> PE_NAME
41 %type <str> PE_NAME_CACHE_TYPE
42 %type <str> PE_NAME_CACHE_OP_RESULT
43 %type <str> PE_MODIFIER_EVENT
44 %type <str> PE_MODIFIER_BP
45 %type <num> value_sym
46 %type <head> event_config
47 %type <term> event_term
48 %type <head> event_pmu
49 %type <head> event_legacy_symbol
50 %type <head> event_legacy_cache
51 %type <head> event_legacy_mem
52 %type <head> event_legacy_tracepoint
53 %type <head> event_legacy_numeric
54 %type <head> event_legacy_raw
55 %type <head> event_def
56 
57 %union
58 {
59 	char *str;
60 	unsigned long num;
61 	struct list_head *head;
62 	struct parse_events__term *term;
63 }
64 %%
65 
66 start:
67 PE_START_EVENTS events
68 |
69 PE_START_TERMS  terms
70 
71 events:
72 events ',' event | event
73 
74 event:
75 event_def PE_MODIFIER_EVENT
76 {
77 	struct parse_events_data__events *data = _data;
78 
79 	/*
80 	 * Apply modifier on all events added by single event definition
81 	 * (there could be more events added for multiple tracepoint
82 	 * definitions via '*?'.
83 	 */
84 	ABORT_ON(parse_events_modifier($1, $2));
85 	parse_events_update_lists($1, &data->list);
86 }
87 |
88 event_def
89 {
90 	struct parse_events_data__events *data = _data;
91 
92 	parse_events_update_lists($1, &data->list);
93 }
94 
95 event_def: event_pmu |
96 	   event_legacy_symbol |
97 	   event_legacy_cache sep_dc |
98 	   event_legacy_mem |
99 	   event_legacy_tracepoint sep_dc |
100 	   event_legacy_numeric sep_dc |
101 	   event_legacy_raw sep_dc
102 
103 event_pmu:
104 PE_NAME '/' event_config '/'
105 {
106 	struct parse_events_data__events *data = _data;
107 	struct list_head *list = NULL;
108 
109 	ABORT_ON(parse_events_add_pmu(&list, &data->idx, $1, $3));
110 	parse_events__free_terms($3);
111 	$$ = list;
112 }
113 
114 value_sym:
115 PE_VALUE_SYM_HW
116 |
117 PE_VALUE_SYM_SW
118 
119 event_legacy_symbol:
120 value_sym '/' event_config '/'
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, $3));
129 	parse_events__free_terms($3);
130 	$$ = list;
131 }
132 |
133 value_sym sep_slash_dc
134 {
135 	struct parse_events_data__events *data = _data;
136 	struct list_head *list = NULL;
137 	int type = $1 >> 16;
138 	int config = $1 & 255;
139 
140 	ABORT_ON(parse_events_add_numeric(&list, &data->idx,
141 					  type, config, NULL));
142 	$$ = list;
143 }
144 
145 event_legacy_cache:
146 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
147 {
148 	struct parse_events_data__events *data = _data;
149 	struct list_head *list = NULL;
150 
151 	ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, $5));
152 	$$ = list;
153 }
154 |
155 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
156 {
157 	struct parse_events_data__events *data = _data;
158 	struct list_head *list = NULL;
159 
160 	ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, NULL));
161 	$$ = list;
162 }
163 |
164 PE_NAME_CACHE_TYPE
165 {
166 	struct parse_events_data__events *data = _data;
167 	struct list_head *list = NULL;
168 
169 	ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, NULL, NULL));
170 	$$ = list;
171 }
172 
173 event_legacy_mem:
174 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
175 {
176 	struct parse_events_data__events *data = _data;
177 	struct list_head *list = NULL;
178 
179 	ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
180 					     (void *) $2, $4));
181 	$$ = list;
182 }
183 |
184 PE_PREFIX_MEM PE_VALUE sep_dc
185 {
186 	struct parse_events_data__events *data = _data;
187 	struct list_head *list = NULL;
188 
189 	ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
190 					     (void *) $2, NULL));
191 	$$ = list;
192 }
193 
194 event_legacy_tracepoint:
195 PE_NAME ':' PE_NAME
196 {
197 	struct parse_events_data__events *data = _data;
198 	struct list_head *list = NULL;
199 
200 	ABORT_ON(parse_events_add_tracepoint(&list, &data->idx, $1, $3));
201 	$$ = list;
202 }
203 
204 event_legacy_numeric:
205 PE_VALUE ':' PE_VALUE
206 {
207 	struct parse_events_data__events *data = _data;
208 	struct list_head *list = NULL;
209 
210 	ABORT_ON(parse_events_add_numeric(&list, &data->idx, $1, $3, NULL));
211 	$$ = list;
212 }
213 
214 event_legacy_raw:
215 PE_RAW
216 {
217 	struct parse_events_data__events *data = _data;
218 	struct list_head *list = NULL;
219 
220 	ABORT_ON(parse_events_add_numeric(&list, &data->idx,
221 					  PERF_TYPE_RAW, $1, NULL));
222 	$$ = list;
223 }
224 
225 terms: event_config
226 {
227 	struct parse_events_data__terms *data = _data;
228 	data->terms = $1;
229 }
230 
231 event_config:
232 event_config ',' event_term
233 {
234 	struct list_head *head = $1;
235 	struct parse_events__term *term = $3;
236 
237 	ABORT_ON(!head);
238 	list_add_tail(&term->list, head);
239 	$$ = $1;
240 }
241 |
242 event_term
243 {
244 	struct list_head *head = malloc(sizeof(*head));
245 	struct parse_events__term *term = $1;
246 
247 	ABORT_ON(!head);
248 	INIT_LIST_HEAD(head);
249 	list_add_tail(&term->list, head);
250 	$$ = head;
251 }
252 
253 event_term:
254 PE_NAME '=' PE_NAME
255 {
256 	struct parse_events__term *term;
257 
258 	ABORT_ON(parse_events__term_str(&term, PARSE_EVENTS__TERM_TYPE_USER,
259 					$1, $3));
260 	$$ = term;
261 }
262 |
263 PE_NAME '=' PE_VALUE
264 {
265 	struct parse_events__term *term;
266 
267 	ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER,
268 					$1, $3));
269 	$$ = term;
270 }
271 |
272 PE_NAME
273 {
274 	struct parse_events__term *term;
275 
276 	ABORT_ON(parse_events__term_num(&term, PARSE_EVENTS__TERM_TYPE_USER,
277 					$1, 1));
278 	$$ = term;
279 }
280 |
281 PE_TERM '=' PE_NAME
282 {
283 	struct parse_events__term *term;
284 
285 	ABORT_ON(parse_events__term_str(&term, $1, NULL, $3));
286 	$$ = term;
287 }
288 |
289 PE_TERM '=' PE_VALUE
290 {
291 	struct parse_events__term *term;
292 
293 	ABORT_ON(parse_events__term_num(&term, $1, NULL, $3));
294 	$$ = term;
295 }
296 |
297 PE_TERM
298 {
299 	struct parse_events__term *term;
300 
301 	ABORT_ON(parse_events__term_num(&term, $1, NULL, 1));
302 	$$ = term;
303 }
304 
305 sep_dc: ':' |
306 
307 sep_slash_dc: '/' | ':' |
308 
309 %%
310 
311 void parse_events_error(void *data __used, void *scanner __used,
312 			char const *msg __used)
313 {
314 }
315