Commit | Line | Data |
---|---|---|
8b9d5b5e MD |
1 | %{ |
2 | /* | |
c59a87f5 | 3 | * ctf-parser.y |
8b9d5b5e MD |
4 | * |
5 | * Common Trace Format Metadata Grammar. | |
c59a87f5 MD |
6 | * |
7 | * Copyright 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
8 | * | |
9 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
10 | * of this software and associated documentation files (the "Software"), to deal | |
11 | * in the Software without restriction, including without limitation the rights | |
12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
13 | * copies of the Software, and to permit persons to whom the Software is | |
14 | * furnished to do so, subject to the following conditions: | |
15 | * | |
16 | * The above copyright notice and this permission notice shall be included in | |
17 | * all copies or substantial portions of the Software. | |
8b9d5b5e MD |
18 | */ |
19 | ||
20 | #include <stdio.h> | |
21 | #include <unistd.h> | |
22 | #include <string.h> | |
23 | #include <stdlib.h> | |
24 | #include <assert.h> | |
25 | #include <helpers/list.h> | |
26 | #include <glib.h> | |
02b234c4 | 27 | #include <errno.h> |
34d3acc4 | 28 | #include "ctf-scanner.h" |
8b9d5b5e MD |
29 | #include "ctf-parser.h" |
30 | #include "ctf-ast.h" | |
31 | ||
8e1a0b6f | 32 | #define printf_dbg(fmt, args...) fprintf(stderr, "%s: " fmt, __func__, ## args) |
8b9d5b5e | 33 | |
34d3acc4 MD |
34 | int yyparse(struct ctf_scanner *scanner); |
35 | int yylex(union YYSTYPE *yyval, struct ctf_scanner *scanner); | |
36 | int yylex_init_extra(struct ctf_scanner *scanner, yyscan_t * ptr_yy_globals); | |
37 | int yylex_destroy(yyscan_t yyscanner) ; | |
38 | void yyset_in(FILE * in_str, yyscan_t scanner); | |
8b9d5b5e | 39 | |
8b9d5b5e MD |
40 | int yydebug; |
41 | ||
8b9d5b5e MD |
42 | struct gc_string { |
43 | struct cds_list_head gc; | |
44 | char s[]; | |
45 | }; | |
46 | ||
8b9d5b5e MD |
47 | char *strredup(char **dest, const char *src) |
48 | { | |
49 | size_t len = strlen(src) + 1; | |
50 | ||
51 | *dest = realloc(*dest, len); | |
52 | if (!*dest) | |
53 | return NULL; | |
54 | strcpy(*dest, src); | |
55 | return *dest; | |
56 | } | |
57 | ||
34d3acc4 | 58 | static struct gc_string *gc_string_alloc(struct ctf_scanner *scanner, size_t len) |
8b9d5b5e MD |
59 | { |
60 | struct gc_string *gstr; | |
61 | ||
62 | gstr = malloc(sizeof(*gstr) + len); | |
34d3acc4 | 63 | cds_list_add(&gstr->gc, &scanner->allocated_strings); |
8b9d5b5e MD |
64 | return gstr; |
65 | } | |
66 | ||
34d3acc4 | 67 | void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src) |
8b9d5b5e | 68 | { |
34d3acc4 MD |
69 | lvalp->gs = gc_string_alloc(scanner, strlen(src) + 1); |
70 | strcpy(lvalp->gs->s, src); | |
8b9d5b5e MD |
71 | } |
72 | ||
609bd1bf MD |
73 | static void init_scope(struct ctf_scanner_scope *scope, |
74 | struct ctf_scanner_scope *parent) | |
8b9d5b5e MD |
75 | { |
76 | scope->parent = parent; | |
77 | scope->types = g_hash_table_new_full(g_str_hash, g_str_equal, | |
78 | (GDestroyNotify) free, NULL); | |
79 | } | |
80 | ||
609bd1bf | 81 | static void finalize_scope(struct ctf_scanner_scope *scope) |
8b9d5b5e MD |
82 | { |
83 | g_hash_table_destroy(scope->types); | |
84 | } | |
85 | ||
34d3acc4 | 86 | static void push_scope(struct ctf_scanner *scanner) |
8b9d5b5e | 87 | { |
609bd1bf | 88 | struct ctf_scanner_scope *ns; |
8b9d5b5e | 89 | |
8e1a0b6f | 90 | printf_dbg("push scope\n"); |
609bd1bf | 91 | ns = malloc(sizeof(struct ctf_scanner_scope)); |
34d3acc4 MD |
92 | init_scope(ns, scanner->cs); |
93 | scanner->cs = ns; | |
8b9d5b5e MD |
94 | } |
95 | ||
34d3acc4 | 96 | static void pop_scope(struct ctf_scanner *scanner) |
8b9d5b5e | 97 | { |
609bd1bf | 98 | struct ctf_scanner_scope *os; |
8b9d5b5e | 99 | |
8e1a0b6f | 100 | printf_dbg("pop scope\n"); |
34d3acc4 MD |
101 | os = scanner->cs; |
102 | scanner->cs = os->parent; | |
8b9d5b5e MD |
103 | finalize_scope(os); |
104 | free(os); | |
105 | } | |
106 | ||
609bd1bf | 107 | static int lookup_type(struct ctf_scanner_scope *s, const char *id) |
8b9d5b5e MD |
108 | { |
109 | int ret; | |
110 | ||
111 | ret = (int) g_hash_table_lookup(s->types, id); | |
112 | printf_dbg("lookup %p %s %d\n", s, id, ret); | |
113 | return ret; | |
114 | } | |
115 | ||
34d3acc4 | 116 | int is_type(struct ctf_scanner *scanner, const char *id) |
8b9d5b5e | 117 | { |
609bd1bf | 118 | struct ctf_scanner_scope *it; |
8b9d5b5e MD |
119 | int ret = 0; |
120 | ||
34d3acc4 | 121 | for (it = scanner->cs; it != NULL; it = it->parent) { |
8b9d5b5e MD |
122 | if (lookup_type(it, id)) { |
123 | ret = 1; | |
124 | break; | |
125 | } | |
126 | } | |
127 | printf_dbg("is type %s %d\n", id, ret); | |
128 | return ret; | |
129 | } | |
130 | ||
34d3acc4 | 131 | static void add_type(struct ctf_scanner *scanner, const char *id) |
8b9d5b5e MD |
132 | { |
133 | char *type_id = NULL; | |
134 | ||
135 | printf_dbg("add type %s\n", id); | |
34d3acc4 | 136 | if (lookup_type(scanner->cs, id)) |
8b9d5b5e MD |
137 | return; |
138 | strredup(&type_id, id); | |
34d3acc4 | 139 | g_hash_table_insert(scanner->cs->types, type_id, type_id); |
8b9d5b5e MD |
140 | } |
141 | ||
02b234c4 MD |
142 | static struct ctf_node *make_node(struct ctf_scanner *scanner, |
143 | enum node_type type) | |
144 | { | |
145 | struct ctf_ast *ast = ctf_scanner_get_ast(scanner); | |
146 | struct ctf_node *node; | |
147 | ||
148 | node = malloc(sizeof(*node)); | |
149 | if (!node) | |
150 | return NULL; | |
151 | memset(node, 0, sizeof(*node)); | |
152 | node->type = type; | |
153 | CDS_INIT_LIST_HEAD(&node->siblings); | |
154 | cds_list_add(&node->gc, &ast->allocated_nodes); | |
155 | ||
156 | switch (type) { | |
157 | case NODE_ROOT: | |
158 | fprintf(stderr, "[error] %s: trying to create root node\n", __func__); | |
159 | break; | |
160 | ||
161 | case NODE_EVENT: | |
162 | CDS_INIT_LIST_HEAD(&node->u.event._typedef); | |
163 | CDS_INIT_LIST_HEAD(&node->u.event.typealias); | |
164 | CDS_INIT_LIST_HEAD(&node->u.event.ctf_expression); | |
165 | CDS_INIT_LIST_HEAD(&node->u.event.declaration_specifier); | |
166 | break; | |
167 | case NODE_STREAM: | |
168 | CDS_INIT_LIST_HEAD(&node->u.stream._typedef); | |
169 | CDS_INIT_LIST_HEAD(&node->u.stream.typealias); | |
170 | CDS_INIT_LIST_HEAD(&node->u.stream.ctf_expression); | |
171 | CDS_INIT_LIST_HEAD(&node->u.stream.declaration_specifier); | |
172 | break; | |
173 | case NODE_TRACE: | |
174 | CDS_INIT_LIST_HEAD(&node->u.trace._typedef); | |
175 | CDS_INIT_LIST_HEAD(&node->u.trace.typealias); | |
176 | CDS_INIT_LIST_HEAD(&node->u.trace.ctf_expression); | |
177 | CDS_INIT_LIST_HEAD(&node->u.trace.declaration_specifier); | |
178 | break; | |
179 | ||
180 | case NODE_CTF_EXPRESSION: | |
181 | break; | |
182 | ||
183 | case NODE_TYPEDEF: | |
184 | CDS_INIT_LIST_HEAD(&node->u._typedef.type_declarators); | |
185 | break; | |
186 | case NODE_TYPEALIAS_TARGET: | |
187 | CDS_INIT_LIST_HEAD(&node->u.typealias_target.type_declarators); | |
188 | break; | |
189 | case NODE_TYPEALIAS_ALIAS: | |
190 | CDS_INIT_LIST_HEAD(&node->u.typealias_alias.type_declarators); | |
191 | break; | |
192 | case NODE_TYPEALIAS: | |
193 | break; | |
194 | ||
195 | case NODE_TYPE_SPECIFIER: | |
196 | break; | |
197 | case NODE_DECLARATION_SPECIFIER: | |
198 | CDS_INIT_LIST_HEAD(&node->u.declaration_specifier.type_specifiers); | |
199 | break; | |
200 | case NODE_POINTER: | |
201 | break; | |
202 | case NODE_TYPE_DECLARATOR: | |
203 | CDS_INIT_LIST_HEAD(&node->u.type_declarator.pointers); | |
204 | break; | |
205 | ||
206 | case NODE_FLOATING_POINT: | |
207 | CDS_INIT_LIST_HEAD(&node->u.floating_point.expressions); | |
208 | break; | |
209 | case NODE_INTEGER: | |
210 | CDS_INIT_LIST_HEAD(&node->u.integer.expressions); | |
211 | break; | |
212 | case NODE_STRING: | |
213 | CDS_INIT_LIST_HEAD(&node->u.string.expressions); | |
214 | break; | |
215 | case NODE_ENUMERATOR: | |
216 | break; | |
217 | case NODE_ENUM: | |
218 | CDS_INIT_LIST_HEAD(&node->u._enum.enumerator_list); | |
219 | break; | |
220 | case NODE_STRUCT_OR_VARIANT_DECLARATION: | |
221 | CDS_INIT_LIST_HEAD(&node->u.struct_or_variant_declaration.type_declarators); | |
222 | break; | |
223 | case NODE_VARIANT: | |
224 | CDS_INIT_LIST_HEAD(&node->u.variant._typedef); | |
225 | CDS_INIT_LIST_HEAD(&node->u.variant.typealias); | |
226 | CDS_INIT_LIST_HEAD(&node->u.variant.declaration_list); | |
227 | break; | |
228 | case NODE_STRUCT: | |
229 | CDS_INIT_LIST_HEAD(&node->u._struct._typedef); | |
230 | CDS_INIT_LIST_HEAD(&node->u._struct.typealias); | |
231 | CDS_INIT_LIST_HEAD(&node->u._struct.declaration_list); | |
232 | break; | |
233 | ||
234 | case NODE_UNKNOWN: | |
235 | default: | |
236 | fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, | |
237 | (int) type); | |
238 | break; | |
239 | } | |
240 | ||
241 | return node; | |
242 | } | |
243 | ||
244 | static int reparent_ctf_expression(struct ctf_node *node, | |
245 | struct ctf_node *parent) | |
246 | { | |
247 | switch (parent->type) { | |
248 | case NODE_EVENT: | |
249 | cds_list_add(&node->siblings, &parent->u.event.ctf_expression); | |
250 | break; | |
251 | case NODE_STREAM: | |
252 | cds_list_add(&node->siblings, &parent->u.stream.ctf_expression); | |
253 | break; | |
254 | case NODE_TRACE: | |
255 | cds_list_add(&node->siblings, &parent->u.trace.ctf_expression); | |
256 | break; | |
257 | case NODE_FLOATING_POINT: | |
258 | cds_list_add(&node->siblings, &parent->u.floating_point.expressions); | |
259 | break; | |
260 | case NODE_INTEGER: | |
261 | cds_list_add(&node->siblings, &parent->u.integer.expressions); | |
262 | break; | |
263 | case NODE_STRING: | |
264 | cds_list_add(&node->siblings, &parent->u.string.expressions); | |
265 | break; | |
266 | ||
267 | case NODE_ROOT: | |
268 | case NODE_CTF_EXPRESSION: | |
269 | case NODE_TYPEDEF: | |
270 | case NODE_TYPEALIAS_TARGET: | |
271 | case NODE_TYPEALIAS_ALIAS: | |
272 | case NODE_TYPEALIAS: | |
273 | case NODE_TYPE_SPECIFIER: | |
274 | case NODE_DECLARATION_SPECIFIER: | |
275 | case NODE_POINTER: | |
276 | case NODE_TYPE_DECLARATOR: | |
277 | case NODE_ENUMERATOR: | |
278 | case NODE_ENUM: | |
279 | case NODE_STRUCT_OR_VARIANT_DECLARATION: | |
280 | case NODE_VARIANT: | |
281 | case NODE_STRUCT: | |
282 | return -EPERM; | |
283 | ||
284 | case NODE_UNKNOWN: | |
285 | default: | |
286 | fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, | |
287 | (int) parent->type); | |
288 | return -EINVAL; | |
289 | } | |
290 | return 0; | |
291 | } | |
292 | ||
293 | static int reparent_typedef(struct ctf_node *node, struct ctf_node *parent) | |
294 | { | |
295 | switch (parent->type) { | |
296 | case NODE_ROOT: | |
297 | cds_list_add(&node->siblings, &parent->u.root._typedef); | |
298 | break; | |
299 | case NODE_EVENT: | |
300 | cds_list_add(&node->siblings, &parent->u.event._typedef); | |
301 | break; | |
302 | case NODE_STREAM: | |
303 | cds_list_add(&node->siblings, &parent->u.stream._typedef); | |
304 | break; | |
305 | case NODE_TRACE: | |
306 | cds_list_add(&node->siblings, &parent->u.trace._typedef); | |
307 | break; | |
308 | case NODE_VARIANT: | |
309 | cds_list_add(&node->siblings, &parent->u.variant._typedef); | |
310 | break; | |
311 | case NODE_STRUCT: | |
312 | cds_list_add(&node->siblings, &parent->u._struct._typedef); | |
313 | break; | |
314 | ||
315 | case NODE_FLOATING_POINT: | |
316 | case NODE_INTEGER: | |
317 | case NODE_STRING: | |
318 | case NODE_CTF_EXPRESSION: | |
319 | case NODE_TYPEDEF: | |
320 | case NODE_TYPEALIAS_TARGET: | |
321 | case NODE_TYPEALIAS_ALIAS: | |
322 | case NODE_TYPEALIAS: | |
323 | case NODE_TYPE_SPECIFIER: | |
324 | case NODE_DECLARATION_SPECIFIER: | |
325 | case NODE_POINTER: | |
326 | case NODE_TYPE_DECLARATOR: | |
327 | case NODE_ENUMERATOR: | |
328 | case NODE_ENUM: | |
329 | case NODE_STRUCT_OR_VARIANT_DECLARATION: | |
330 | return -EPERM; | |
331 | ||
332 | case NODE_UNKNOWN: | |
333 | default: | |
334 | fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, | |
335 | (int) parent->type); | |
336 | return -EINVAL; | |
337 | } | |
338 | return 0; | |
339 | } | |
340 | ||
341 | static int reparent_typealias(struct ctf_node *node, struct ctf_node *parent) | |
342 | { | |
343 | switch (parent->type) { | |
344 | case NODE_ROOT: | |
345 | cds_list_add(&node->siblings, &parent->u.root.typealias); | |
346 | break; | |
347 | case NODE_EVENT: | |
348 | cds_list_add(&node->siblings, &parent->u.event.typealias); | |
349 | break; | |
350 | case NODE_STREAM: | |
351 | cds_list_add(&node->siblings, &parent->u.stream.typealias); | |
352 | break; | |
353 | case NODE_TRACE: | |
354 | cds_list_add(&node->siblings, &parent->u.trace.typealias); | |
355 | break; | |
356 | case NODE_VARIANT: | |
357 | cds_list_add(&node->siblings, &parent->u.variant.typealias); | |
358 | break; | |
359 | case NODE_STRUCT: | |
360 | cds_list_add(&node->siblings, &parent->u._struct.typealias); | |
361 | break; | |
362 | ||
363 | case NODE_FLOATING_POINT: | |
364 | case NODE_INTEGER: | |
365 | case NODE_STRING: | |
366 | case NODE_CTF_EXPRESSION: | |
367 | case NODE_TYPEDEF: | |
368 | case NODE_TYPEALIAS_TARGET: | |
369 | case NODE_TYPEALIAS_ALIAS: | |
370 | case NODE_TYPEALIAS: | |
371 | case NODE_TYPE_SPECIFIER: | |
372 | case NODE_DECLARATION_SPECIFIER: | |
373 | case NODE_POINTER: | |
374 | case NODE_TYPE_DECLARATOR: | |
375 | case NODE_ENUMERATOR: | |
376 | case NODE_ENUM: | |
377 | case NODE_STRUCT_OR_VARIANT_DECLARATION: | |
378 | return -EPERM; | |
379 | ||
380 | case NODE_UNKNOWN: | |
381 | default: | |
382 | fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, | |
383 | (int) parent->type); | |
384 | return -EINVAL; | |
385 | } | |
386 | return 0; | |
387 | } | |
388 | ||
389 | static int reparent_declaration_specifier(struct ctf_node *node, | |
390 | struct ctf_node *parent) | |
391 | { | |
392 | switch (parent->type) { | |
393 | case NODE_ROOT: | |
394 | cds_list_add(&node->siblings, &parent->u.root.declaration_specifier); | |
395 | break; | |
396 | case NODE_EVENT: | |
397 | cds_list_add(&node->siblings, &parent->u.event.declaration_specifier); | |
398 | break; | |
399 | case NODE_STREAM: | |
400 | cds_list_add(&node->siblings, &parent->u.stream.declaration_specifier); | |
401 | break; | |
402 | case NODE_TRACE: | |
403 | cds_list_add(&node->siblings, &parent->u.trace.declaration_specifier); | |
404 | break; | |
405 | case NODE_VARIANT: | |
406 | cds_list_add(&node->siblings, &parent->u.variant.declaration_list); | |
407 | break; | |
408 | case NODE_STRUCT: | |
409 | cds_list_add(&node->siblings, &parent->u._struct.declaration_list); | |
410 | break; | |
411 | case NODE_TYPEDEF: | |
412 | parent->u._typedef.declaration_specifier = node; | |
413 | break; | |
414 | case NODE_TYPEALIAS_TARGET: | |
415 | parent->u.typealias_target.declaration_specifier = node; | |
416 | break; | |
417 | case NODE_TYPEALIAS_ALIAS: | |
418 | parent->u.typealias_alias.declaration_specifier = node; | |
419 | break; | |
420 | case NODE_TYPE_DECLARATOR: | |
421 | parent->u.type_declarator.type = TYPEDEC_NESTED; | |
422 | parent->u.type_declarator.u.nested.length.type = TYPEDEC_TYPE_TYPE; | |
423 | parent->u.type_declarator.u.nested.length.u.declaration_specifier = node; | |
424 | break; | |
425 | case NODE_ENUM: | |
426 | parent->u._enum.container_type.type = ENUM_TYPE_TYPE; | |
427 | parent->u._enum.container_type.u.declaration_specifier = node; | |
428 | break; | |
429 | case NODE_STRUCT_OR_VARIANT_DECLARATION: | |
430 | parent->u.struct_or_variant_declaration.declaration_specifier = node; | |
431 | break; | |
432 | case NODE_TYPEALIAS: | |
433 | case NODE_FLOATING_POINT: | |
434 | case NODE_INTEGER: | |
435 | case NODE_STRING: | |
436 | case NODE_CTF_EXPRESSION: | |
437 | case NODE_TYPE_SPECIFIER: | |
438 | case NODE_DECLARATION_SPECIFIER: | |
439 | case NODE_POINTER: | |
440 | case NODE_ENUMERATOR: | |
441 | return -EPERM; | |
442 | ||
443 | case NODE_UNKNOWN: | |
444 | default: | |
445 | fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, | |
446 | (int) parent->type); | |
447 | return -EINVAL; | |
448 | } | |
449 | return 0; | |
450 | } | |
451 | ||
452 | static int reparent_type_declarator(struct ctf_node *node, | |
453 | struct ctf_node *parent) | |
454 | { | |
455 | switch (parent->type) { | |
456 | case NODE_TYPE_DECLARATOR: | |
457 | parent->u.type_declarator.type = TYPEDEC_NESTED; | |
458 | parent->u.type_declarator.u.nested.type_declarator = node; | |
459 | break; | |
460 | case NODE_STRUCT_OR_VARIANT_DECLARATION: | |
461 | cds_list_add(&node->siblings, &parent->u.struct_or_variant_declaration.type_declarators); | |
462 | break; | |
463 | case NODE_TYPEDEF: | |
464 | cds_list_add(&node->siblings, &parent->u._typedef.type_declarators); | |
465 | break; | |
466 | case NODE_TYPEALIAS_TARGET: | |
467 | cds_list_add(&node->siblings, &parent->u.typealias_target.type_declarators); | |
468 | break; | |
469 | case NODE_TYPEALIAS_ALIAS: | |
470 | cds_list_add(&node->siblings, &parent->u.typealias_alias.type_declarators); | |
471 | break; | |
472 | ||
473 | case NODE_ROOT: | |
474 | case NODE_EVENT: | |
475 | case NODE_STREAM: | |
476 | case NODE_TRACE: | |
477 | case NODE_VARIANT: | |
478 | case NODE_STRUCT: | |
479 | case NODE_TYPEALIAS: | |
480 | case NODE_ENUM: | |
481 | case NODE_FLOATING_POINT: | |
482 | case NODE_INTEGER: | |
483 | case NODE_STRING: | |
484 | case NODE_CTF_EXPRESSION: | |
485 | case NODE_TYPE_SPECIFIER: | |
486 | case NODE_DECLARATION_SPECIFIER: | |
487 | case NODE_POINTER: | |
488 | case NODE_ENUMERATOR: | |
489 | return -EPERM; | |
490 | ||
491 | case NODE_UNKNOWN: | |
492 | default: | |
493 | fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, | |
494 | (int) parent->type); | |
495 | return -EINVAL; | |
496 | } | |
497 | return 0; | |
498 | } | |
499 | ||
500 | /* | |
501 | * reparent node | |
502 | * | |
503 | * Relink node to new parent. Returns 0 on success, -EPERM if it is not | |
504 | * permitted to create the link declared by the input, -ENOENT if node or parent | |
505 | * is NULL, -EINVAL if there is an internal structure problem. | |
506 | */ | |
507 | static int reparent_node(struct ctf_node *node, | |
508 | struct ctf_node *parent) | |
509 | { | |
510 | if (!node || !parent) | |
511 | return -ENOENT; | |
512 | ||
513 | /* Unlink from old parent */ | |
514 | cds_list_del(&node->siblings); | |
515 | ||
516 | /* Link to new parent */ | |
517 | node->parent = parent; | |
518 | ||
519 | switch (node->type) { | |
520 | case NODE_ROOT: | |
521 | fprintf(stderr, "[error] %s: trying to reparent root node\n", __func__); | |
522 | return -EINVAL; | |
523 | ||
524 | case NODE_EVENT: | |
525 | if (parent->type == NODE_ROOT) | |
526 | cds_list_add(&node->siblings, &parent->u.root.event); | |
527 | else | |
528 | return -EPERM; | |
529 | break; | |
530 | case NODE_STREAM: | |
531 | if (parent->type == NODE_ROOT) | |
532 | cds_list_add(&node->siblings, &parent->u.root.stream); | |
533 | else | |
534 | return -EPERM; | |
535 | break; | |
536 | case NODE_TRACE: | |
537 | if (parent->type == NODE_ROOT) | |
538 | cds_list_add(&node->siblings, &parent->u.root.trace); | |
539 | else | |
540 | return -EPERM; | |
541 | break; | |
542 | ||
543 | case NODE_CTF_EXPRESSION: | |
544 | return reparent_ctf_expression(node, parent); | |
545 | ||
546 | case NODE_TYPEDEF: | |
547 | return reparent_typedef(node, parent); | |
548 | case NODE_TYPEALIAS_TARGET: | |
549 | if (parent->type == NODE_TYPEALIAS) | |
550 | parent->u.typealias.target = node; | |
551 | else | |
552 | return -EINVAL; | |
553 | case NODE_TYPEALIAS_ALIAS: | |
554 | if (parent->type == NODE_TYPEALIAS) | |
555 | parent->u.typealias.alias = node; | |
556 | else | |
557 | return -EINVAL; | |
558 | case NODE_TYPEALIAS: | |
559 | return reparent_typealias(node, parent); | |
560 | ||
561 | case NODE_TYPE_SPECIFIER: | |
562 | if (parent->type == NODE_DECLARATION_SPECIFIER) | |
563 | cds_list_add(&node->siblings, &parent->u.declaration_specifier.type_specifiers); | |
564 | else | |
565 | return -EPERM; | |
566 | break; | |
567 | case NODE_DECLARATION_SPECIFIER: | |
568 | return reparent_declaration_specifier(node, parent); | |
569 | case NODE_POINTER: | |
570 | if (parent->type == NODE_TYPE_DECLARATOR) | |
571 | cds_list_add(&node->siblings, &parent->u.type_declarator.pointers); | |
572 | else | |
573 | return -EPERM; | |
574 | break; | |
575 | case NODE_TYPE_DECLARATOR: | |
576 | return reparent_type_declarator(node, parent); | |
577 | ||
578 | case NODE_FLOATING_POINT: | |
579 | if (parent->type == NODE_TYPE_SPECIFIER) { | |
580 | parent->u.type_specifier.type = TYPESPEC_FLOATING_POINT; | |
581 | parent->u.type_specifier.u.floating_point = node; | |
582 | } else | |
583 | return -EPERM; | |
584 | break; | |
585 | case NODE_INTEGER: | |
586 | if (parent->type == NODE_TYPE_SPECIFIER) { | |
587 | parent->u.type_specifier.type = TYPESPEC_INTEGER; | |
588 | parent->u.type_specifier.u.integer = node; | |
589 | } else | |
590 | return -EPERM; | |
591 | break; | |
592 | case NODE_STRING: | |
593 | if (parent->type == NODE_TYPE_SPECIFIER) { | |
594 | parent->u.type_specifier.type = TYPESPEC_STRING; | |
595 | parent->u.type_specifier.u.string = node; | |
596 | } else | |
597 | return -EPERM; | |
598 | break; | |
599 | case NODE_ENUMERATOR: | |
600 | if (parent->type == NODE_ENUM) | |
601 | cds_list_add(&node->siblings, &parent->u._enum.enumerator_list); | |
602 | else | |
603 | return -EPERM; | |
604 | break; | |
605 | case NODE_ENUM: | |
606 | if (parent->type == NODE_TYPE_SPECIFIER) { | |
607 | parent->u.type_specifier.type = TYPESPEC_ENUM; | |
608 | parent->u.type_specifier.u._enum = node; | |
609 | } else | |
610 | return -EPERM; | |
611 | break; | |
612 | case NODE_STRUCT_OR_VARIANT_DECLARATION: | |
613 | switch (parent->type) { | |
614 | case NODE_STRUCT: | |
615 | cds_list_add(&node->siblings, &parent->u.variant.declaration_list); | |
616 | break; | |
617 | case NODE_VARIANT: | |
618 | cds_list_add(&node->siblings, &parent->u._struct.declaration_list); | |
619 | break; | |
620 | default: | |
621 | return -EINVAL; | |
622 | } | |
623 | break; | |
624 | case NODE_VARIANT: | |
625 | if (parent->type == NODE_TYPE_SPECIFIER) { | |
626 | parent->u.type_specifier.type = TYPESPEC_VARIANT; | |
627 | parent->u.type_specifier.u.variant = node; | |
628 | } else | |
629 | return -EPERM; | |
630 | break; | |
631 | case NODE_STRUCT: | |
632 | if (parent->type == NODE_TYPE_SPECIFIER) { | |
633 | parent->u.type_specifier.type = TYPESPEC_STRUCT; | |
634 | parent->u.type_specifier.u._struct = node; | |
635 | } else | |
636 | return -EPERM; | |
637 | break; | |
638 | ||
639 | case NODE_UNKNOWN: | |
640 | default: | |
641 | fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, | |
642 | (int) parent->type); | |
643 | return -EINVAL; | |
644 | } | |
645 | return 0; | |
646 | } | |
647 | ||
34d3acc4 | 648 | void yyerror(struct ctf_scanner *scanner, const char *str) |
8b9d5b5e MD |
649 | { |
650 | fprintf(stderr, "error %s\n", str); | |
651 | } | |
652 | ||
653 | int yywrap(void) | |
654 | { | |
655 | return 1; | |
656 | } | |
657 | ||
34d3acc4 | 658 | static void free_strings(struct cds_list_head *list) |
8b9d5b5e MD |
659 | { |
660 | struct gc_string *gstr, *tmp; | |
661 | ||
34d3acc4 | 662 | cds_list_for_each_entry_safe(gstr, tmp, list, gc) |
8b9d5b5e MD |
663 | free(gstr); |
664 | } | |
665 | ||
34d3acc4 | 666 | static struct ctf_ast *ctf_ast_alloc(void) |
8b9d5b5e | 667 | { |
34d3acc4 MD |
668 | struct ctf_ast *ast; |
669 | ||
670 | ast = malloc(sizeof(*ast)); | |
671 | if (!ast) | |
672 | return NULL; | |
673 | memset(ast, 0, sizeof(*ast)); | |
02b234c4 MD |
674 | CDS_INIT_LIST_HEAD(&ast->allocated_nodes); |
675 | ast->root.type = NODE_ROOT; | |
676 | CDS_INIT_LIST_HEAD(&ast->root.siblings); | |
677 | CDS_INIT_LIST_HEAD(&ast->root.u.root._typedef); | |
678 | CDS_INIT_LIST_HEAD(&ast->root.u.root.typealias); | |
679 | CDS_INIT_LIST_HEAD(&ast->root.u.root.declaration_specifier); | |
680 | CDS_INIT_LIST_HEAD(&ast->root.u.root.trace); | |
681 | CDS_INIT_LIST_HEAD(&ast->root.u.root.stream); | |
682 | CDS_INIT_LIST_HEAD(&ast->root.u.root.event); | |
34d3acc4 MD |
683 | return ast; |
684 | } | |
685 | ||
686 | static void ctf_ast_free(struct ctf_ast *ast) | |
687 | { | |
02b234c4 MD |
688 | struct ctf_node *node, *tmp; |
689 | ||
690 | cds_list_for_each_entry_safe(node, tmp, &ast->allocated_nodes, gc) | |
691 | free(node); | |
34d3acc4 MD |
692 | } |
693 | ||
694 | int ctf_scanner_append_ast(struct ctf_scanner *scanner) | |
695 | { | |
696 | return yyparse(scanner); | |
697 | } | |
698 | ||
699 | struct ctf_scanner *ctf_scanner_alloc(FILE *input) | |
700 | { | |
701 | struct ctf_scanner *scanner; | |
702 | int ret; | |
703 | ||
704 | scanner = malloc(sizeof(*scanner)); | |
705 | if (!scanner) | |
706 | return NULL; | |
707 | memset(scanner, 0, sizeof(*scanner)); | |
708 | ||
709 | ret = yylex_init_extra(scanner, &scanner->scanner); | |
710 | if (ret) { | |
711 | fprintf(stderr, "yylex_init error\n"); | |
712 | goto cleanup_scanner; | |
713 | } | |
714 | yyset_in(input, scanner); | |
715 | ||
716 | scanner->ast = ctf_ast_alloc(); | |
717 | if (!scanner->ast) | |
718 | goto cleanup_lexer; | |
719 | init_scope(&scanner->root_scope, NULL); | |
720 | CDS_INIT_LIST_HEAD(&scanner->allocated_strings); | |
721 | ||
722 | return scanner; | |
723 | ||
724 | cleanup_lexer: | |
725 | ret = yylex_destroy(scanner->scanner); | |
726 | if (!ret) | |
727 | fprintf(stderr, "yylex_destroy error\n"); | |
728 | cleanup_scanner: | |
729 | free(scanner); | |
730 | return NULL; | |
731 | } | |
732 | ||
733 | void ctf_scanner_free(struct ctf_scanner *scanner) | |
734 | { | |
735 | int ret; | |
736 | ||
737 | finalize_scope(&scanner->root_scope); | |
738 | free_strings(&scanner->allocated_strings); | |
739 | ctf_ast_free(scanner->ast); | |
740 | ret = yylex_destroy(scanner->scanner); | |
741 | if (ret) | |
742 | fprintf(stderr, "yylex_destroy error\n"); | |
743 | free(scanner); | |
744 | } | |
8b9d5b5e MD |
745 | |
746 | %} | |
747 | ||
34d3acc4 MD |
748 | %define api.pure |
749 | /* %locations */ | |
750 | %parse-param {struct ctf_scanner *scanner} | |
751 | %lex-param {struct ctf_scanner *scanner} | |
8b9d5b5e | 752 | %start file |
8b9d5b5e MD |
753 | %token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT |
754 | %token <gs> IDENTIFIER ID_TYPE | |
755 | %token ERROR | |
756 | %union | |
757 | { | |
758 | long long ll; | |
759 | char c; | |
760 | struct gc_string *gs; | |
761 | struct ctf_node *n; | |
762 | } | |
763 | ||
02b234c4 MD |
764 | %type <n> event_declaration |
765 | %type <n> ctf_assignment_expression_list | |
766 | %type <n> ctf_assignment_expression | |
767 | ||
8b9d5b5e MD |
768 | %% |
769 | ||
770 | file: | |
771 | declaration | |
772 | | file declaration | |
773 | ; | |
774 | ||
775 | keywords: | |
776 | VOID | |
777 | | CHAR | |
778 | | SHORT | |
779 | | INT | |
780 | | LONG | |
781 | | FLOAT | |
782 | | DOUBLE | |
783 | | SIGNED | |
784 | | UNSIGNED | |
785 | | _BOOL | |
786 | | _COMPLEX | |
787 | | FLOATING_POINT | |
788 | | INTEGER | |
789 | | STRING | |
790 | | ENUM | |
791 | | VARIANT | |
792 | | STRUCT | |
793 | | CONST | |
794 | | TYPEDEF | |
795 | | EVENT | |
796 | | STREAM | |
797 | | TRACE | |
798 | ; | |
799 | ||
800 | /* 1.5 Constants */ | |
801 | ||
802 | c_char_sequence: | |
803 | c_char | |
804 | | c_char_sequence c_char | |
805 | ; | |
806 | ||
807 | c_char: | |
808 | CHAR_STRING_TOKEN | |
809 | | ESCSEQ | |
810 | ; | |
811 | ||
812 | /* 1.6 String literals */ | |
813 | ||
814 | s_char_sequence: | |
815 | s_char | |
816 | | s_char_sequence s_char | |
817 | ; | |
818 | ||
819 | s_char: | |
820 | CHAR_STRING_TOKEN | |
821 | | ESCSEQ | |
822 | ; | |
823 | ||
824 | /* 2: Phrase structure grammar */ | |
825 | ||
826 | postfix_expression: | |
827 | IDENTIFIER | |
828 | | ID_TYPE | |
829 | | keywords | |
830 | | DECIMAL_CONSTANT | |
831 | | OCTAL_CONSTANT | |
832 | | HEXADECIMAL_CONSTANT | |
833 | | STRING_LITERAL_START DQUOTE | |
834 | | STRING_LITERAL_START s_char_sequence DQUOTE | |
835 | | CHARACTER_CONSTANT_START c_char_sequence SQUOTE | |
836 | | LPAREN unary_expression RPAREN | |
837 | | postfix_expression LSBRAC unary_expression RSBRAC | |
838 | | postfix_expression DOT IDENTIFIER | |
839 | | postfix_expression DOT ID_TYPE | |
840 | | postfix_expression RARROW IDENTIFIER | |
841 | | postfix_expression RARROW ID_TYPE | |
842 | ; | |
843 | ||
844 | unary_expression: | |
845 | postfix_expression | |
846 | | PLUS postfix_expression | |
847 | | MINUS postfix_expression | |
848 | ; | |
849 | ||
850 | unary_expression_or_range: | |
851 | unary_expression DOTDOTDOT unary_expression | |
852 | | unary_expression | |
853 | ; | |
854 | ||
855 | /* 2.2: Declarations */ | |
856 | ||
857 | declaration: | |
858 | declaration_specifiers SEMICOLON | |
859 | | event_declaration | |
860 | | stream_declaration | |
861 | | trace_declaration | |
862 | | declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON | |
863 | | TYPEDEF declaration_specifiers type_declarator_list SEMICOLON | |
864 | | declaration_specifiers TYPEDEF type_declarator_list SEMICOLON | |
865 | | TYPEALIAS declaration_specifiers abstract_declarator_list COLON declaration_specifiers abstract_type_declarator_list SEMICOLON | |
866 | | TYPEALIAS declaration_specifiers abstract_declarator_list COLON type_declarator_list SEMICOLON | |
867 | ; | |
868 | ||
869 | event_declaration: | |
870 | event_declaration_begin event_declaration_end | |
871 | | event_declaration_begin ctf_assignment_expression_list event_declaration_end | |
02b234c4 MD |
872 | { |
873 | $$ = make_node(scanner, NODE_EVENT); | |
874 | /* TODO */ | |
875 | } | |
8b9d5b5e MD |
876 | ; |
877 | ||
878 | event_declaration_begin: | |
879 | EVENT LBRAC | |
fce8006d | 880 | { push_scope(scanner); } |
8b9d5b5e MD |
881 | ; |
882 | ||
883 | event_declaration_end: | |
884 | RBRAC SEMICOLON | |
fce8006d | 885 | { pop_scope(scanner); } |
8b9d5b5e MD |
886 | ; |
887 | ||
888 | ||
889 | stream_declaration: | |
890 | stream_declaration_begin stream_declaration_end | |
891 | | stream_declaration_begin ctf_assignment_expression_list stream_declaration_end | |
892 | ; | |
893 | ||
894 | stream_declaration_begin: | |
895 | STREAM LBRAC | |
fce8006d | 896 | { push_scope(scanner); } |
8b9d5b5e MD |
897 | ; |
898 | ||
899 | stream_declaration_end: | |
900 | RBRAC SEMICOLON | |
fce8006d | 901 | { pop_scope(scanner); } |
8b9d5b5e MD |
902 | ; |
903 | ||
904 | ||
905 | trace_declaration: | |
906 | trace_declaration_begin trace_declaration_end | |
907 | | trace_declaration_begin ctf_assignment_expression_list trace_declaration_end | |
908 | ; | |
909 | ||
910 | trace_declaration_begin: | |
911 | TRACE LBRAC | |
fce8006d | 912 | { push_scope(scanner); } |
8b9d5b5e MD |
913 | ; |
914 | ||
915 | trace_declaration_end: | |
916 | RBRAC SEMICOLON | |
fce8006d | 917 | { pop_scope(scanner); } |
8b9d5b5e MD |
918 | ; |
919 | ||
920 | declaration_specifiers: | |
921 | CONST | |
922 | | type_specifier | |
923 | | declaration_specifiers CONST | |
924 | | declaration_specifiers type_specifier | |
925 | ; | |
926 | ||
927 | type_declarator_list: | |
928 | type_declarator | |
929 | | type_declarator_list COMMA type_declarator | |
930 | ; | |
931 | ||
932 | abstract_type_declarator_list: | |
933 | abstract_type_declarator | |
934 | | abstract_type_declarator_list COMMA abstract_type_declarator | |
935 | ; | |
936 | ||
937 | type_specifier: | |
938 | VOID | |
939 | | CHAR | |
940 | | SHORT | |
941 | | INT | |
942 | | LONG | |
943 | | FLOAT | |
944 | | DOUBLE | |
945 | | SIGNED | |
946 | | UNSIGNED | |
947 | | _BOOL | |
948 | | _COMPLEX | |
949 | | ID_TYPE | |
950 | | FLOATING_POINT LBRAC RBRAC | |
951 | | FLOATING_POINT LBRAC ctf_assignment_expression_list RBRAC | |
952 | | INTEGER LBRAC RBRAC | |
953 | | INTEGER LBRAC ctf_assignment_expression_list RBRAC | |
954 | | STRING LBRAC RBRAC | |
955 | | STRING LBRAC ctf_assignment_expression_list RBRAC | |
956 | | ENUM enum_type_specifier | |
957 | | VARIANT variant_type_specifier | |
958 | | STRUCT struct_type_specifier | |
959 | ; | |
960 | ||
961 | struct_type_specifier: | |
962 | struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end | |
963 | | IDENTIFIER struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end | |
964 | | ID_TYPE struct_declaration_begin struct_or_variant_declaration_list struct_declaration_end | |
965 | | IDENTIFIER | |
966 | | ID_TYPE | |
967 | ; | |
968 | ||
969 | struct_declaration_begin: | |
970 | LBRAC | |
fce8006d | 971 | { push_scope(scanner); } |
8b9d5b5e MD |
972 | ; |
973 | ||
974 | struct_declaration_end: | |
975 | RBRAC | |
fce8006d | 976 | { pop_scope(scanner); } |
8b9d5b5e MD |
977 | ; |
978 | ||
979 | variant_type_specifier: | |
980 | variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end | |
981 | | LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end | |
982 | | LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end | |
983 | | IDENTIFIER variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end | |
984 | | IDENTIFIER LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end | |
985 | | IDENTIFIER LT IDENTIFIER GT | |
986 | | IDENTIFIER LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end | |
987 | | IDENTIFIER LT ID_TYPE GT | |
988 | | ID_TYPE variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end | |
989 | | ID_TYPE LT IDENTIFIER GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end | |
990 | | ID_TYPE LT IDENTIFIER GT | |
991 | | ID_TYPE LT ID_TYPE GT variant_declaration_begin struct_or_variant_declaration_list variant_declaration_end | |
992 | | ID_TYPE LT ID_TYPE GT | |
993 | ; | |
994 | ||
995 | variant_declaration_begin: | |
996 | LBRAC | |
fce8006d | 997 | { push_scope(scanner); } |
8b9d5b5e MD |
998 | ; |
999 | ||
1000 | variant_declaration_end: | |
1001 | RBRAC | |
fce8006d | 1002 | { pop_scope(scanner); } |
8b9d5b5e MD |
1003 | ; |
1004 | ||
1005 | type_specifier_or_integer_constant: | |
1006 | declaration_specifiers | |
1007 | | DECIMAL_CONSTANT | |
1008 | | OCTAL_CONSTANT | |
1009 | | HEXADECIMAL_CONSTANT | |
1010 | ; | |
1011 | ||
1012 | enum_type_specifier: | |
1013 | LBRAC enumerator_list RBRAC | |
1014 | | LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC | |
1015 | | IDENTIFIER LBRAC enumerator_list RBRAC | |
1016 | | IDENTIFIER LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC | |
1017 | | ID_TYPE LBRAC enumerator_list RBRAC | |
1018 | | ID_TYPE LT type_specifier_or_integer_constant GT LBRAC enumerator_list RBRAC | |
1019 | | LBRAC enumerator_list COMMA RBRAC | |
1020 | | LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC | |
1021 | | IDENTIFIER LBRAC enumerator_list COMMA RBRAC | |
1022 | | IDENTIFIER LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC | |
1023 | | IDENTIFIER | |
1024 | | IDENTIFIER LT type_specifier_or_integer_constant GT | |
1025 | | ID_TYPE LBRAC enumerator_list COMMA RBRAC | |
1026 | | ID_TYPE LT type_specifier_or_integer_constant GT LBRAC enumerator_list COMMA RBRAC | |
1027 | | ID_TYPE | |
1028 | | ID_TYPE LT type_specifier_or_integer_constant GT | |
1029 | ; | |
1030 | ||
1031 | struct_or_variant_declaration_list: | |
1032 | /* empty */ | |
1033 | | struct_or_variant_declaration_list struct_or_variant_declaration | |
1034 | ; | |
1035 | ||
1036 | struct_or_variant_declaration: | |
1037 | specifier_qualifier_list struct_or_variant_declarator_list SEMICOLON | |
1038 | | specifier_qualifier_list TYPEDEF specifier_qualifier_list type_declarator_list SEMICOLON | |
1039 | | TYPEDEF specifier_qualifier_list type_declarator_list SEMICOLON | |
1040 | | specifier_qualifier_list TYPEDEF type_declarator_list SEMICOLON | |
1041 | | TYPEALIAS specifier_qualifier_list abstract_declarator_list COLON specifier_qualifier_list abstract_type_declarator_list SEMICOLON | |
1042 | | TYPEALIAS specifier_qualifier_list abstract_declarator_list COLON type_declarator_list SEMICOLON | |
1043 | ; | |
1044 | ||
1045 | specifier_qualifier_list: | |
1046 | CONST | |
1047 | | type_specifier | |
1048 | | specifier_qualifier_list CONST | |
1049 | | specifier_qualifier_list type_specifier | |
1050 | ; | |
1051 | ||
1052 | struct_or_variant_declarator_list: | |
1053 | struct_or_variant_declarator | |
1054 | | struct_or_variant_declarator_list COMMA struct_or_variant_declarator | |
1055 | ; | |
1056 | ||
1057 | struct_or_variant_declarator: | |
1058 | declarator | |
1059 | | COLON unary_expression | |
1060 | | declarator COLON unary_expression | |
1061 | ; | |
1062 | ||
1063 | enumerator_list: | |
1064 | enumerator | |
1065 | | enumerator_list COMMA enumerator | |
1066 | ; | |
1067 | ||
1068 | enumerator: | |
1069 | IDENTIFIER | |
1070 | | ID_TYPE | |
1071 | | keywords | |
1072 | | STRING_LITERAL_START DQUOTE | |
1073 | | STRING_LITERAL_START s_char_sequence DQUOTE | |
1074 | | IDENTIFIER EQUAL unary_expression_or_range | |
1075 | | ID_TYPE EQUAL unary_expression_or_range | |
1076 | | keywords EQUAL unary_expression_or_range | |
1077 | | STRING_LITERAL_START DQUOTE EQUAL unary_expression_or_range | |
1078 | | STRING_LITERAL_START s_char_sequence DQUOTE EQUAL unary_expression_or_range | |
1079 | ; | |
1080 | ||
1081 | abstract_declarator_list: | |
1082 | abstract_declarator | |
1083 | | abstract_declarator_list COMMA abstract_declarator | |
1084 | ; | |
1085 | ||
1086 | abstract_declarator: | |
1087 | direct_abstract_declarator | |
1088 | | pointer direct_abstract_declarator | |
1089 | ; | |
1090 | ||
1091 | direct_abstract_declarator: | |
1092 | /* empty */ | |
1093 | | IDENTIFIER | |
1094 | | LPAREN abstract_declarator RPAREN | |
1095 | | direct_abstract_declarator LSBRAC type_specifier_or_integer_constant RSBRAC | |
1096 | | direct_abstract_declarator LSBRAC RSBRAC | |
1097 | ; | |
1098 | ||
1099 | declarator: | |
1100 | direct_declarator | |
1101 | | pointer direct_declarator | |
1102 | ; | |
1103 | ||
1104 | direct_declarator: | |
1105 | IDENTIFIER | |
1106 | | LPAREN declarator RPAREN | |
1107 | | direct_declarator LSBRAC type_specifier_or_integer_constant RSBRAC | |
1108 | ; | |
1109 | ||
1110 | type_declarator: | |
1111 | direct_type_declarator | |
1112 | | pointer direct_type_declarator | |
1113 | ; | |
1114 | ||
1115 | direct_type_declarator: | |
1116 | IDENTIFIER | |
fce8006d | 1117 | { add_type(scanner, $1->s); } |
8b9d5b5e MD |
1118 | | LPAREN type_declarator RPAREN |
1119 | | direct_type_declarator LSBRAC type_specifier_or_integer_constant RSBRAC | |
1120 | ; | |
1121 | ||
1122 | abstract_type_declarator: | |
1123 | direct_abstract_type_declarator | |
1124 | | pointer direct_abstract_type_declarator | |
1125 | ; | |
1126 | ||
1127 | direct_abstract_type_declarator: | |
1128 | /* empty */ | |
1129 | | IDENTIFIER | |
fce8006d | 1130 | { add_type(scanner, $1->s); } |
8b9d5b5e MD |
1131 | | LPAREN abstract_type_declarator RPAREN |
1132 | | direct_abstract_type_declarator LSBRAC type_specifier_or_integer_constant RSBRAC | |
1133 | | direct_abstract_type_declarator LSBRAC RSBRAC | |
1134 | ; | |
1135 | ||
1136 | pointer: | |
1137 | STAR | |
1138 | | STAR pointer | |
1139 | | STAR type_qualifier_list pointer | |
1140 | ; | |
1141 | ||
1142 | type_qualifier_list: | |
1143 | CONST | |
1144 | | type_qualifier_list CONST | |
1145 | ; | |
1146 | ||
1147 | /* 2.3: CTF-specific declarations */ | |
1148 | ||
1149 | ctf_assignment_expression_list: | |
1150 | ctf_assignment_expression SEMICOLON | |
1151 | | ctf_assignment_expression_list ctf_assignment_expression SEMICOLON | |
1152 | ; | |
1153 | ||
1154 | ctf_assignment_expression: | |
1155 | unary_expression EQUAL unary_expression | |
02b234c4 MD |
1156 | { |
1157 | $$ = make_node(scanner, NODE_CTF_EXPRESSION); | |
1158 | /* TODO */ | |
1159 | ||
1160 | } | |
8b9d5b5e MD |
1161 | | unary_expression TYPEASSIGN type_specifier |
1162 | | declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list | |
1163 | | TYPEDEF declaration_specifiers type_declarator_list | |
1164 | | declaration_specifiers TYPEDEF type_declarator_list | |
1165 | | TYPEALIAS declaration_specifiers abstract_declarator_list COLON declaration_specifiers abstract_type_declarator_list | |
1166 | | TYPEALIAS declaration_specifiers abstract_declarator_list COLON type_declarator_list | |
1167 | ; |