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