1 %{
2 /*
3 * CDDL HEADER START
4 *
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License, Version 1.0 only
7 * (the "License"). You may not use this file except in compliance
8 * with the License.
9 *
10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 * or http://www.opensolaris.org/os/licensing.
12 * See the License for the specific language governing permissions
13 * and limitations under the License.
14 *
15 * When distributing Covered Code, include this CDDL HEADER in each
16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 * If applicable, add the following below this CDDL HEADER, with the
18 * fields enclosed by brackets "[]" replaced with your own identifying
19 * information: Portions Copyright [yyyy] [name of copyright owner]
20 *
21 * CDDL HEADER END
22 *
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <dt_impl.h>
30
31 #define OP1(op, c) dt_node_op1(op, c)
32 #define OP2(op, l, r) dt_node_op2(op, l, r)
33 #define OP3(x, y, z) dt_node_op3(x, y, z)
34 #define LINK(l, r) dt_node_link(l, r)
35 #define DUP(s) strdup(s)
36
37 %}
38
39 %union {
40 dt_node_t *l_node;
41 dt_decl_t *l_decl;
42 char *l_str;
43 uintmax_t l_int;
44 int l_tok;
45 }
46
47 %token DT_TOK_COMMA DT_TOK_ELLIPSIS
48 %token DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ
49 %token DT_TOK_DIV_EQ DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ
50 %token DT_TOK_LSH_EQ DT_TOK_RSH_EQ DT_TOK_QUESTION DT_TOK_COLON
51 %token DT_TOK_LOR DT_TOK_LXOR DT_TOK_LAND
52 %token DT_TOK_BOR DT_TOK_XOR DT_TOK_BAND DT_TOK_EQU DT_TOK_NEQ
53 %token DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE DT_TOK_LSH DT_TOK_RSH
54 %token DT_TOK_ADD DT_TOK_SUB DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
55 %token DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
56 %token DT_TOK_PREINC DT_TOK_POSTINC DT_TOK_PREDEC DT_TOK_POSTDEC
57 %token DT_TOK_IPOS DT_TOK_INEG DT_TOK_DEREF DT_TOK_ADDROF
58 %token DT_TOK_OFFSETOF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
59 %token DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
60
61 %token <l_str> DT_TOK_STRING
62 %token <l_str> DT_TOK_IDENT
63 %token <l_str> DT_TOK_PSPEC
64 %token <l_str> DT_TOK_AGG
65 %token <l_str> DT_TOK_TNAME
66 %token <l_int> DT_TOK_INT
67
68 %token DT_KEY_AUTO
69 %token DT_KEY_BREAK
70 %token DT_KEY_CASE
71 %token DT_KEY_CHAR
72 %token DT_KEY_CONST
73 %token DT_KEY_CONTINUE
74 %token DT_KEY_COUNTER
75 %token DT_KEY_DEFAULT
76 %token DT_KEY_DO
77 %token DT_KEY_DOUBLE
78 %token DT_KEY_ELSE
79 %token DT_KEY_ENUM
80 %token DT_KEY_EXTERN
81 %token DT_KEY_FLOAT
82 %token DT_KEY_FOR
83 %token DT_KEY_GOTO
84 %token DT_KEY_IF
85 %token DT_KEY_IMPORT
86 %token DT_KEY_INLINE
87 %token DT_KEY_INT
88 %token DT_KEY_LONG
89 %token DT_KEY_PROBE
90 %token DT_KEY_PROVIDER
91 %token DT_KEY_REGISTER
92 %token DT_KEY_RESTRICT
93 %token DT_KEY_RETURN
94 %token DT_KEY_SELF
95 %token DT_KEY_SHORT
96 %token DT_KEY_SIGNED
97 %token DT_KEY_STATIC
98 %token DT_KEY_STRING
99 %token DT_KEY_STRUCT
100 %token DT_KEY_SWITCH
101 %token DT_KEY_THIS
102 %token DT_KEY_TYPEDEF
103 %token DT_KEY_UNION
104 %token DT_KEY_UNSIGNED
105 %token DT_KEY_VOID
106 %token DT_KEY_VOLATILE
107 %token DT_KEY_WHILE
108 %token DT_KEY_XLATOR
109
110 %token DT_TOK_EPRED
111 %token DT_CTX_DEXPR
112 %token DT_CTX_DPROG
113 %token DT_CTX_DTYPE
114 %token DT_TOK_EOF 0
115
116 %left DT_TOK_COMMA
117 %right DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ DT_TOK_DIV_EQ
118 DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ DT_TOK_LSH_EQ
119 DT_TOK_RSH_EQ
120 %left DT_TOK_QUESTION DT_TOK_COLON
121 %left DT_TOK_LOR
122 %left DT_TOK_LXOR
123 %left DT_TOK_LAND
124 %left DT_TOK_BOR
125 %left DT_TOK_XOR
126 %left DT_TOK_BAND
127 %left DT_TOK_EQU DT_TOK_NEQ
128 %left DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE
129 %left DT_TOK_LSH DT_TOK_RSH
130 %left DT_TOK_ADD DT_TOK_SUB
131 %left DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
132 %right DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
133 DT_TOK_IPOS DT_TOK_INEG
134 %right DT_TOK_DEREF DT_TOK_ADDROF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
135 %left DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
136
137 %type <l_node> d_expression
138 %type <l_node> d_program
139 %type <l_node> d_type
140
141 %type <l_node> translation_unit
142 %type <l_node> external_declaration
143 %type <l_node> inline_definition
144 %type <l_node> translator_definition
145 %type <l_node> translator_member_list
146 %type <l_node> translator_member
147 %type <l_node> provider_definition
148 %type <l_node> provider_probe_list
149 %type <l_node> provider_probe
150 %type <l_node> probe_definition
151 %type <l_node> probe_specifiers
152 %type <l_node> probe_specifier_list
153 %type <l_node> probe_specifier
154 %type <l_node> statement_list
155 %type <l_node> statement
156 %type <l_node> declaration
157 %type <l_node> init_declarator_list
158 %type <l_node> init_declarator
159
160 %type <l_decl> type_specifier
161 %type <l_decl> type_qualifier
162 %type <l_decl> struct_or_union_specifier
163 %type <l_decl> specifier_qualifier_list
164 %type <l_decl> enum_specifier
165 %type <l_decl> declarator
166 %type <l_decl> direct_declarator
167 %type <l_decl> pointer
168 %type <l_decl> type_qualifier_list
169 %type <l_decl> type_name
170 %type <l_decl> abstract_declarator
171 %type <l_decl> direct_abstract_declarator
172
173 %type <l_node> parameter_type_list
174 %type <l_node> parameter_list
175 %type <l_node> parameter_declaration
176
177 %type <l_node> array
178 %type <l_node> array_parameters
179 %type <l_node> function
180 %type <l_node> function_parameters
181
182 %type <l_node> expression
183 %type <l_node> assignment_expression
184 %type <l_node> conditional_expression
185 %type <l_node> constant_expression
186 %type <l_node> logical_or_expression
187 %type <l_node> logical_xor_expression
188 %type <l_node> logical_and_expression
189 %type <l_node> inclusive_or_expression
190 %type <l_node> exclusive_or_expression
191 %type <l_node> and_expression
192 %type <l_node> equality_expression
193 %type <l_node> relational_expression
194 %type <l_node> shift_expression
195 %type <l_node> additive_expression
196 %type <l_node> multiplicative_expression
197 %type <l_node> cast_expression
198 %type <l_node> unary_expression
199 %type <l_node> postfix_expression
200 %type <l_node> primary_expression
201 %type <l_node> argument_expression_list
202
203 %type <l_tok> assignment_operator
204 %type <l_tok> unary_operator
205 %type <l_tok> struct_or_union
206
207 %%
208
209 dtrace_program: d_expression DT_TOK_EOF { return (dt_node_root($1)); }
210 | d_program DT_TOK_EOF { return (dt_node_root($1)); }
211 | d_type DT_TOK_EOF { return (dt_node_root($1)); }
212 ;
213
214 d_expression: DT_CTX_DEXPR { $$ = NULL; }
215 | DT_CTX_DEXPR expression { $$ = $2; }
216 ;
217
218 d_program: DT_CTX_DPROG { $$ = dt_node_program(NULL); }
219 | DT_CTX_DPROG translation_unit { $$ = dt_node_program($2); }
220 ;
221
222 d_type: DT_CTX_DTYPE { $$ = NULL; }
223 | DT_CTX_DTYPE type_name { $$ = (dt_node_t *)$2; }
224 ;
225
226 translation_unit:
227 external_declaration
228 | translation_unit external_declaration { $$ = LINK($1, $2); }
229 ;
230
231 external_declaration:
232 inline_definition
233 | translator_definition
234 | provider_definition
235 | probe_definition
236 | declaration
237 ;
238
239 inline_definition:
240 DT_KEY_INLINE declaration_specifiers declarator
241 { dt_scope_push(NULL, CTF_ERR); } DT_TOK_ASGN
242 assignment_expression ';' {
243 /*
244 * We push a new declaration scope before shifting the
245 * assignment_expression in order to preserve ds_class
246 * and ds_ident for use in dt_node_inline(). Once the
247 * entire inline_definition rule is matched, pop the
248 * scope and construct the inline using the saved decl.
249 */
250 dt_scope_pop();
251 $$ = dt_node_inline($6);
252 }
253 ;
254
255 translator_definition:
256 DT_KEY_XLATOR type_name DT_TOK_LT type_name
257 DT_TOK_IDENT DT_TOK_GT '{' translator_member_list '}' ';' {
258 $$ = dt_node_xlator($2, $4, $5, $8);
259 }
260 | DT_KEY_XLATOR type_name DT_TOK_LT type_name
261 DT_TOK_IDENT DT_TOK_GT '{' '}' ';' {
262 $$ = dt_node_xlator($2, $4, $5, NULL);
263 }
264 ;
265
266 translator_member_list:
267 translator_member
268 | translator_member_list translator_member { $$ = LINK($1,$2); }
269 ;
270
271 translator_member:
272 DT_TOK_IDENT DT_TOK_ASGN assignment_expression ';' {
273 $$ = dt_node_member(NULL, $1, $3);
274 }
275 ;
276
277 provider_definition:
278 DT_KEY_PROVIDER DT_TOK_IDENT '{' provider_probe_list '}' ';' {
279 $$ = dt_node_provider($2, $4);
280 }
281 | DT_KEY_PROVIDER DT_TOK_IDENT '{' '}' ';' {
282 $$ = dt_node_provider($2, NULL);
283 }
284 ;
285
286 provider_probe_list:
287 provider_probe
288 | provider_probe_list provider_probe { $$ = LINK($1, $2); }
289 ;
290
291 provider_probe:
292 DT_KEY_PROBE DT_TOK_IDENT function DT_TOK_COLON function ';' {
293 $$ = dt_node_probe($2, 2, $3, $5);
294 }
295 | DT_KEY_PROBE DT_TOK_IDENT function ';' {
296 $$ = dt_node_probe($2, 1, $3, NULL);
297 }
298 ;
299
300
301 probe_definition:
302 probe_specifiers {
303 /*
304 * If the input stream is a file, do not permit a probe
305 * specification without / <pred> / or { <act> } after
306 * it. This can only occur if the next token is EOF or
307 * an ambiguous predicate was slurped up as a comment.
308 * We cannot perform this check if input() is a string
309 * because dtrace(1M) [-fmnP] also use the compiler and
310 * things like dtrace -n BEGIN have to be accepted.
311 */
312 if (yypcb->pcb_fileptr != NULL) {
313 dnerror($1, D_SYNTAX, "expected predicate and/"
314 "or actions following probe description\n");
315 }
316 $$ = dt_node_clause($1, NULL, NULL);
317 }
318 | probe_specifiers '{' statement_list '}' {
319 $$ = dt_node_clause($1, NULL, $3);
320 }
321 | probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED {
322 dnerror($3, D_SYNTAX, "expected actions { } following "
323 "probe description and predicate\n");
324 }
325 | probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED
326 '{' statement_list '}' {
327 $$ = dt_node_clause($1, $3, $6);
328 }
329 ;
330
331 probe_specifiers:
332 probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; }
333 ;
334
335 probe_specifier_list:
336 probe_specifier
337 | probe_specifier_list DT_TOK_COMMA probe_specifier {
338 $$ = LINK($1, $3);
339 }
340 ;
341
342 probe_specifier:
343 DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); }
344 | DT_TOK_INT { $$ = dt_node_pdesc_by_id($1); }
345 ;
346
347 statement_list: statement { $$ = $1; }
348 | statement_list ';' statement { $$ = LINK($1, $3); }
349 ;
350
351 statement: /* empty */ { $$ = NULL; }
352 | expression { $$ = dt_node_statement($1); }
353 ;
354
355 argument_expression_list:
356 assignment_expression
357 | argument_expression_list DT_TOK_COMMA assignment_expression {
358 $$ = LINK($1, $3);
359 }
360 ;
361
362 primary_expression:
363 DT_TOK_IDENT { $$ = dt_node_ident($1); }
364 | DT_TOK_AGG { $$ = dt_node_ident($1); }
365 | DT_TOK_INT { $$ = dt_node_int($1); }
366 | DT_TOK_STRING { $$ = dt_node_string($1); }
367 | DT_KEY_SELF { $$ = dt_node_ident(DUP("self")); }
368 | DT_KEY_THIS { $$ = dt_node_ident(DUP("this")); }
369 | DT_TOK_LPAR expression DT_TOK_RPAR { $$ = $2; }
370 ;
371
372 postfix_expression:
373 primary_expression
374 | postfix_expression
375 DT_TOK_LBRAC argument_expression_list DT_TOK_RBRAC {
376 $$ = OP2(DT_TOK_LBRAC, $1, $3);
377 }
378 | postfix_expression DT_TOK_LPAR DT_TOK_RPAR {
379 $$ = dt_node_func($1, NULL);
380 }
381 | postfix_expression
382 DT_TOK_LPAR argument_expression_list DT_TOK_RPAR {
383 $$ = dt_node_func($1, $3);
384 }
385 | postfix_expression DT_TOK_DOT DT_TOK_IDENT {
386 $$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
387 }
388 | postfix_expression DT_TOK_DOT DT_TOK_TNAME {
389 $$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
390 }
391 | postfix_expression DT_TOK_PTR DT_TOK_IDENT {
392 $$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
393 }
394 | postfix_expression DT_TOK_PTR DT_TOK_TNAME {
395 $$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
396 }
397 | postfix_expression DT_TOK_ADDADD {
398 $$ = OP1(DT_TOK_POSTINC, $1);
399 }
400 | postfix_expression DT_TOK_SUBSUB {
401 $$ = OP1(DT_TOK_POSTDEC, $1);
402 }
403 | DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA
404 DT_TOK_IDENT DT_TOK_RPAR {
405 $$ = dt_node_offsetof($3, $5);
406 }
407 | DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA
408 DT_TOK_TNAME DT_TOK_RPAR {
409 $$ = dt_node_offsetof($3, $5);
410 }
411 | DT_TOK_XLATE DT_TOK_LT type_name DT_TOK_GT
412 DT_TOK_LPAR expression DT_TOK_RPAR {
413 $$ = OP2(DT_TOK_XLATE, dt_node_type($3), $6);
414 }
415 ;
416
417 unary_expression:
418 postfix_expression
419 | DT_TOK_ADDADD unary_expression { $$ = OP1(DT_TOK_PREINC, $2); }
420 | DT_TOK_SUBSUB unary_expression { $$ = OP1(DT_TOK_PREDEC, $2); }
421 | unary_operator cast_expression { $$ = OP1($1, $2); }
422 | DT_TOK_SIZEOF unary_expression { $$ = OP1(DT_TOK_SIZEOF, $2); }
423 | DT_TOK_SIZEOF DT_TOK_LPAR type_name DT_TOK_RPAR {
424 $$ = OP1(DT_TOK_SIZEOF, dt_node_type($3));
425 }
426 | DT_TOK_STRINGOF unary_expression {
427 $$ = OP1(DT_TOK_STRINGOF, $2);
428 }
429 ;
430
431 unary_operator: DT_TOK_BAND { $$ = DT_TOK_ADDROF; }
432 | DT_TOK_MUL { $$ = DT_TOK_DEREF; }
433 | DT_TOK_ADD { $$ = DT_TOK_IPOS; }
434 | DT_TOK_SUB { $$ = DT_TOK_INEG; }
435 | DT_TOK_BNEG { $$ = DT_TOK_BNEG; }
436 | DT_TOK_LNEG { $$ = DT_TOK_LNEG; }
437 ;
438
439 cast_expression:
440 unary_expression
441 | DT_TOK_LPAR type_name DT_TOK_RPAR cast_expression {
442 $$ = OP2(DT_TOK_LPAR, dt_node_type($2), $4);
443 }
444 ;
445
446 multiplicative_expression:
447 cast_expression
448 | multiplicative_expression DT_TOK_MUL cast_expression {
449 $$ = OP2(DT_TOK_MUL, $1, $3);
450 }
451 | multiplicative_expression DT_TOK_DIV cast_expression {
452 $$ = OP2(DT_TOK_DIV, $1, $3);
453 }
454 | multiplicative_expression DT_TOK_MOD cast_expression {
455 $$ = OP2(DT_TOK_MOD, $1, $3);
456 }
457 ;
458
459 additive_expression:
460 multiplicative_expression
461 | additive_expression DT_TOK_ADD multiplicative_expression {
462 $$ = OP2(DT_TOK_ADD, $1, $3);
463 }
464 | additive_expression DT_TOK_SUB multiplicative_expression {
465 $$ = OP2(DT_TOK_SUB, $1, $3);
466 }
467 ;
468
469 shift_expression:
470 additive_expression
471 | shift_expression DT_TOK_LSH additive_expression {
472 $$ = OP2(DT_TOK_LSH, $1, $3);
473 }
474 | shift_expression DT_TOK_RSH additive_expression {
475 $$ = OP2(DT_TOK_RSH, $1, $3);
476 }
477 ;
478
479 relational_expression:
480 shift_expression
481 | relational_expression DT_TOK_LT shift_expression {
482 $$ = OP2(DT_TOK_LT, $1, $3);
483 }
484 | relational_expression DT_TOK_GT shift_expression {
485 $$ = OP2(DT_TOK_GT, $1, $3);
486 }
487 | relational_expression DT_TOK_LE shift_expression {
488 $$ = OP2(DT_TOK_LE, $1, $3);
489 }
490 | relational_expression DT_TOK_GE shift_expression {
491 $$ = OP2(DT_TOK_GE, $1, $3);
492 }
493 ;
494
495 equality_expression:
496 relational_expression
497 | equality_expression DT_TOK_EQU relational_expression {
498 $$ = OP2(DT_TOK_EQU, $1, $3);
499 }
500 | equality_expression DT_TOK_NEQ relational_expression {
501 $$ = OP2(DT_TOK_NEQ, $1, $3);
502 }
503 ;
504
505 and_expression:
506 equality_expression
507 | and_expression DT_TOK_BAND equality_expression {
508 $$ = OP2(DT_TOK_BAND, $1, $3);
509 }
510 ;
511
512 exclusive_or_expression:
513 and_expression
514 | exclusive_or_expression DT_TOK_XOR and_expression {
515 $$ = OP2(DT_TOK_XOR, $1, $3);
516 }
517 ;
518
519 inclusive_or_expression:
520 exclusive_or_expression
521 | inclusive_or_expression DT_TOK_BOR exclusive_or_expression {
522 $$ = OP2(DT_TOK_BOR, $1, $3);
523 }
524 ;
525
526 logical_and_expression:
527 inclusive_or_expression
528 | logical_and_expression DT_TOK_LAND inclusive_or_expression {
529 $$ = OP2(DT_TOK_LAND, $1, $3);
530 }
531 ;
532
533 logical_xor_expression:
534 logical_and_expression
535 | logical_xor_expression DT_TOK_LXOR logical_and_expression {
536 $$ = OP2(DT_TOK_LXOR, $1, $3);
537 }
538 ;
539
540 logical_or_expression:
541 logical_xor_expression
542 | logical_or_expression DT_TOK_LOR logical_xor_expression {
543 $$ = OP2(DT_TOK_LOR, $1, $3);
544 }
545 ;
546
547 constant_expression: conditional_expression
548 ;
549
550 conditional_expression:
551 logical_or_expression
552 | logical_or_expression DT_TOK_QUESTION expression DT_TOK_COLON
553 conditional_expression { $$ = OP3($1, $3, $5); }
554 ;
555
556 assignment_expression:
557 conditional_expression
558 | unary_expression assignment_operator assignment_expression {
559 $$ = OP2($2, $1, $3);
560 }
561 ;
562
563 assignment_operator:
564 DT_TOK_ASGN { $$ = DT_TOK_ASGN; }
565 | DT_TOK_MUL_EQ { $$ = DT_TOK_MUL_EQ; }
566 | DT_TOK_DIV_EQ { $$ = DT_TOK_DIV_EQ; }
567 | DT_TOK_MOD_EQ { $$ = DT_TOK_MOD_EQ; }
568 | DT_TOK_ADD_EQ { $$ = DT_TOK_ADD_EQ; }
569 | DT_TOK_SUB_EQ { $$ = DT_TOK_SUB_EQ; }
570 | DT_TOK_LSH_EQ { $$ = DT_TOK_LSH_EQ; }
571 | DT_TOK_RSH_EQ { $$ = DT_TOK_RSH_EQ; }
572 | DT_TOK_AND_EQ { $$ = DT_TOK_AND_EQ; }
573 | DT_TOK_XOR_EQ { $$ = DT_TOK_XOR_EQ; }
574 | DT_TOK_OR_EQ { $$ = DT_TOK_OR_EQ; }
575 ;
576
577 expression: assignment_expression
578 | expression DT_TOK_COMMA assignment_expression {
579 $$ = OP2(DT_TOK_COMMA, $1, $3);
580 }
581 ;
582
583 declaration: declaration_specifiers ';' {
584 $$ = dt_node_decl();
585 dt_decl_free(dt_decl_pop());
586 yybegin(YYS_CLAUSE);
587 }
588 | declaration_specifiers init_declarator_list ';' {
589 $$ = $2;
590 dt_decl_free(dt_decl_pop());
591 yybegin(YYS_CLAUSE);
592 }
593 ;
594
595 declaration_specifiers:
596 d_storage_class_specifier
597 | d_storage_class_specifier declaration_specifiers
598 | type_specifier
599 | type_specifier declaration_specifiers
600 | type_qualifier
601 | type_qualifier declaration_specifiers
602 ;
603
604 parameter_declaration_specifiers:
605 storage_class_specifier
606 | storage_class_specifier declaration_specifiers
607 | type_specifier
608 | type_specifier declaration_specifiers
609 | type_qualifier
610 | type_qualifier declaration_specifiers
611 ;
612
613 storage_class_specifier:
614 DT_KEY_AUTO { dt_decl_class(DT_DC_AUTO); }
615 | DT_KEY_REGISTER { dt_decl_class(DT_DC_REGISTER); }
616 | DT_KEY_STATIC { dt_decl_class(DT_DC_STATIC); }
617 | DT_KEY_EXTERN { dt_decl_class(DT_DC_EXTERN); }
618 | DT_KEY_TYPEDEF { dt_decl_class(DT_DC_TYPEDEF); }
619 ;
620
621 d_storage_class_specifier:
622 storage_class_specifier
623 | DT_KEY_SELF { dt_decl_class(DT_DC_SELF); }
624 | DT_KEY_THIS { dt_decl_class(DT_DC_THIS); }
625 ;
626
627 type_specifier: DT_KEY_VOID { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("void")); }
628 | DT_KEY_CHAR { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("char")); }
629 | DT_KEY_SHORT { $$ = dt_decl_attr(DT_DA_SHORT); }
630 | DT_KEY_INT { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("int")); }
631 | DT_KEY_LONG { $$ = dt_decl_attr(DT_DA_LONG); }
632 | DT_KEY_FLOAT { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("float")); }
633 | DT_KEY_DOUBLE { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("double")); }
634 | DT_KEY_SIGNED { $$ = dt_decl_attr(DT_DA_SIGNED); }
635 | DT_KEY_UNSIGNED { $$ = dt_decl_attr(DT_DA_UNSIGNED); }
636 | DT_KEY_STRING {
637 $$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string"));
638 }
639 | DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_TYPEDEF, $1); }
640 | struct_or_union_specifier
641 | enum_specifier
642 ;
643
644 type_qualifier: DT_KEY_CONST { $$ = dt_decl_attr(DT_DA_CONST); }
645 | DT_KEY_RESTRICT { $$ = dt_decl_attr(DT_DA_RESTRICT); }
646 | DT_KEY_VOLATILE { $$ = dt_decl_attr(DT_DA_VOLATILE); }
647 ;
648
649 struct_or_union_specifier:
650 struct_or_union_definition struct_declaration_list '}' {
651 $$ = dt_scope_pop();
652 }
653 | struct_or_union DT_TOK_IDENT { $$ = dt_decl_spec($1, $2); }
654 | struct_or_union DT_TOK_TNAME { $$ = dt_decl_spec($1, $2); }
655 ;
656
657 struct_or_union_definition:
658 struct_or_union '{' { dt_decl_sou($1, NULL); }
659 | struct_or_union DT_TOK_IDENT '{' { dt_decl_sou($1, $2); }
660 | struct_or_union DT_TOK_TNAME '{' { dt_decl_sou($1, $2); }
661 ;
662
663 struct_or_union:
664 DT_KEY_STRUCT { $$ = CTF_K_STRUCT; }
665 | DT_KEY_UNION { $$ = CTF_K_UNION; }
666 ;
667
668 struct_declaration_list:
669 struct_declaration
670 | struct_declaration_list struct_declaration
671 ;
672
673 init_declarator_list:
674 init_declarator
675 | init_declarator_list DT_TOK_COMMA init_declarator {
676 $$ = LINK($1, $3);
677 }
678 ;
679
680 init_declarator:
681 declarator {
682 $$ = dt_node_decl();
683 dt_decl_reset();
684 }
685 ;
686
687 struct_declaration:
688 specifier_qualifier_list struct_declarator_list ';' {
689 dt_decl_free(dt_decl_pop());
690 }
691 ;
692
693 specifier_qualifier_list:
694 type_specifier
695 | type_specifier specifier_qualifier_list { $$ = $2; }
696 | type_qualifier
697 | type_qualifier specifier_qualifier_list { $$ = $2; }
698 ;
699
700 struct_declarator_list:
701 struct_declarator
702 | struct_declarator_list DT_TOK_COMMA struct_declarator
703 ;
704
705 struct_declarator:
706 declarator { dt_decl_member(NULL); }
707 | DT_TOK_COLON constant_expression { dt_decl_member($2); }
708 | declarator DT_TOK_COLON constant_expression {
709 dt_decl_member($3);
710 }
711 ;
712
713 enum_specifier:
714 enum_definition enumerator_list '}' { $$ = dt_scope_pop(); }
715 | DT_KEY_ENUM DT_TOK_IDENT { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
716 | DT_KEY_ENUM DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
717 ;
718
719 enum_definition:
720 DT_KEY_ENUM '{' { dt_decl_enum(NULL); }
721 | DT_KEY_ENUM DT_TOK_IDENT '{' { dt_decl_enum($2); }
722 | DT_KEY_ENUM DT_TOK_TNAME '{' { dt_decl_enum($2); }
723 ;
724
725 enumerator_list:
726 enumerator
727 | enumerator_list DT_TOK_COMMA enumerator
728 ;
729
730 enumerator: DT_TOK_IDENT { dt_decl_enumerator($1, NULL); }
731 | DT_TOK_IDENT DT_TOK_ASGN expression {
732 dt_decl_enumerator($1, $3);
733 }
734 ;
735
736 declarator: direct_declarator
737 | pointer direct_declarator
738 ;
739
740 direct_declarator:
741 DT_TOK_IDENT { $$ = dt_decl_ident($1); }
742 | lparen declarator DT_TOK_RPAR { $$ = $2; }
743 | direct_declarator array { dt_decl_array($2); }
744 | direct_declarator function { dt_decl_func($1, $2); }
745 ;
746
747 lparen: DT_TOK_LPAR { dt_decl_top()->dd_attr |= DT_DA_PAREN; }
748 ;
749
750 pointer: DT_TOK_MUL { $$ = dt_decl_ptr(); }
751 | DT_TOK_MUL type_qualifier_list { $$ = dt_decl_ptr(); }
752 | DT_TOK_MUL pointer { $$ = dt_decl_ptr(); }
753 | DT_TOK_MUL type_qualifier_list pointer { $$ = dt_decl_ptr(); }
754 ;
755
756 type_qualifier_list:
757 type_qualifier
758 | type_qualifier_list type_qualifier { $$ = $2; }
759 ;
760
761 parameter_type_list:
762 parameter_list
763 | DT_TOK_ELLIPSIS { $$ = dt_node_vatype(); }
764 | parameter_list DT_TOK_COMMA DT_TOK_ELLIPSIS {
765 $$ = LINK($1, dt_node_vatype());
766 }
767 ;
768
769 parameter_list: parameter_declaration
770 | parameter_list DT_TOK_COMMA parameter_declaration {
771 $$ = LINK($1, $3);
772 }
773 ;
774
775 parameter_declaration:
776 parameter_declaration_specifiers {
777 $$ = dt_node_type(NULL);
778 }
779 | parameter_declaration_specifiers declarator {
780 $$ = dt_node_type(NULL);
781 }
782 | parameter_declaration_specifiers abstract_declarator {
783 $$ = dt_node_type(NULL);
784 }
785 ;
786
787 type_name: specifier_qualifier_list {
788 $$ = dt_decl_pop();
789 }
790 | specifier_qualifier_list abstract_declarator {
791 $$ = dt_decl_pop();
792 }
793 ;
794
795 abstract_declarator:
796 pointer
797 | direct_abstract_declarator
798 | pointer direct_abstract_declarator
799 ;
800
801 direct_abstract_declarator:
802 lparen abstract_declarator DT_TOK_RPAR { $$ = $2; }
803 | direct_abstract_declarator array { dt_decl_array($2); }
804 | array { dt_decl_array($1); $$ = NULL; }
805 | direct_abstract_declarator function { dt_decl_func($1, $2); }
806 | function { dt_decl_func(NULL, $1); }
807 ;
808
809 array: DT_TOK_LBRAC { dt_scope_push(NULL, CTF_ERR); }
810 array_parameters DT_TOK_RBRAC {
811 dt_scope_pop();
812 $$ = $3;
813 }
814 ;
815
816 array_parameters:
817 /* empty */ { $$ = NULL; }
818 | constant_expression { $$ = $1; }
819 | parameter_type_list { $$ = $1; }
820 ;
821
822 function: DT_TOK_LPAR { dt_scope_push(NULL, CTF_ERR); }
823 function_parameters DT_TOK_RPAR {
824 dt_scope_pop();
825 $$ = $3;
826 }
827 ;
828
829 function_parameters:
830 /* empty */ { $$ = NULL; }
831 | parameter_type_list { $$ = $1; }
832 ;
833
834 %%