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