Commit | Line | Data |
---|---|---|
3cd4b0f8 MW |
1 | %{ |
2 | ||
3 | /* enable chatty error messages */ | |
4 | #define YYERROR_VERBOSE 1 | |
5 | ||
6 | /* figure out the location of a non-terminal. We discard extent information | |
7 | * but this isn't necessarily disastrous for our purpose. */ | |
8 | #define YYLLOC_DEFAULT(Current, Rhs, N) do { \ | |
9 | Current = Rhs[1]; \ | |
10 | } while(0) | |
11 | ||
12 | #include "cparse.h" | |
13 | #include <stddef.h> | |
14 | #include <assert.h> | |
15 | ||
16 | /* various bits of parsing infrastructure. increasingly i'm thinking some of | |
17 | * this belongs in its own file. still... */ | |
18 | ||
19 | /* hang on to both ends of a declarator while it is being parsed. This idiom | |
20 | * is used a lot with anonymous structures below, but we need an actual name | |
21 | * for the type for this particular case. */ | |
22 | struct parsing_declarator { | |
23 | struct declarator_type *first, **end; | |
24 | char *name; /* pick up name */ | |
25 | }; | |
26 | ||
27 | /* we need to know what declaration specifiers apply to the current | |
28 | * declarator. This means we need a stack of them to cope with nested | |
29 | * declarations. */ | |
30 | struct declaration_specifiers_stack { | |
31 | struct declaration_specifiers_stack *next; | |
32 | struct declaration_specifiers *ds; | |
33 | }; | |
34 | ||
35 | static struct declaration_specifiers_stack *declaration_specifiers_stack; | |
36 | ||
37 | static void push_declaration_specifiers(struct declaration_specifiers *ds) { | |
38 | struct declaration_specifiers_stack *n; | |
39 | ||
40 | NEW(n); | |
41 | n->next = declaration_specifiers_stack; | |
42 | n->ds = ds; | |
43 | declaration_specifiers_stack = n; | |
44 | } | |
45 | ||
46 | static void pop_declaration_specifiers(void) { | |
47 | /* can we have ->= and .= operators? */ | |
48 | declaration_specifiers_stack = declaration_specifiers_stack->next; | |
49 | } | |
50 | ||
51 | static struct declaration_specifiers *top_declaration_specifiers(void) { | |
52 | return declaration_specifiers_stack->ds; | |
53 | } | |
54 | ||
55 | static void check_top_declaration_specifier(struct declaration_specifiers *ds) { | |
56 | assert(declaration_specifiers_stack->ds == ds); | |
57 | } | |
58 | ||
59 | /* make up an actual declarator from a completed parse */ | |
60 | static struct declarator *get_declarator(struct parsing_declarator *pd, | |
61 | const struct location *where) { | |
62 | struct declarator *d; | |
63 | ||
64 | NEW(d); | |
65 | d->declarator_type = pd->first; | |
66 | d->declaration_specifiers = top_declaration_specifiers(); | |
67 | d->name = pd->name; | |
68 | d->where = *where; | |
69 | return d; | |
70 | } | |
71 | ||
72 | static struct expression expr_star; /* kludge */ | |
73 | ||
74 | static void warn_old_style_function(const struct location *where) { | |
75 | inputwarning(where, warn_obsolete, | |
76 | "old-style function declarator"); | |
77 | } | |
78 | ||
79 | void parser_init(FILE *fp) { | |
80 | yyin = fp; | |
81 | translation_unit = 0; | |
82 | scope_init(); | |
83 | gcc_extensions(); | |
84 | } | |
85 | ||
86 | %} | |
87 | ||
88 | %debug | |
89 | %verbose | |
90 | %expect 11 | |
91 | %defines | |
92 | ||
93 | %union { | |
94 | long i; | |
95 | unsigned long u; | |
96 | char *s; | |
97 | struct { | |
98 | char *name; | |
99 | struct declarator *declarator; | |
100 | } name; | |
101 | struct declaration_specifiers *declaration_specifiers; | |
102 | struct declarator *declarator; | |
103 | struct parsing_declarator *declarator_parse; | |
104 | struct declaration *declaration; | |
105 | struct identifier_list *identifier_list; | |
106 | struct expression *expression; | |
107 | struct expression_list *expression_list; | |
108 | struct initializer *initializer; | |
109 | struct designator *designator; | |
110 | struct external_declaration *external_declaration; | |
111 | struct function_definition *function_definition; | |
112 | struct enumerator *enumerator; | |
113 | struct statement *statement; | |
114 | /* transients for parsing lists */ | |
115 | struct { struct declarator *first, **end; } *declarator_list; | |
116 | struct { struct declaration *first, **end; } *declaration_list; | |
117 | struct { struct identifier_list *first, **end; } *identifier_list_parse; | |
118 | struct { struct expression_list *first, **end; } *parsing_expression_list; | |
119 | struct { struct initializer *first, **end; } *initializer_list; | |
120 | struct { struct designator *first, **end; } *designator_list; | |
121 | struct { struct external_declaration *first, **end; } *external_declaration_list; | |
122 | struct { struct enumerator *first, **end; } *enumerator_list; | |
123 | struct { struct statement *first, **end; } *statement_list; | |
124 | } | |
125 | ||
126 | %token <i> MEMBER "->" | |
127 | %token <i> INCR "++" | |
128 | %token <i> DECR "--" | |
129 | %token <i> SL "<<" | |
130 | %token <i> SR ">>" | |
131 | %token <i> LE "<=" | |
132 | %token <i> GE ">=" | |
133 | %token <i> EQ "==" | |
134 | %token <i> NE "!=" | |
135 | %token <i> AND "&&" | |
136 | %token <i> OR "||" | |
137 | %token <i> MULEQ "*=" | |
138 | %token <i> DIVEQ "/=" | |
139 | %token <i> MODEQ "%=" | |
140 | %token <i> ADDEQ "+=" | |
141 | %token <i> SUBEQ "-=" | |
142 | %token <i> SLEQ "<<=" | |
143 | %token <i> SREQ ">>=" | |
144 | %token <i> ANDEQ "&=" | |
145 | %token <i> XOREQ "^=" | |
146 | %token <i> OREQ "|=" | |
147 | ||
148 | %token <i> VARARG "..." | |
149 | ||
150 | %token <i> '&' | |
151 | %token <i> '*' | |
152 | %token <i> '+' | |
153 | %token <i> '-' | |
154 | %token <i> '~' | |
155 | %token <i> '!' | |
156 | %token <i> '/' | |
157 | %token <i> '%' | |
158 | %token <i> '<' | |
159 | %token <i> '>' | |
160 | %token <i> '^' | |
161 | %token <i> '|' | |
162 | %token <i> ',' | |
163 | %token <i> '=' | |
164 | %token <i> '.' | |
165 | ||
166 | %token <u> AUTO "auto" | |
167 | %token BREAK "break" | |
168 | %token CASE "case" | |
169 | %token <u> CHAR "char" | |
170 | %token <u> CONST "const" | |
171 | %token CONTINUE "continue" | |
172 | %token DEFAULT "default" | |
173 | %token DO "do" | |
174 | %token <u> DOUBLE "double" | |
175 | %token ELSE "else" | |
176 | %token ENUM "enum" | |
177 | %token <u> EXTERN "extern" | |
178 | %token <u> FLOAT "float" | |
179 | %token FOR "for" | |
180 | %token GOTO "goto" | |
181 | %token IF "if" | |
182 | %token <u> INLINE "inline" | |
183 | %token <u> INT "int" | |
184 | %token <u> LONG "long" | |
185 | %token <u> REGISTER "register" | |
186 | %token <u> RESTRICT "restrict" | |
187 | %token RETURN "return" | |
188 | %token <u> SHORT "short" | |
189 | %token <u> SIGNED "signed" | |
190 | %token SIZEOF "sizeof" | |
191 | %token <u> STATIC "static" | |
192 | %token <u> STRUCT "struct" | |
193 | %token SWITCH "switch" | |
194 | %token <u> TYPEDEF "typedef" | |
195 | %token <u> UNION "union" | |
196 | %token <u> UNSIGNED "unsigned" | |
197 | %token <u> VOID "void" | |
198 | %token <u> VOLATILE "volatile" | |
199 | %token WHILE "while" | |
200 | %token <u> BOOL "_Bool" | |
201 | %token <u> COMPLEX "_Complex" | |
202 | %token <u> IMAGINARY "_Imaginary" | |
203 | %token ATTRIBUTE "__attribute__" | |
204 | %token <u> GCC_VA_LIST "__builtin_va_list" | |
205 | %token GCC_VA_ARG "__builtin_va_arg" | |
206 | %token GCC_EXPECT "__builtin_expect" | |
207 | ||
208 | %token <name> TYPEDEF_NAME | |
209 | %token <name> ID | |
210 | %token <s> NUMBER | |
211 | %token <s> STRINGLIT | |
212 | %token <s> CHARLIT | |
213 | %token <s> WSTRINGLIT | |
214 | %token <s> WCHARLIT | |
215 | ||
216 | %type <u> storage_class_specifier | |
217 | %type <u> type_qualifier | |
218 | %type <u> struct_or_union | |
219 | %type <u> type_qualifier_list | |
220 | %type <u> type_qualifier_list_opt | |
221 | %type <u> function_specifier | |
222 | %type <u> basic_type_specifier | |
223 | ||
224 | %type <name> identifier | |
225 | %type <name> identifier_opt | |
226 | ||
227 | %type <declaration_specifiers> type_specifier | |
228 | %type <declaration_specifiers> struct_or_union_specifier | |
229 | %type <declaration_specifiers> enum_specifier | |
230 | ||
231 | %type <declaration_specifiers> declaration_specifiers | |
232 | %type <declaration_specifiers> declaration_specifiers_definition | |
233 | %type <declaration_specifiers> declaration_specifiers_opt | |
234 | %type <declaration_specifiers> parameter_declaration_specifiers | |
235 | %type <declaration_specifiers> specifier_qualifier_list | |
236 | %type <declaration_specifiers> specifier_qualifier_list_definition | |
237 | %type <declaration_specifiers> specifier_qualifier_list_opt | |
238 | %type <declaration_specifiers> array_specifiers | |
239 | %type <declarator> declarator_opt | |
240 | %type <declarator> init_declarator_list_opt | |
241 | %type <declarator> attributed_declarator | |
242 | %type <declarator> attributed_init_declarator | |
243 | %type <declarator> struct_declarator | |
244 | %type <declarator_list> init_declarator_list | |
245 | %type <declarator_list> struct_declarator_list | |
246 | ||
247 | %type <declarator_parse> declarator pointer | |
248 | %type <declarator_parse> direct_declarator | |
249 | %type <declarator_parse> abstract_declarator | |
250 | %type <declarator_parse> pointer_opt | |
251 | %type <declarator_parse> direct_abstract_declarator | |
252 | %type <declarator_parse> direct_abstract_declarator_opt | |
253 | %type <declarator_parse> abstract_declarator_opt | |
254 | ||
255 | %type <declaration> declaration | |
256 | %type <declaration> struct_declaration | |
257 | %type <declaration> parameter_declaration | |
258 | %type <declaration> type_name | |
259 | %type <declaration> main | |
260 | %type <external_declaration_list> translation_unit | |
261 | %type <external_declaration> external_declaration | |
262 | %type <declaration_list> struct_declaration_list | |
263 | %type <declaration_list> parameter_list | |
264 | %type <declaration_list> declaration_list_opt | |
265 | ||
266 | %type <identifier_list_parse> ID_list | |
267 | %type <identifier_list> ID_list_opt | |
268 | ||
269 | %type <expression> expression | |
270 | %type <expression> expression_opt | |
271 | %type <expression> primary_expression | |
272 | %type <expression> postfix_expression | |
273 | %type <expression> unary_expression | |
274 | %type <expression> cast_expression | |
275 | %type <expression> multiplicative_expression | |
276 | %type <expression> additive_expression | |
277 | %type <expression> shift_expression | |
278 | %type <expression> relational_expression | |
279 | %type <expression> equality_expression | |
280 | %type <expression> AND_expression | |
281 | %type <expression> exclusive_OR_expression | |
282 | %type <expression> inclusive_OR_expression | |
283 | %type <expression> logical_AND_expression | |
284 | %type <expression> logical_OR_expression | |
285 | %type <expression> conditional_expression | |
286 | %type <expression> assignment_expression | |
287 | %type <expression> constant_expression | |
288 | ||
289 | %type <expression> array_size | |
290 | ||
291 | %type <expression_list> argument_expression_list_opt | |
292 | %type <parsing_expression_list> argument_expression_list | |
293 | ||
294 | %type <initializer> initializer | |
295 | %type <initializer> designated_initializer | |
296 | %type <initializer_list> initializer_list | |
297 | %type <designator_list> designator_list | |
298 | %type <designator> designator | |
299 | ||
300 | %type <i> variadic | |
301 | %type <i> incrdecr | |
302 | %type <i> member_operator | |
303 | %type <i> unary_operator | |
304 | %type <i> multiplicative_operator | |
305 | %type <i> additive_operator | |
306 | %type <i> shift_operator | |
307 | %type <i> relational_operator | |
308 | %type <i> equality_operator | |
309 | %type <i> assignment_operator | |
310 | ||
311 | %type <i> comma_opt | |
312 | ||
313 | %type <function_definition> function_definition | |
314 | %type <enumerator> enumerator | |
315 | %type <enumerator> registered_enumerator | |
316 | %type <enumerator_list> enumerator_list | |
317 | ||
318 | %type <statement> statement | |
319 | %type <statement> function_body | |
320 | %type <statement> block_item | |
321 | %type <statement> else_part_opt | |
322 | %type <statement_list> block_item_list_opt | |
323 | ||
324 | %% | |
325 | ||
326 | main: | |
327 | translation_unit { | |
328 | translation_unit = $1->first; | |
329 | } | |
330 | ; | |
331 | ||
332 | /* kludge */ | |
333 | identifier: | |
334 | ID | |
335 | | TYPEDEF_NAME | |
336 | ; | |
337 | ||
338 | identifier_opt: | |
339 | identifier | |
340 | | { | |
341 | $$.name = 0; | |
342 | $$.declarator = 0; | |
343 | } | |
344 | ; | |
345 | ||
346 | /* C99 6.5 expressions */ | |
347 | ||
348 | primary_expression: | |
349 | ID { | |
350 | struct declarator *d; | |
351 | $$ = expr(ex_id, &@1); | |
352 | $$->u.name = $1.name; | |
353 | d = $1.declarator; | |
354 | if(!d) { | |
355 | inputerror(&@1, "undeclared identifier '%s'", $1.name); | |
356 | } else if(d->declaration_specifiers | |
357 | && (d->declaration_specifiers->storage_class_specifiers | |
358 | & SCS_TYPEDEF)) | |
359 | inputerror(&@1, "typedef-name '%s' used in expression", $1); | |
360 | else | |
361 | $$->valuetype = resolve_typedefs(d); | |
362 | } | |
363 | | NUMBER { | |
364 | $$ = expr(ex_number, &@1); | |
365 | $$->u.constant = $1; | |
366 | $$->valuetype = numbertype($$); | |
367 | } | |
368 | | CHARLIT { | |
369 | $$ = stringexpr(ex_char, $1, &@1); | |
370 | } | |
371 | | STRINGLIT { | |
372 | $$ = stringexpr(ex_string, $1, &@1); | |
373 | } | |
374 | | WCHARLIT { | |
375 | $$ = stringexpr(ex_wchar, $1, &@1); | |
376 | } | |
377 | | WSTRINGLIT { | |
378 | $$ = stringexpr(ex_wstring, $1, &@1); | |
379 | } | |
380 | | '(' expression ')' { | |
381 | $$ = paren($2, &@1); | |
382 | } | |
383 | ; | |
384 | ||
385 | postfix_expression: | |
386 | primary_expression | |
387 | | postfix_expression '[' expression ']' { | |
388 | $$ = binary('[', $1, $3, &@2); | |
389 | } | |
390 | | postfix_expression '(' argument_expression_list_opt ')' { | |
391 | $$ = fncallexpr($1, $3, &@2); | |
392 | } | |
393 | | GCC_VA_ARG '(' assignment_expression ',' type_name ')' { | |
394 | $$ = expr(ex_gcc_va_arg, &@2); | |
395 | $$->u.gcc_va_arg.arg = $3; | |
396 | $$->u.gcc_va_arg.type = $5; | |
397 | $$->valuetype = resolve_typedefs($5->declarator_list); | |
398 | } | |
399 | | GCC_EXPECT '(' assignment_expression ',' assignment_expression ')' { | |
400 | /* we can't hack this in as a function as the return type is that of | |
401 | * the LH argument */ | |
402 | $$ = expr(ex_gcc_expect, &@1); | |
403 | /* XXX does the LH arg undergo any implicit conversions? */ | |
404 | $$->u.binary.l = $3; | |
405 | $$->u.binary.r = $5; | |
406 | $$->valuetype = $3->valuetype; | |
407 | } | |
408 | | postfix_expression member_operator identifier { | |
409 | struct expression *e = expr(ex_id, &@2); | |
410 | e->u.name = $3.name; | |
411 | $$ = binary($2, $1, e, &@2); | |
412 | } | |
413 | | postfix_expression incrdecr { | |
414 | $$ = postfix($2, $1, &@2); | |
415 | } | |
416 | | '(' type_name ')' '{' initializer_list comma_opt '}' { | |
417 | $$ = expr(ex_compound_literal, &@1); | |
418 | $$->u.compound_literal.type = $2; | |
419 | $$->u.compound_literal.value = $5->first; | |
420 | declaration_constraints($2, dc_compound_literal); | |
421 | $$->valuetype = resolve_typedefs($2->declarator_list); | |
422 | } | |
423 | ; | |
424 | ||
425 | member_operator: '.' | "->" ; | |
426 | ||
427 | incrdecr: "++" | "--" ; | |
428 | ||
429 | argument_expression_list: | |
430 | assignment_expression { | |
431 | NEW($$); | |
432 | NEW($$->first); | |
433 | $$->first->e = $1; | |
434 | $$->end = &$$->first->next; | |
435 | } | |
436 | | argument_expression_list ',' assignment_expression { | |
437 | struct expression_list *e; | |
438 | NEW(e); | |
439 | e->e = $3; | |
440 | *($$ = $1)->end = e; | |
441 | $$->end = &e->next; | |
442 | } | |
443 | ; | |
444 | ||
445 | argument_expression_list_opt: | |
446 | argument_expression_list { $$ = $1->first; } | |
447 | | { $$ = 0; } | |
448 | ; | |
449 | ||
450 | unary_expression: | |
451 | postfix_expression | |
452 | | unary_operator cast_expression { | |
453 | $$ = prefix($1, $2, &@1); | |
454 | } | |
455 | | "sizeof" unary_expression { | |
456 | $$ = prefix(SIZEOF, $2, &@1); | |
457 | } | |
458 | | "sizeof" '(' type_name ')' { | |
459 | $$ = expr(ex_sizeof_type, &@1); | |
460 | $$->u.type = $3; | |
461 | declaration_constraints($3, dc_sizeof); | |
462 | } | |
463 | ; | |
464 | ||
465 | /* putting sizeof in here would conflict with sizeof(type) */ | |
466 | unary_operator: | |
467 | '&' | |
468 | | '*' | |
469 | | '+' | |
470 | | '-' | |
471 | | '~' | |
472 | | '!' | |
473 | | incrdecr | |
474 | ; | |
475 | ||
476 | cast_expression: | |
477 | unary_expression | |
478 | | '(' type_name ')' cast_expression { | |
479 | $$ = expr(ex_cast, &@1); | |
480 | $$->valuetype = $2->declarator_list; | |
481 | $$->u.cast = $4; | |
482 | declaration_constraints($2, dc_cast); | |
483 | } | |
484 | ; | |
485 | ||
486 | multiplicative_expression: | |
487 | cast_expression | |
488 | | multiplicative_expression multiplicative_operator cast_expression { | |
489 | $$ = binary($2, $1, $3, &@2); | |
490 | } | |
491 | ; | |
492 | ||
493 | multiplicative_operator: | |
494 | '*' | |
495 | | '/' | |
496 | | '%' | |
497 | ; | |
498 | ||
499 | additive_expression: | |
500 | multiplicative_expression | |
501 | | additive_expression additive_operator multiplicative_expression { | |
502 | $$ = binary($2, $1, $3, &@2); | |
503 | } | |
504 | ; | |
505 | ||
506 | additive_operator: | |
507 | '+' | |
508 | | '-' | |
509 | ; | |
510 | ||
511 | shift_expression: | |
512 | additive_expression | |
513 | | shift_expression shift_operator additive_expression { | |
514 | $$ = binary($2, $1, $3, &@2); | |
515 | } | |
516 | ; | |
517 | ||
518 | shift_operator: | |
519 | "<<" | |
520 | | ">>" | |
521 | ; | |
522 | ||
523 | relational_expression: | |
524 | shift_expression | |
525 | | relational_expression relational_operator shift_expression { | |
526 | $$ = binary($2, $1, $3, &@2); | |
527 | } | |
528 | ; | |
529 | ||
530 | relational_operator: | |
531 | '<' | |
532 | | '>' | |
533 | | "<=" | |
534 | | ">=" | |
535 | ; | |
536 | ||
537 | equality_expression: | |
538 | relational_expression | |
539 | | equality_expression equality_operator relational_expression { | |
540 | $$ = binary($2, $1, $3, &@2); | |
541 | } | |
542 | ; | |
543 | ||
544 | equality_operator: | |
545 | "==" | |
546 | | "!=" | |
547 | ; | |
548 | ||
549 | AND_expression: | |
550 | equality_expression | |
551 | | AND_expression '&' equality_expression { | |
552 | $$ = binary($2, $1, $3, &@2); | |
553 | } | |
554 | ; | |
555 | ||
556 | exclusive_OR_expression: | |
557 | AND_expression | |
558 | | exclusive_OR_expression '^' AND_expression { | |
559 | $$ = binary($2, $1, $3, &@2); | |
560 | } | |
561 | ; | |
562 | ||
563 | inclusive_OR_expression: | |
564 | exclusive_OR_expression | |
565 | | inclusive_OR_expression '|' exclusive_OR_expression { | |
566 | $$ = binary($2, $1, $3, &@2); | |
567 | } | |
568 | ; | |
569 | ||
570 | logical_AND_expression: | |
571 | inclusive_OR_expression | |
572 | | logical_AND_expression "&&" inclusive_OR_expression { | |
573 | $$ = binary($2, $1, $3, &@2); | |
574 | } | |
575 | ; | |
576 | ||
577 | logical_OR_expression: | |
578 | logical_AND_expression | |
579 | | logical_OR_expression "||" logical_AND_expression { | |
580 | $$ = binary($2, $1, $3, &@2); | |
581 | } | |
582 | ; | |
583 | ||
584 | conditional_expression: | |
585 | logical_OR_expression | |
586 | | logical_OR_expression '?' expression ':' conditional_expression { | |
587 | $$ = binary('?', $1, binary(':', $3, $5, &@4), &@2); | |
588 | } | |
589 | ; | |
590 | ||
591 | assignment_expression: | |
592 | conditional_expression | |
593 | | unary_expression assignment_operator assignment_expression { | |
594 | $$ = binary($2, $1, $3, &@2); | |
595 | } | |
596 | ; | |
597 | ||
598 | assignment_operator: | |
599 | '=' | |
600 | | "*=" | |
601 | | "/=" | |
602 | | "%=" | |
603 | | "+=" | |
604 | | "-=" | |
605 | | "<<=" | |
606 | | ">>=" | |
607 | | "&=" | |
608 | | "^=" | |
609 | | "|=" | |
610 | ; | |
611 | ||
612 | expression: | |
613 | assignment_expression | |
614 | | expression ',' assignment_expression { | |
615 | $$ = binary($2, $1, $3, &@2); | |
616 | } | |
617 | ; | |
618 | ||
619 | expression_opt: | |
620 | expression | |
621 | | { $$ = 0; } | |
622 | ; | |
623 | ||
624 | constant_expression: | |
625 | conditional_expression | |
626 | ; | |
627 | ||
628 | /* C99 6.7 declarations */ | |
629 | ||
630 | declaration: | |
631 | declaration_specifiers init_declarator_list_opt ';' { | |
632 | struct declaration_specifiers *ds = $1; | |
633 | struct declarator *decl = $2; | |
634 | ||
635 | check_top_declaration_specifier(ds); | |
636 | pop_declaration_specifiers(); | |
637 | /* will have already done add_declarator() */ | |
638 | NEW($$); | |
639 | $$->declaration_specifiers = ds; | |
640 | $$->declarator_list = decl; | |
641 | $$->where = @1; | |
642 | /* constraints checked by calling production */ | |
643 | } | |
644 | ; | |
645 | ||
646 | declaration_specifiers: | |
647 | declaration_specifiers_definition { | |
648 | push_declaration_specifiers($1); | |
649 | $$ = $1; | |
650 | } | |
651 | ; | |
652 | ||
653 | declaration_specifiers_definition: | |
654 | storage_class_specifier declaration_specifiers_opt { | |
655 | struct declaration_specifiers ds = { | |
656 | .type_specifiers = 0, | |
657 | .storage_class_specifiers = $1, | |
658 | .type_qualifiers = 0, | |
659 | .function_specifiers = 0, | |
660 | .name = 0, | |
661 | .structure = 0, | |
662 | .enumerators = 0, | |
663 | .type = 0, | |
664 | .enum_compat_type = 0 | |
665 | }; | |
666 | $$ = merge_declaration_specifiers($2, &ds); | |
667 | } | |
668 | | type_specifier declaration_specifiers_opt { | |
669 | $$ = merge_declaration_specifiers($2, $1); | |
670 | } | |
671 | | type_qualifier declaration_specifiers_opt { | |
672 | struct declaration_specifiers ds = { | |
673 | .type_specifiers = 0, | |
674 | .storage_class_specifiers = 0, | |
675 | .type_qualifiers = $1, | |
676 | .function_specifiers = 0, | |
677 | .name = 0, | |
678 | .structure = 0, | |
679 | .enumerators = 0, | |
680 | .type = 0, | |
681 | .enum_compat_type = 0 | |
682 | }; | |
683 | $$ = merge_declaration_specifiers($2, &ds); | |
684 | } | |
685 | | function_specifier declaration_specifiers_opt { | |
686 | struct declaration_specifiers ds = { | |
687 | .type_specifiers = 0, | |
688 | .storage_class_specifiers = 0, | |
689 | .type_qualifiers = 0, | |
690 | .function_specifiers = $1, | |
691 | .name = 0, | |
692 | .structure = 0, | |
693 | .enumerators = 0, | |
694 | .type = 0, | |
695 | .enum_compat_type = 0 | |
696 | }; | |
697 | $$ = merge_declaration_specifiers($2, &ds); | |
698 | } | |
699 | | attribute_specifier declaration_specifiers_opt { | |
700 | $$ = $2; | |
701 | } | |
702 | ; | |
703 | ||
704 | declaration_specifiers_opt: | |
705 | declaration_specifiers_definition | |
706 | | { | |
707 | NEW($$); | |
708 | } | |
709 | ; | |
710 | ||
711 | init_declarator_list_opt: | |
712 | init_declarator_list { $$ = $1->first; } | |
713 | | { $$ = 0; } | |
714 | ; | |
715 | ||
716 | init_declarator_list: | |
717 | attributed_init_declarator { | |
718 | NEW($$); | |
719 | $$->first = $1; | |
720 | $$->end = &$1->next; | |
721 | } | |
722 | | init_declarator_list ',' attribute_specifier_list attributed_init_declarator { | |
723 | $$ = $1; | |
724 | *$$->end = $4; | |
725 | $$->end = &$4->next; | |
726 | } | |
727 | ; | |
728 | ||
729 | attributed_declarator: | |
730 | declarator attribute_specifier_list { $$ = get_declarator($1, &@1); } | |
731 | ; | |
732 | ||
733 | attributed_init_declarator: | |
734 | attributed_declarator { | |
735 | add_declaration($$ = $1); | |
736 | } | |
737 | | attributed_declarator '=' { | |
738 | /* need to do this before we parse the initializer */ | |
739 | add_declaration($1); | |
740 | } initializer { | |
741 | $$ = $1; | |
742 | $$->initializer = $4; | |
743 | } | |
744 | ; | |
745 | ||
746 | /* C99 6.7.1 storage-class specifiers */ | |
747 | ||
748 | storage_class_specifier: | |
749 | "typedef" | |
750 | | "extern" | |
751 | | "static" | |
752 | | "auto" | |
753 | | "register" | |
754 | ; | |
755 | ||
756 | /* C99 6.7.2 type specifiers */ | |
757 | ||
758 | type_specifier: | |
759 | basic_type_specifier { | |
760 | NEW($$); | |
761 | $$->type_specifiers = $1; | |
762 | } | |
763 | | struct_or_union_specifier { $$ = $1; } | |
764 | | enum_specifier | |
765 | | TYPEDEF_NAME { | |
766 | NEW($$); | |
767 | $$->type_specifiers = TS_TYPEDEF; | |
768 | $$->name = $1.name; | |
769 | $$->type = $1.declarator; | |
770 | } | |
771 | ; | |
772 | ||
773 | basic_type_specifier: | |
774 | "void" | |
775 | | "char" | |
776 | | "short" | |
777 | | "int" | |
778 | | "long" | |
779 | | "float" | |
780 | | "double" | |
781 | | "signed" | |
782 | | "unsigned" | |
783 | | "_Bool" | |
784 | | "_Complex" | |
785 | | "_Imaginary" | |
786 | | GCC_VA_LIST | |
787 | ; | |
788 | ||
789 | /* C99 6.2.7.1 structure and union specifiers */ | |
790 | ||
791 | /* shift/reduce conflict between | |
792 | ID | |
793 | and | |
794 | ID '{' | |
795 | resolved by shifting (which is right) | |
796 | */ | |
797 | struct_or_union_specifier: | |
798 | struct_or_union identifier_opt '{' struct_declaration_list '}' attribute_specifier_list { | |
799 | NEW($$); | |
800 | $$->type_specifiers = $1 | TS_DEFINITION; | |
801 | $$->name = $2.name; | |
802 | $$->structure = $4->first; | |
803 | } | |
804 | | struct_or_union identifier { | |
805 | NEW($$); | |
806 | $$->type_specifiers = $1; | |
807 | $$->name = $2.name; | |
808 | } | |
809 | | struct_or_union { /* shift/reduce conflict */ | |
810 | inputerror(&@1, "structure must have a tag or a definition"); | |
811 | NEW($$); | |
812 | $$->type_specifiers = $1; | |
813 | } | |
814 | ; | |
815 | ||
816 | struct_or_union: | |
817 | "struct" attribute_specifier_list { $$ = $1; } | |
818 | | "union" attribute_specifier_list { $$ = $1; } | |
819 | ; | |
820 | ||
821 | struct_declaration_list: | |
822 | struct_declaration { | |
823 | NEW($$); | |
824 | $$->first = $1; | |
825 | $$->end = &$1->next; | |
826 | } | |
827 | | struct_declaration_list struct_declaration { | |
828 | $$ = $1; | |
829 | *$$->end = $2; | |
830 | $$->end = &$2->next; | |
831 | } | |
832 | ; | |
833 | ||
834 | struct_declaration: | |
835 | specifier_qualifier_list struct_declarator_list ';' { | |
836 | check_top_declaration_specifier($1); | |
837 | pop_declaration_specifiers(); | |
838 | NEW($$); | |
839 | $$->declaration_specifiers = $1; | |
840 | $$->declarator_list = $2->first; | |
841 | declaration_constraints($$, dc_struct_member); | |
842 | /* XXX perhaps add to a dictionary of struct/union declarations? */ | |
843 | $$->where = @1; | |
844 | } | |
845 | ; | |
846 | ||
847 | specifier_qualifier_list: | |
848 | specifier_qualifier_list_definition { | |
849 | push_declaration_specifiers($1); | |
850 | $$ = $1; | |
851 | } | |
852 | ; | |
853 | ||
854 | specifier_qualifier_list_definition: | |
855 | type_specifier specifier_qualifier_list_opt { | |
856 | $$ = merge_declaration_specifiers($2, $1); | |
857 | } | |
858 | | type_qualifier specifier_qualifier_list_opt { | |
859 | struct declaration_specifiers ds = { | |
860 | .type_specifiers = 0, | |
861 | .storage_class_specifiers = 0, | |
862 | .type_qualifiers = $1, | |
863 | .function_specifiers = 0, | |
864 | .name = 0, | |
865 | .structure = 0, | |
866 | .enumerators = 0, | |
867 | .type = 0, | |
868 | .enum_compat_type = 0 | |
869 | }; | |
870 | $$ = merge_declaration_specifiers($2, &ds); | |
871 | } | |
872 | | storage_class_specifier specifier_qualifier_list_opt { | |
873 | inputerror(&@1, "storage class specifiers not allowed here"); | |
874 | $$ = $2; | |
875 | } | |
876 | | function_specifier specifier_qualifier_list_opt { | |
877 | inputerror(&@1, "function specifiers not allowed here"); | |
878 | $$ = $2; | |
879 | } | |
880 | | attribute_specifier specifier_qualifier_list_opt { | |
881 | $$ = $2; | |
882 | } | |
883 | ; | |
884 | ||
885 | specifier_qualifier_list_opt: | |
886 | specifier_qualifier_list_definition | |
887 | | { | |
888 | NEW($$); | |
889 | } | |
890 | ; | |
891 | ||
892 | struct_declarator_list: | |
893 | struct_declarator attribute_specifier_list { | |
894 | NEW($$); | |
895 | $$->first = $1; | |
896 | $$->end = &$1->next; | |
897 | } | |
898 | | struct_declarator_list ',' attribute_specifier_list struct_declarator attribute_specifier_list { | |
899 | $$ = $1; | |
900 | *$$->end = $4; | |
901 | $$->end = &$4->next; | |
902 | } | |
903 | ; | |
904 | ||
905 | struct_declarator: | |
906 | attributed_declarator | |
907 | | declarator_opt ':' constant_expression { | |
908 | if(!($$ = $1)) { | |
909 | NEW($$); | |
910 | $$->declaration_specifiers = top_declaration_specifiers(); | |
911 | } | |
912 | $$->bits = $3; | |
913 | $$->where = @2; | |
914 | } | |
915 | ; | |
916 | ||
917 | /* C99 6.7.2.2 enumeration specifiers */ | |
918 | ||
919 | enum_specifier: | |
920 | enum identifier_opt '{' enumerator_list comma_opt '}' attribute_specifier_list { | |
921 | NEW($$); | |
922 | $$->type_specifiers = TS_ENUM | TS_DEFINITION; | |
923 | $$->name = $2.name; | |
924 | $$->enumerators = $4->first; | |
925 | $$->enum_compat_type = TS_INT; /* XXX */ | |
926 | if($5) | |
927 | inputwarning(&@5, warn_compat, | |
928 | "enumerator-list trailing comma not supported in C89 or C++"); | |
929 | /* XXX pick type and fix up the declarators of all the enumerators */ | |
930 | } | |
931 | | enum identifier { | |
932 | NEW($$); | |
933 | $$->type_specifiers = TS_ENUM; | |
934 | $$->name = $2.name; | |
935 | } | |
936 | ; | |
937 | ||
938 | enum: | |
939 | "enum" attribute_specifier_list | |
940 | ; | |
941 | ||
942 | enumerator_list: | |
943 | registered_enumerator { | |
944 | NEW($$); | |
945 | $$->first = $1; | |
946 | $$->end = &$1->next; | |
947 | } | |
948 | | enumerator_list ',' registered_enumerator { | |
949 | *($$ = $1)->end = $3; | |
950 | $$->end = &$3->next; | |
951 | } | |
952 | ; | |
953 | ||
954 | registered_enumerator: | |
955 | enumerator { | |
956 | struct declarator *d; | |
957 | NEW(d); | |
958 | d->name = $1->name; | |
959 | d->where = $$->where; | |
960 | NEW(d->declaration_specifiers); | |
961 | d->declaration_specifiers->type_specifiers = TS_INT; | |
962 | add_declaration(d); | |
963 | $$ = $1; | |
964 | $$->declarator = d; | |
965 | } | |
966 | ; | |
967 | ||
968 | enumerator: | |
969 | identifier { | |
970 | NEW($$); | |
971 | $$->name = $1.name; | |
972 | $$->where = @1; | |
973 | } | |
974 | | identifier '=' constant_expression { | |
975 | NEW($$); | |
976 | $$->name = $1.name; | |
977 | $$->value = $3; | |
978 | $$->where = @1; | |
979 | } | |
980 | ; | |
981 | ||
982 | /* C99 6.7.3 type qualifiers */ | |
983 | ||
984 | type_qualifier: | |
985 | "const" | |
986 | | "restrict" | |
987 | | "volatile" | |
988 | ; | |
989 | ||
990 | /* C99 6.7.4 function specifiers */ | |
991 | ||
992 | function_specifier: | |
993 | "inline" | |
994 | ; | |
995 | ||
996 | /* C99 6.7.5 declarators */ | |
997 | ||
998 | declarator_opt: | |
999 | declarator { $$ = get_declarator($1, &@1); } | |
1000 | | { $$ = 0; } | |
1001 | ; | |
1002 | ||
1003 | declarator: | |
1004 | pointer direct_declarator { | |
1005 | $$ = $2; | |
1006 | *$$->end = $1->first; | |
1007 | $$->end = $1->end; | |
1008 | } | |
1009 | | direct_declarator | |
1010 | ; | |
1011 | ||
1012 | direct_declarator: | |
1013 | ID { | |
1014 | NEW($$); | |
1015 | $$->end = &$$->first; | |
1016 | $$->name = $1.name; | |
1017 | /* XXX warn about redeclaration */ | |
1018 | } | |
1019 | | '(' attribute_specifier_list declarator ')' { | |
1020 | $$ = $3; | |
1021 | } | |
1022 | | direct_declarator '[' array_specifiers array_size ']' { | |
1023 | struct declarator_type *t; | |
1024 | ||
1025 | NEW(t); | |
1026 | $$ = $1; | |
1027 | t->type = dt_array; | |
1028 | t->type_qualifiers = $3->type_qualifiers; | |
1029 | t->storage_class_specifiers = $3->storage_class_specifiers; | |
1030 | if($4 == &expr_star) { | |
1031 | t->u.array.size = 0; | |
1032 | t->u.array.flags = AF_STAR; | |
1033 | } else | |
1034 | t->u.array.size = $4; | |
1035 | t->where = @2; | |
1036 | *$$->end = t; | |
1037 | $$->end = &t->next; | |
1038 | } | |
1039 | | direct_declarator '(' ID_list_opt ')' { | |
1040 | struct declarator_type *t; | |
1041 | ||
1042 | NEW(t); | |
1043 | $$ = $1; | |
1044 | t->type = dt_old_function; | |
1045 | t->u.old_function.args = $3; | |
1046 | t->where = @2; | |
1047 | *$$->end = t; | |
1048 | $$->end = &t->next; | |
1049 | warn_old_style_function(&@2); | |
1050 | } | |
1051 | | direct_declarator '(' parameter_list variadic ')' { | |
1052 | struct declarator_type *t; | |
1053 | ||
1054 | NEW(t); | |
1055 | $$ = $1; | |
1056 | t->type = dt_function; | |
1057 | t->u.function.args = $3->first; | |
1058 | t->u.function.variadic = $4; | |
1059 | t->where = @2; | |
1060 | *$$->end = t; | |
1061 | $$->end = &t->next; | |
1062 | } | |
1063 | ; | |
1064 | ||
1065 | array_size: | |
1066 | assignment_expression | |
1067 | | '*' { $$ = &expr_star; } | |
1068 | | { $$ = 0; } | |
1069 | ; | |
1070 | ||
1071 | array_specifiers: | |
1072 | type_qualifier_list_opt { | |
1073 | NEW($$); | |
1074 | } | |
1075 | | "static" type_qualifier_list_opt { | |
1076 | NEW($$); | |
1077 | $$->type_qualifiers = $2; | |
1078 | $$->storage_class_specifiers = SCS_STATIC; | |
1079 | } | |
1080 | | type_qualifier_list "static" { | |
1081 | NEW($$); | |
1082 | $$->type_qualifiers = $1; | |
1083 | $$->storage_class_specifiers = SCS_STATIC; | |
1084 | } | |
1085 | ; | |
1086 | ||
1087 | variadic: | |
1088 | ',' "..." { $$ = 1; } | |
1089 | | { $$ = 0; } | |
1090 | ; | |
1091 | ||
1092 | ||
1093 | pointer_opt: | |
1094 | pointer | |
1095 | | { | |
1096 | NEW($$); | |
1097 | $$->end = &$$->first; | |
1098 | } | |
1099 | ; | |
1100 | ||
1101 | pointer: | |
1102 | '*' type_qualifier_list_opt { | |
1103 | struct declarator_type *t; | |
1104 | ||
1105 | NEW(t); | |
1106 | t->type = dt_pointer; | |
1107 | t->type_qualifiers = $2; | |
1108 | t->where = @1; | |
1109 | NEW($$); | |
1110 | $$->first = t; | |
1111 | $$->end = &t->next; | |
1112 | } | |
1113 | | '*' type_qualifier_list_opt pointer { | |
1114 | struct declarator_type *t; | |
1115 | ||
1116 | NEW(t); | |
1117 | t->type = dt_pointer; | |
1118 | t->type_qualifiers = $2; | |
1119 | t->where = @1; | |
1120 | $$ = $3; | |
1121 | *$$->end = t; | |
1122 | $$->end = &t->next; | |
1123 | } | |
1124 | ; | |
1125 | ||
1126 | type_qualifier_list: | |
1127 | type_qualifier | |
1128 | | type_qualifier_list type_qualifier { $$ = $1 | $2; } | |
1129 | | type_qualifier_list attribute_specifier | |
1130 | ; | |
1131 | ||
1132 | type_qualifier_list_opt: | |
1133 | type_qualifier_list | |
1134 | | { $$ = 0; } | |
1135 | ; | |
1136 | ||
1137 | parameter_list: | |
1138 | parameter_declaration { | |
1139 | NEW($$); | |
1140 | $$->first = $1; | |
1141 | $$->end = &$1->next; | |
1142 | } | |
1143 | | parameter_list ',' parameter_declaration { | |
1144 | *$$->end = $3; | |
1145 | $$->end = &$3->next; | |
1146 | } | |
1147 | ; | |
1148 | ||
1149 | parameter_declaration_specifiers: | |
1150 | declaration_specifiers { | |
1151 | $$ = $1; | |
1152 | } | |
1153 | ; | |
1154 | ||
1155 | /* declaration_constraints will be checked recursively once we know what | |
1156 | * context we're really in (i.e. function-definition or not) */ | |
1157 | parameter_declaration: | |
1158 | parameter_declaration_specifiers declarator { | |
1159 | struct declarator *d = get_declarator($2, &@2); | |
1160 | check_top_declaration_specifier($1); | |
1161 | pop_declaration_specifiers(); | |
1162 | NEW($$); | |
1163 | $$->declaration_specifiers = $1; | |
1164 | $$->declarator_list = d; | |
1165 | $$->where = @1; | |
1166 | } | |
1167 | | parameter_declaration_specifiers abstract_declarator_opt { | |
1168 | struct declarator *d = get_declarator($2, $2->first ? &@2 : &@1); | |
1169 | check_top_declaration_specifier($1); | |
1170 | pop_declaration_specifiers(); | |
1171 | NEW($$); | |
1172 | $$->declaration_specifiers = $1; | |
1173 | $$->declarator_list = d; | |
1174 | $$->where = @1; | |
1175 | } | |
1176 | ; | |
1177 | ||
1178 | /* an old-style function declaration where all the parameter names match | |
1179 | * typedef names is ambiguous - it could be a parameter list where all the | |
1180 | * declarators are abstract. We resolve the ambiguity by assumiong that it is | |
1181 | * the latter, modern form. */ | |
1182 | ID_list_opt: | |
1183 | ID_list { $$ = $1->first; } | |
1184 | | { $$ = 0; } | |
1185 | ; | |
1186 | ||
1187 | ID_list: | |
1188 | ID { | |
1189 | struct identifier_list *i; | |
1190 | ||
1191 | NEW(i); | |
1192 | i->id = $1.name; | |
1193 | /* XXX warn about redeclaration */ | |
1194 | NEW($$); | |
1195 | $$->first = i; | |
1196 | $$->end = &i->next; | |
1197 | } | |
1198 | | ID_list ',' ID { | |
1199 | struct identifier_list *i; | |
1200 | ||
1201 | NEW(i); | |
1202 | i->id = $3.name; | |
1203 | /* XXX warn about redeclaration */ | |
1204 | *($$ = $1)->end = i; | |
1205 | $$->end = &i->next; | |
1206 | } | |
1207 | ; | |
1208 | ||
1209 | /* C99 6.7.6 type names */ | |
1210 | ||
1211 | type_name: | |
1212 | specifier_qualifier_list abstract_declarator_opt { | |
1213 | struct declarator *d = get_declarator($2, $2->first ? &@2 : &@1); | |
1214 | check_top_declaration_specifier($1); | |
1215 | pop_declaration_specifiers(); | |
1216 | NEW($$); | |
1217 | $$->declaration_specifiers = $1; | |
1218 | $$->declarator_list = d; | |
1219 | $$->where = @1; | |
1220 | /* declaration_constraints checked by calling production */ | |
1221 | } | |
1222 | ; | |
1223 | ||
1224 | direct_abstract_declarator: | |
1225 | '(' attribute_specifier_list abstract_declarator ')' { | |
1226 | $$ = $3; | |
1227 | } | |
1228 | | direct_abstract_declarator_opt '[' array_specifiers array_size ']' { | |
1229 | struct declarator_type *t; | |
1230 | ||
1231 | NEW(t); | |
1232 | $$ = $1; | |
1233 | t->type = dt_array; | |
1234 | t->type_qualifiers = $3->type_qualifiers; | |
1235 | t->storage_class_specifiers = $3->storage_class_specifiers; | |
1236 | if($4 == &expr_star) { | |
1237 | t->u.array.size = 0; | |
1238 | t->u.array.flags = AF_STAR; | |
1239 | } else | |
1240 | t->u.array.size = $4; | |
1241 | t->where = @2; | |
1242 | *$$->end = t; | |
1243 | $$->end = &t->next; | |
1244 | } | |
1245 | | direct_abstract_declarator_opt '(' ')' { | |
1246 | struct declarator_type *t; | |
1247 | ||
1248 | NEW(t); | |
1249 | $$ = $1; | |
1250 | t->type = dt_old_function; | |
1251 | t->u.old_function.args = 0; | |
1252 | t->where = @2; | |
1253 | *$$->end = t; | |
1254 | $$->end = &t->next; | |
1255 | warn_old_style_function(&@2); | |
1256 | } | |
1257 | | direct_abstract_declarator_opt '(' parameter_list variadic ')' { | |
1258 | struct declarator_type *t; | |
1259 | ||
1260 | NEW(t); | |
1261 | $$ = $1; | |
1262 | t->type = dt_function; | |
1263 | t->u.function.args = $3->first; | |
1264 | t->u.function.variadic = $4; | |
1265 | t->where = @2; | |
1266 | *$$->end = t; | |
1267 | $$->end = &t->next; | |
1268 | } | |
1269 | ; | |
1270 | ||
1271 | direct_abstract_declarator_opt: | |
1272 | direct_abstract_declarator | |
1273 | | { | |
1274 | NEW($$); | |
1275 | $$->end = &$$->first; | |
1276 | @$ = (struct location){path, line}; | |
1277 | } | |
1278 | ; | |
1279 | ||
1280 | abstract_declarator_opt: | |
1281 | abstract_declarator | |
1282 | | { | |
1283 | NEW($$); | |
1284 | $$->end = &$$->first; | |
1285 | @$ = (struct location){path, line}; | |
1286 | } | |
1287 | ; | |
1288 | ||
1289 | abstract_declarator: | |
1290 | pointer | |
1291 | | pointer_opt direct_abstract_declarator { | |
1292 | $$ = $2; | |
1293 | *$$->end = $1->first; | |
1294 | $$->end = $1->end; | |
1295 | } | |
1296 | ; | |
1297 | ||
1298 | /* C99 6.7.8 initializers */ | |
1299 | ||
1300 | initializer: | |
1301 | assignment_expression { | |
1302 | NEW($$); | |
1303 | $$->type = in_expr; | |
1304 | $$->u.expr = $1; | |
1305 | } | |
1306 | | '{' initializer_list comma_opt '}' { | |
1307 | NEW($$); | |
1308 | $$->type = in_list; | |
1309 | $$->u.list = $2->first; | |
1310 | } | |
1311 | ; | |
1312 | ||
1313 | comma_opt: | |
1314 | ',' { $$ = 1; } | |
1315 | | { $$ = 0; } | |
1316 | ; | |
1317 | ||
1318 | initializer_list: | |
1319 | designated_initializer { | |
1320 | NEW($$); | |
1321 | $$->first = $1; | |
1322 | $$->end = &$1->next; | |
1323 | } | |
1324 | | initializer_list ',' designated_initializer { | |
1325 | *($$ = $1)->end = $3; | |
1326 | $$->end = &$3->next; | |
1327 | } | |
1328 | ; | |
1329 | ||
1330 | designated_initializer: | |
1331 | designator_list '=' initializer { | |
1332 | ($$ = $3)->designator = $1->first; | |
1333 | $$->syntax = des_c99; | |
1334 | } | |
1335 | | designator initializer { | |
1336 | ($$ = $2)->designator = $1; | |
1337 | $$->syntax = des_gcc_raw; | |
1338 | inputwarning(&@1, warn_compat, | |
1339 | "non-portable GNU C initializer designator"); | |
1340 | } | |
1341 | | ID ':' initializer { | |
1342 | struct designator *d; | |
1343 | ||
1344 | NEW(d); | |
1345 | d->type = des_field; | |
1346 | d->u.name = $1.name; | |
1347 | d->where = @1; | |
1348 | ($$ = $3)->designator = d; | |
1349 | $$->syntax = des_gcc_colon; | |
1350 | inputwarning(&@1, warn_compat, | |
1351 | "non-portable GNU C initializer designator"); | |
1352 | } | |
1353 | | initializer | |
1354 | ; | |
1355 | ||
1356 | designator_list: | |
1357 | designator { | |
1358 | NEW($$); | |
1359 | $$->first = $1; | |
1360 | $$->end = &$1->next; | |
1361 | } | |
1362 | | designator_list designator { | |
1363 | *($$ = $1)->end = $2; | |
1364 | $$->end = &$2->next; | |
1365 | } | |
1366 | ; | |
1367 | ||
1368 | designator: | |
1369 | '[' constant_expression ']' { | |
1370 | NEW($$); | |
1371 | $$->type = des_expr; | |
1372 | $$->u.expr = $2; | |
1373 | $$->where = @1; | |
1374 | } | |
1375 | | '.' identifier { | |
1376 | NEW($$); | |
1377 | $$->type = des_field; | |
1378 | $$->u.name = $2.name; | |
1379 | $$->where = @1; | |
1380 | } | |
1381 | ; | |
1382 | ||
1383 | /* C99 6.8 statements and blocks */ | |
1384 | ||
1385 | statement: | |
1386 | identifier ':' attribute_specifier_list statement { | |
1387 | NEW($$); | |
1388 | $$->type = st_label; | |
1389 | $$->u.label.label = $1.name; | |
1390 | /* XXX warn about redeclaration */ | |
1391 | $$->u.label.body = $4; | |
1392 | $$->where = @1; | |
1393 | } | |
1394 | | "case" constant_expression ':' statement { | |
1395 | NEW($$); | |
1396 | $$->type = st_case; | |
1397 | $$->u.case_.value = $2; | |
1398 | $$->u.case_.body = $4; | |
1399 | $$->where = @1; | |
1400 | } | |
1401 | | "default" ':' statement { | |
1402 | NEW($$); | |
1403 | $$->type = st_default; | |
1404 | $$->u.default_ = $3; | |
1405 | $$->where = @1; | |
1406 | } | |
1407 | | "if" '(' expression ')' statement else_part_opt { | |
1408 | NEW($$); | |
1409 | $$->type = st_if; | |
1410 | $$->u.if_.cond = $3; | |
1411 | $$->u.if_.true = $5; | |
1412 | $$->u.if_.false = $6; | |
1413 | $$->where = @1; | |
1414 | } | |
1415 | | "switch" '(' expression ')' statement { | |
1416 | NEW($$); | |
1417 | $$->type = st_switch; | |
1418 | $$->u.switch_.cond = $3; | |
1419 | $$->u.switch_.body = $5; | |
1420 | $$->where = @1; | |
1421 | } | |
1422 | | expression_opt ';' { | |
1423 | NEW($$); | |
1424 | $$->type = st_expression; | |
1425 | $$->u.expression = $1; | |
1426 | $$->where = $1 ? @1 : @2; | |
1427 | } | |
1428 | | "while" '(' expression ')' statement { | |
1429 | NEW($$); | |
1430 | $$->type = st_while; | |
1431 | $$->u.while_.cond = $3; | |
1432 | $$->u.while_.body = $5; | |
1433 | $$->where = @1; | |
1434 | } | |
1435 | | "do" statement "while" '(' expression ')' ';' { | |
1436 | NEW($$); | |
1437 | $$->type = st_do; | |
1438 | $$->u.while_.cond = $5; | |
1439 | $$->u.while_.body = $2; | |
1440 | $$->where = @1; | |
1441 | } | |
1442 | | "for" '(' expression_opt ';' | |
1443 | expression_opt ';' | |
1444 | expression_opt ')' statement { | |
1445 | NEW($$); | |
1446 | $$->type = st_for; | |
1447 | $$->u.for_.init = $3; | |
1448 | $$->u.for_.cond = $5; | |
1449 | $$->u.for_.iter = $7; | |
1450 | $$->u.for_.body = $9; | |
1451 | $$->where = @1; | |
1452 | } | |
1453 | | "for" '(' | |
1454 | { enter_scope(); } | |
1455 | declaration | |
1456 | expression_opt ';' | |
1457 | expression_opt ')' statement { | |
1458 | NEW($$); | |
1459 | $$->type = st_for_declaration; | |
1460 | $$->u.for_declaration.init = $4; | |
1461 | $$->u.for_declaration.cond = $5; | |
1462 | $$->u.for_declaration.iter = $7; | |
1463 | $$->u.for_declaration.body = $9; | |
1464 | $$->where = @1; | |
1465 | exit_scope(); | |
1466 | } | |
1467 | | "goto" identifier ';' { | |
1468 | NEW($$); | |
1469 | $$->type = st_goto; | |
1470 | $$->u.goto_ = $2.name; | |
1471 | $$->where = @1; | |
1472 | } | |
1473 | | "continue" ';' { | |
1474 | NEW($$); | |
1475 | $$->type = st_continue; | |
1476 | $$->where = @1; | |
1477 | } | |
1478 | | "break" ';' { | |
1479 | NEW($$); | |
1480 | $$->type = st_break; | |
1481 | $$->where = @1; | |
1482 | } | |
1483 | | "return" expression_opt ';' { | |
1484 | NEW($$); | |
1485 | $$->type = st_return; | |
1486 | $$->u.expression = $2; | |
1487 | $$->where = @1; | |
1488 | } | |
1489 | | '{' { enter_scope(); } block_item_list_opt '}' { | |
1490 | NEW($$); | |
1491 | $$->type = st_compound; | |
1492 | $$->u.compound.body = $3->first; | |
1493 | $$->where = @1; | |
1494 | $$->u.compound.endwhere = @4; | |
1495 | /*$$->u.compound.scope = scope;*/ | |
1496 | exit_scope(); | |
1497 | } | |
1498 | ; | |
1499 | ||
1500 | /* scope handling for function bodies is done by function_definition */ | |
1501 | function_body: | |
1502 | '{' block_item_list_opt '}' { | |
1503 | NEW($$); | |
1504 | $$->type = st_compound; | |
1505 | $$->u.compound.body = $2->first; | |
1506 | $$->where = @1; | |
1507 | $$->u.compound.endwhere = @3; | |
1508 | /*$$->u.compound.scope = scope;*/ | |
1509 | } | |
1510 | ; | |
1511 | ||
1512 | block_item_list_opt: | |
1513 | block_item_list_opt block_item { | |
1514 | *($$ = $1)->end = $2; | |
1515 | $$->end = &$2->next; | |
1516 | } | |
1517 | | { | |
1518 | NEW($$); | |
1519 | $$->end = &$$->first; | |
1520 | } | |
1521 | ; | |
1522 | ||
1523 | block_item: | |
1524 | declaration { | |
1525 | NEW($$); | |
1526 | $$->type = st_declaration; | |
1527 | $$->u.declaration = $1; | |
1528 | $$->where = @1; | |
1529 | declaration_constraints($1, dc_block_scope); | |
1530 | } | |
1531 | | statement | |
1532 | ; | |
1533 | ||
1534 | /* shift/reduce conflict here */ | |
1535 | else_part_opt: | |
1536 | "else" statement { $$ = $2; } | |
1537 | | { $$ = 0; } | |
1538 | ; | |
1539 | ||
1540 | /* C99 6.9 external definitions */ | |
1541 | ||
1542 | translation_unit: | |
1543 | external_declaration { | |
1544 | NEW($$); | |
1545 | translation_unit = $$->first = $1; | |
1546 | $$->end = &$1->next; | |
1547 | } | |
1548 | | translation_unit external_declaration { | |
1549 | $$ = $1; | |
1550 | *$$->end = $2; | |
1551 | $$->end = &$2->next; | |
1552 | } | |
1553 | | translation_unit ';' { | |
1554 | inputerror(&@2, "redundant semicolon at top level"); | |
1555 | } | |
1556 | ; | |
1557 | ||
1558 | external_declaration: | |
1559 | declaration { | |
1560 | NEW($$); | |
1561 | $$->type = ed_declaration; | |
1562 | $$->u.declaration = $1; | |
1563 | declaration_constraints($1, dc_file_scope); | |
1564 | } | |
1565 | | function_definition { | |
1566 | NEW($$); | |
1567 | $$->type = ed_function_definition; | |
1568 | $$->u.function_definition = $1; | |
1569 | /* constraints checked in function_definition (i.e. before errors | |
1570 | * from the function body) */ | |
1571 | } | |
1572 | ; | |
1573 | ||
1574 | /* C99 6.9.1 function definitions */ | |
1575 | ||
1576 | function_definition: | |
1577 | declaration_specifiers attributed_declarator { | |
1578 | check_top_declaration_specifier($1); | |
1579 | pop_declaration_specifiers(); | |
1580 | declarator_constraints($1, $2, dc_function_definition, 0); | |
1581 | NEW($<declaration>$); | |
1582 | $<declaration>$->declaration_specifiers = $1; | |
1583 | $<declaration>$->declarator_list = $2; | |
1584 | $<declaration>$->where = @1; | |
1585 | add_declaration($2); | |
1586 | enter_scope(); | |
1587 | { | |
1588 | struct declarator *d; | |
1589 | NEW(d); | |
1590 | NEW(d->declaration_specifiers); | |
1591 | NEW(d->declarator_type); | |
1592 | d->name = xstrdup("__PRETTY_FUNCTION__"); | |
1593 | d->declaration_specifiers->type_qualifiers = TQ_CONST; | |
1594 | d->declaration_specifiers->type_specifiers = TS_CHAR; | |
1595 | d->declarator_type->type = dt_pointer; | |
1596 | add_declaration(d); | |
1597 | } | |
1598 | /* we had better be in the right scope before parsing the declaration | |
1599 | * list for old style functions */ | |
1600 | } declaration_list_opt { | |
1601 | struct declaration *decl; | |
1602 | struct declarator *d = 0; /* quieten compiler */ | |
1603 | ||
1604 | /* inject function args into scope */ | |
1605 | if($2->declarator_type) switch($2->declarator_type->type) { | |
1606 | case dt_function: | |
1607 | if(!is_void_args($2->declarator_type)) { | |
1608 | for(decl = $2->declarator_type->u.function.args; | |
1609 | decl; | |
1610 | decl = decl->next) { | |
1611 | decl->declarator_list->flags |= DF_PARAM; | |
1612 | add_declaration(decl->declarator_list); | |
1613 | } | |
1614 | } | |
1615 | if($4->first) | |
1616 | inputerror(&@4, "declaration-list not required for new-style function definitions"); | |
1617 | break; | |
1618 | case dt_old_function: | |
1619 | if($2->declarator_type->u.old_function.args) { | |
1620 | struct identifier_list *i; | |
1621 | ||
1622 | for(i = $2->declarator_type->u.old_function.args; | |
1623 | i; | |
1624 | i = i->next) { | |
1625 | for(decl = $4->first; | |
1626 | decl; | |
1627 | decl = decl->next) | |
1628 | for(d = decl->declarator_list; | |
1629 | d; | |
1630 | d = d->next) | |
1631 | if(!strcmp(d->name, i->id)) | |
1632 | break; | |
1633 | if(d) { | |
1634 | d->flags |= DF_PARAM; | |
1635 | add_declaration(d); | |
1636 | } else { | |
1637 | /* default to int */ | |
1638 | NEW(d); | |
1639 | d->name = i->id; | |
1640 | NEW(d->declaration_specifiers); | |
1641 | d->declaration_specifiers->type_specifiers = TS_INT; | |
1642 | d->flags = DF_PARAM; | |
1643 | add_declaration(d); | |
1644 | } | |
1645 | } | |
1646 | } | |
1647 | /* check that all the identifiers in the list are actually | |
1648 | * parameters */ | |
1649 | for(decl = $4->first; decl; decl = decl->next) | |
1650 | for(d = decl->declarator_list; | |
1651 | d; | |
1652 | d = d->next) { | |
1653 | struct identifier_list *i; | |
1654 | ||
1655 | for(i = $2->declarator_type->u.old_function.args; i; i = i->next) | |
1656 | if(!strcmp(d->name, i->id)) | |
1657 | break; | |
1658 | if(!i) | |
1659 | inputerror(&d->where, "'%s' is not a parameter", d->name); | |
1660 | } | |
1661 | break; | |
1662 | ||
1663 | default: /* quieten compiler */ | |
1664 | break; | |
1665 | } | |
1666 | } function_body { | |
1667 | NEW($$); | |
1668 | $$->declaration = $<declaration>3; | |
1669 | $$->args = $4->first; | |
1670 | $$->body = $6; | |
1671 | exit_scope(); | |
1672 | } | |
1673 | ; | |
1674 | ||
1675 | declaration_list_opt: | |
1676 | declaration_list_opt declaration { | |
1677 | *($$ = $1)->end = $2; | |
1678 | $$->end = &$2->next; | |
1679 | } | |
1680 | | { | |
1681 | NEW($$); | |
1682 | $$->end = &$$->first; | |
1683 | } | |
1684 | ; | |
1685 | ||
1686 | /* gcc.info attribute syntax */ | |
1687 | ||
1688 | attribute_specifier_list: | |
1689 | attribute_specifier_list attribute_specifier | |
1690 | | | |
1691 | ; | |
1692 | ||
1693 | attribute_specifier: | |
1694 | ATTRIBUTE '(' '(' attribute_list ')' ')' { | |
1695 | static int attr_warning; | |
1696 | if(!attr_warning++) | |
1697 | inputwarning(&@1, warn_compat, "GNU C attributes are ignored"); | |
1698 | } | |
1699 | ; | |
1700 | ||
1701 | attribute_list: | |
1702 | attribute_list attribute | |
1703 | | | |
1704 | ; | |
1705 | ||
1706 | attribute: | |
1707 | CONST { } | |
1708 | | identifier { } | |
1709 | | identifier '(' | |
1710 | { suppress_errors(); } | |
1711 | argument_expression_list_opt | |
1712 | { restore_errors(); } | |
1713 | ')' { } | |
1714 | ; | |
1715 | ||
1716 | %% | |
1717 | ||
1718 | /* | |
1719 | Local Variables: | |
1720 | c-basic-offset:2 | |
1721 | comment-column:40 | |
1722 | fill-column:79 | |
1723 | End: | |
1724 | */ |