dt_grammar.y revision 268578
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
212dtrace_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
217d_expression:	DT_CTX_DEXPR { $$ = NULL; }
218	|	DT_CTX_DEXPR expression { $$ = $2; }
219	;
220
221d_program:	DT_CTX_DPROG { $$ = dt_node_program(NULL); }
222	|	DT_CTX_DPROG translation_unit { $$ = dt_node_program($2); }
223	;
224
225d_type:		DT_CTX_DTYPE { $$ = NULL; }
226	|	DT_CTX_DTYPE type_name { $$ = (dt_node_t *)$2; }
227	;
228
229translation_unit:
230		external_declaration
231	|	translation_unit external_declaration { $$ = LINK($1, $2); }
232	;
233
234external_declaration:
235		inline_definition
236	|	translator_definition
237	|	provider_definition
238	|	probe_definition
239	|	declaration
240	;
241
242inline_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
258translator_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
269translator_member_list:
270		translator_member
271	|	translator_member_list translator_member { $$ = LINK($1,$2); }
272	;
273
274translator_member:
275		DT_TOK_IDENT DT_TOK_ASGN assignment_expression ';' {
276			$$ = dt_node_member(NULL, $1, $3);
277		}
278	;
279
280provider_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
289provider_probe_list:
290		provider_probe
291	|	provider_probe_list provider_probe { $$ = LINK($1, $2); }
292	;
293
294provider_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
304probe_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
334probe_specifiers:
335		probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; }
336	;
337
338probe_specifier_list:
339		probe_specifier
340	|	probe_specifier_list DT_TOK_COMMA probe_specifier {
341			$$ = LINK($1, $3);
342		}
343	;
344
345probe_specifier:
346		DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); }
347	|	DT_TOK_INT   { $$ = dt_node_pdesc_by_id($1); }
348	;
349
350statement_list:	statement { $$ = $1; }
351	|	statement_list ';' statement { $$ = LINK($1, $3); }
352	;
353
354statement:	/* empty */ { $$ = NULL; }
355	|	expression { $$ = dt_node_statement($1); }
356	;
357
358argument_expression_list:
359		assignment_expression
360	|	argument_expression_list DT_TOK_COMMA assignment_expression {
361			$$ = LINK($1, $3);
362		}
363	;
364
365primary_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
375postfix_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
420unary_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
434unary_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
442cast_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
449multiplicative_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
462additive_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
472shift_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
482relational_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
498equality_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
508and_expression:
509		equality_expression
510	|	and_expression DT_TOK_BAND equality_expression {
511			$$ = OP2(DT_TOK_BAND, $1, $3);
512		}
513	;
514
515exclusive_or_expression:
516		and_expression
517	|	exclusive_or_expression DT_TOK_XOR and_expression {
518			$$ = OP2(DT_TOK_XOR, $1, $3);
519		}
520	;
521
522inclusive_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
529logical_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
536logical_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
543logical_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
550constant_expression: conditional_expression
551	;
552
553conditional_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
559assignment_expression:
560		conditional_expression
561	|	unary_expression assignment_operator assignment_expression {
562			$$ = OP2($2, $1, $3);
563		}
564	;
565
566assignment_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
580expression:	assignment_expression
581	|	expression DT_TOK_COMMA assignment_expression {
582			$$ = OP2(DT_TOK_COMMA, $1, $3);
583		}
584	;
585
586declaration:	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
598declaration_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
607parameter_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
616storage_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
624d_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
630type_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
648type_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
653struct_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
661struct_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
667struct_or_union:
668		DT_KEY_STRUCT { $$ = CTF_K_STRUCT; }
669	|	DT_KEY_UNION { $$ = CTF_K_UNION; }
670	;
671
672struct_declaration_list:
673		struct_declaration
674	|	struct_declaration_list struct_declaration
675	;
676
677init_declarator_list:
678		init_declarator
679	|	init_declarator_list DT_TOK_COMMA init_declarator {
680			$$ = LINK($1, $3);
681		}
682	;
683
684init_declarator:
685		declarator {
686			$$ = dt_node_decl();
687			dt_decl_reset();
688		}
689	;
690
691struct_declaration:
692		specifier_qualifier_list struct_declarator_list ';' {
693			dt_decl_free(dt_decl_pop());
694		}
695	;
696
697specifier_qualifier_list:
698		type_specifier
699	|	type_specifier specifier_qualifier_list { $$ = $2; }
700	|	type_qualifier
701	|	type_qualifier specifier_qualifier_list { $$ = $2; }
702	;
703
704struct_declarator_list:
705		struct_declarator
706	|	struct_declarator_list DT_TOK_COMMA struct_declarator
707	;
708
709struct_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
717enum_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
723enum_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
729enumerator_list:
730		enumerator
731	|	enumerator_list DT_TOK_COMMA enumerator
732	;
733
734enumerator:	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
740declarator:	direct_declarator
741	|	pointer direct_declarator
742	;
743
744direct_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
751lparen:		DT_TOK_LPAR { dt_decl_top()->dd_attr |= DT_DA_PAREN; }
752	;
753
754pointer:	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
760type_qualifier_list:
761		type_qualifier
762	|	type_qualifier_list type_qualifier { $$ = $2; }
763	;
764
765parameter_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
773parameter_list:	parameter_declaration
774	|	parameter_list DT_TOK_COMMA parameter_declaration {
775			$$ = LINK($1, $3);
776		}
777	;
778
779parameter_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
791type_name:	specifier_qualifier_list {
792			$$ = dt_decl_pop();
793		}
794	|	specifier_qualifier_list abstract_declarator {
795			$$ = dt_decl_pop();
796		}
797	;
798
799abstract_declarator:
800		pointer
801	|	direct_abstract_declarator
802	|	pointer direct_abstract_declarator
803	;
804
805direct_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
813array:		DT_TOK_LBRAC { dt_scope_push(NULL, CTF_ERR); }
814		    array_parameters DT_TOK_RBRAC {
815			dt_scope_pop();
816			$$ = $3;
817		}
818	;
819
820array_parameters:
821		/* empty */ 		{ $$ = NULL; }
822	|	constant_expression	{ $$ = $1; }
823	|	parameter_type_list	{ $$ = $1; }
824	;
825
826function:	DT_TOK_LPAR { dt_scope_push(NULL, CTF_ERR); }
827		    function_parameters DT_TOK_RPAR {
828			dt_scope_pop();
829			$$ = $3;
830		}
831	;
832
833function_parameters:
834		/* empty */ 		{ $$ = NULL; }
835	|	parameter_type_list	{ $$ = $1; }
836	;
837
838%%
839