xref: /onnv-gate/usr/src/lib/libdtrace/common/dt_grammar.y (revision 1222:6c8cd7eac61b)
10Sstevel@tonic-gate %{
20Sstevel@tonic-gate /*
30Sstevel@tonic-gate  * CDDL HEADER START
40Sstevel@tonic-gate  *
50Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
60Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
70Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
80Sstevel@tonic-gate  * with the License.
90Sstevel@tonic-gate  *
100Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
110Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
120Sstevel@tonic-gate  * See the License for the specific language governing permissions
130Sstevel@tonic-gate  * and limitations under the License.
140Sstevel@tonic-gate  *
150Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
160Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
170Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
180Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
190Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
200Sstevel@tonic-gate  *
210Sstevel@tonic-gate  * CDDL HEADER END
220Sstevel@tonic-gate  *
23*1222Smws  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <dt_impl.h>
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #define	OP1(op, c)	dt_node_op1(op, c)
320Sstevel@tonic-gate #define	OP2(op, l, r)	dt_node_op2(op, l, r)
330Sstevel@tonic-gate #define	OP3(x, y, z)	dt_node_op3(x, y, z)
340Sstevel@tonic-gate #define	LINK(l, r)	dt_node_link(l, r)
350Sstevel@tonic-gate #define	DUP(s)		strdup(s)
360Sstevel@tonic-gate 
370Sstevel@tonic-gate %}
380Sstevel@tonic-gate 
390Sstevel@tonic-gate %union {
400Sstevel@tonic-gate 	dt_node_t *l_node;
410Sstevel@tonic-gate 	dt_decl_t *l_decl;
420Sstevel@tonic-gate 	char *l_str;
430Sstevel@tonic-gate 	uintmax_t l_int;
440Sstevel@tonic-gate 	int l_tok;
450Sstevel@tonic-gate }
460Sstevel@tonic-gate 
470Sstevel@tonic-gate %token	DT_TOK_COMMA DT_TOK_ELLIPSIS
480Sstevel@tonic-gate %token	DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ
490Sstevel@tonic-gate %token	DT_TOK_DIV_EQ DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ
500Sstevel@tonic-gate %token	DT_TOK_LSH_EQ DT_TOK_RSH_EQ DT_TOK_QUESTION DT_TOK_COLON
510Sstevel@tonic-gate %token	DT_TOK_LOR DT_TOK_LXOR DT_TOK_LAND
520Sstevel@tonic-gate %token	DT_TOK_BOR DT_TOK_XOR DT_TOK_BAND DT_TOK_EQU DT_TOK_NEQ
530Sstevel@tonic-gate %token	DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE DT_TOK_LSH DT_TOK_RSH
540Sstevel@tonic-gate %token	DT_TOK_ADD DT_TOK_SUB DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
550Sstevel@tonic-gate %token	DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
560Sstevel@tonic-gate %token	DT_TOK_PREINC DT_TOK_POSTINC DT_TOK_PREDEC DT_TOK_POSTDEC
570Sstevel@tonic-gate %token	DT_TOK_IPOS DT_TOK_INEG DT_TOK_DEREF DT_TOK_ADDROF
580Sstevel@tonic-gate %token	DT_TOK_OFFSETOF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
590Sstevel@tonic-gate %token	DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
600Sstevel@tonic-gate 
610Sstevel@tonic-gate %token <l_str>	DT_TOK_STRING
620Sstevel@tonic-gate %token <l_str>	DT_TOK_IDENT
630Sstevel@tonic-gate %token <l_str>	DT_TOK_PSPEC
640Sstevel@tonic-gate %token <l_str>	DT_TOK_AGG
650Sstevel@tonic-gate %token <l_str>	DT_TOK_TNAME
660Sstevel@tonic-gate %token <l_int>	DT_TOK_INT
670Sstevel@tonic-gate 
680Sstevel@tonic-gate %token	DT_KEY_AUTO
690Sstevel@tonic-gate %token	DT_KEY_BREAK
700Sstevel@tonic-gate %token	DT_KEY_CASE
710Sstevel@tonic-gate %token	DT_KEY_CHAR
720Sstevel@tonic-gate %token	DT_KEY_CONST
730Sstevel@tonic-gate %token	DT_KEY_CONTINUE
740Sstevel@tonic-gate %token	DT_KEY_COUNTER
750Sstevel@tonic-gate %token	DT_KEY_DEFAULT
760Sstevel@tonic-gate %token	DT_KEY_DO
770Sstevel@tonic-gate %token	DT_KEY_DOUBLE
780Sstevel@tonic-gate %token	DT_KEY_ELSE
790Sstevel@tonic-gate %token	DT_KEY_ENUM
800Sstevel@tonic-gate %token	DT_KEY_EXTERN
810Sstevel@tonic-gate %token	DT_KEY_FLOAT
820Sstevel@tonic-gate %token	DT_KEY_FOR
830Sstevel@tonic-gate %token	DT_KEY_GOTO
840Sstevel@tonic-gate %token	DT_KEY_IF
850Sstevel@tonic-gate %token	DT_KEY_IMPORT
860Sstevel@tonic-gate %token	DT_KEY_INLINE
870Sstevel@tonic-gate %token	DT_KEY_INT
880Sstevel@tonic-gate %token	DT_KEY_LONG
890Sstevel@tonic-gate %token	DT_KEY_PROBE
900Sstevel@tonic-gate %token	DT_KEY_PROVIDER
910Sstevel@tonic-gate %token	DT_KEY_REGISTER
920Sstevel@tonic-gate %token	DT_KEY_RESTRICT
930Sstevel@tonic-gate %token	DT_KEY_RETURN
940Sstevel@tonic-gate %token	DT_KEY_SELF
950Sstevel@tonic-gate %token	DT_KEY_SHORT
960Sstevel@tonic-gate %token	DT_KEY_SIGNED
970Sstevel@tonic-gate %token	DT_KEY_STATIC
980Sstevel@tonic-gate %token	DT_KEY_STRING
990Sstevel@tonic-gate %token	DT_KEY_STRUCT
1000Sstevel@tonic-gate %token	DT_KEY_SWITCH
1010Sstevel@tonic-gate %token	DT_KEY_THIS
1020Sstevel@tonic-gate %token	DT_KEY_TYPEDEF
1030Sstevel@tonic-gate %token	DT_KEY_UNION
1040Sstevel@tonic-gate %token	DT_KEY_UNSIGNED
1050Sstevel@tonic-gate %token	DT_KEY_VOID
1060Sstevel@tonic-gate %token	DT_KEY_VOLATILE
1070Sstevel@tonic-gate %token	DT_KEY_WHILE
1080Sstevel@tonic-gate %token	DT_KEY_XLATOR
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate %token	DT_TOK_EPRED
1110Sstevel@tonic-gate %token	DT_CTX_DEXPR
1120Sstevel@tonic-gate %token	DT_CTX_DPROG
1130Sstevel@tonic-gate %token	DT_CTX_DTYPE
1140Sstevel@tonic-gate %token	DT_TOK_EOF	0
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate %left	DT_TOK_COMMA
1170Sstevel@tonic-gate %right	DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ DT_TOK_DIV_EQ
1180Sstevel@tonic-gate 	DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ DT_TOK_LSH_EQ
1190Sstevel@tonic-gate 	DT_TOK_RSH_EQ
1200Sstevel@tonic-gate %left	DT_TOK_QUESTION DT_TOK_COLON
1210Sstevel@tonic-gate %left	DT_TOK_LOR
1220Sstevel@tonic-gate %left	DT_TOK_LXOR
1230Sstevel@tonic-gate %left	DT_TOK_LAND
1240Sstevel@tonic-gate %left	DT_TOK_BOR
1250Sstevel@tonic-gate %left	DT_TOK_XOR
1260Sstevel@tonic-gate %left	DT_TOK_BAND
1270Sstevel@tonic-gate %left	DT_TOK_EQU DT_TOK_NEQ
1280Sstevel@tonic-gate %left	DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE
1290Sstevel@tonic-gate %left	DT_TOK_LSH DT_TOK_RSH
1300Sstevel@tonic-gate %left	DT_TOK_ADD DT_TOK_SUB
1310Sstevel@tonic-gate %left	DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
1320Sstevel@tonic-gate %right	DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
1330Sstevel@tonic-gate 	DT_TOK_IPOS DT_TOK_INEG
1340Sstevel@tonic-gate %right	DT_TOK_DEREF DT_TOK_ADDROF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
1350Sstevel@tonic-gate %left	DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate %type	<l_node>	d_expression
1380Sstevel@tonic-gate %type	<l_node>	d_program
1390Sstevel@tonic-gate %type	<l_node>	d_type
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate %type	<l_node>	translation_unit
1420Sstevel@tonic-gate %type	<l_node>	external_declaration
1430Sstevel@tonic-gate %type	<l_node>	inline_definition
1440Sstevel@tonic-gate %type	<l_node>	translator_definition
1450Sstevel@tonic-gate %type	<l_node>	translator_member_list
1460Sstevel@tonic-gate %type	<l_node>	translator_member
1470Sstevel@tonic-gate %type	<l_node>	provider_definition
1480Sstevel@tonic-gate %type	<l_node>	provider_probe_list
1490Sstevel@tonic-gate %type	<l_node>	provider_probe
1500Sstevel@tonic-gate %type	<l_node>	probe_definition
1510Sstevel@tonic-gate %type	<l_node>	probe_specifiers
1520Sstevel@tonic-gate %type	<l_node>	probe_specifier_list
1530Sstevel@tonic-gate %type	<l_node>	probe_specifier
1540Sstevel@tonic-gate %type	<l_node>	statement_list
1550Sstevel@tonic-gate %type	<l_node>	statement
1560Sstevel@tonic-gate %type	<l_node>	declaration
1570Sstevel@tonic-gate %type	<l_node>	init_declarator_list
1580Sstevel@tonic-gate %type	<l_node>	init_declarator
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate %type	<l_decl>	type_specifier
1610Sstevel@tonic-gate %type	<l_decl>	type_qualifier
1620Sstevel@tonic-gate %type	<l_decl>	struct_or_union_specifier
1630Sstevel@tonic-gate %type	<l_decl>	specifier_qualifier_list
1640Sstevel@tonic-gate %type	<l_decl>	enum_specifier
1650Sstevel@tonic-gate %type	<l_decl>	declarator
1660Sstevel@tonic-gate %type	<l_decl>	direct_declarator
1670Sstevel@tonic-gate %type	<l_decl>	pointer
1680Sstevel@tonic-gate %type	<l_decl>	type_qualifier_list
1690Sstevel@tonic-gate %type	<l_decl>	type_name
1700Sstevel@tonic-gate %type	<l_decl>	abstract_declarator
1710Sstevel@tonic-gate %type	<l_decl>	direct_abstract_declarator
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate %type	<l_node>	parameter_type_list
1740Sstevel@tonic-gate %type	<l_node>	parameter_list
1750Sstevel@tonic-gate %type	<l_node>	parameter_declaration
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate %type	<l_node>	array
178*1222Smws %type	<l_node>	array_parameters
1790Sstevel@tonic-gate %type	<l_node>	function
180*1222Smws %type	<l_node>	function_parameters
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate %type	<l_node>	expression
1830Sstevel@tonic-gate %type	<l_node>	assignment_expression
1840Sstevel@tonic-gate %type	<l_node>	conditional_expression
1850Sstevel@tonic-gate %type	<l_node>	constant_expression
1860Sstevel@tonic-gate %type	<l_node>	logical_or_expression
1870Sstevel@tonic-gate %type	<l_node>	logical_xor_expression
1880Sstevel@tonic-gate %type	<l_node>	logical_and_expression
1890Sstevel@tonic-gate %type	<l_node>	inclusive_or_expression
1900Sstevel@tonic-gate %type	<l_node>	exclusive_or_expression
1910Sstevel@tonic-gate %type	<l_node>	and_expression
1920Sstevel@tonic-gate %type	<l_node>	equality_expression
1930Sstevel@tonic-gate %type	<l_node>	relational_expression
1940Sstevel@tonic-gate %type	<l_node>	shift_expression
1950Sstevel@tonic-gate %type	<l_node>	additive_expression
1960Sstevel@tonic-gate %type	<l_node>	multiplicative_expression
1970Sstevel@tonic-gate %type	<l_node>	cast_expression
1980Sstevel@tonic-gate %type	<l_node>	unary_expression
1990Sstevel@tonic-gate %type	<l_node>	postfix_expression
2000Sstevel@tonic-gate %type	<l_node>	primary_expression
2010Sstevel@tonic-gate %type	<l_node>	argument_expression_list
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate %type	<l_tok>		assignment_operator
2040Sstevel@tonic-gate %type	<l_tok>		unary_operator
2050Sstevel@tonic-gate %type	<l_tok>		struct_or_union
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate %%
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate dtrace_program: d_expression DT_TOK_EOF { return (dt_node_root($1)); }
2100Sstevel@tonic-gate 	|	d_program DT_TOK_EOF { return (dt_node_root($1)); }
2110Sstevel@tonic-gate 	|	d_type DT_TOK_EOF { return (dt_node_root($1)); }
2120Sstevel@tonic-gate 	;
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate d_expression:	DT_CTX_DEXPR { $$ = NULL; }
2150Sstevel@tonic-gate 	|	DT_CTX_DEXPR expression { $$ = $2; }
2160Sstevel@tonic-gate 	;
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate d_program:	DT_CTX_DPROG { $$ = dt_node_program(NULL); }
2190Sstevel@tonic-gate 	|	DT_CTX_DPROG translation_unit { $$ = dt_node_program($2); }
2200Sstevel@tonic-gate 	;
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate d_type:		DT_CTX_DTYPE { $$ = NULL; }
2230Sstevel@tonic-gate 	|	DT_CTX_DTYPE type_name { $$ = (dt_node_t *)$2; }
2240Sstevel@tonic-gate 	;
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate translation_unit:
2270Sstevel@tonic-gate 		external_declaration
2280Sstevel@tonic-gate 	|	translation_unit external_declaration { $$ = LINK($1, $2); }
2290Sstevel@tonic-gate 	;
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate external_declaration:
2320Sstevel@tonic-gate 		inline_definition
2330Sstevel@tonic-gate 	|	translator_definition
2340Sstevel@tonic-gate 	|	provider_definition
2350Sstevel@tonic-gate 	|	probe_definition
2360Sstevel@tonic-gate 	|	declaration
2370Sstevel@tonic-gate 	;
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate inline_definition:
2400Sstevel@tonic-gate 		DT_KEY_INLINE declaration_specifiers declarator
2410Sstevel@tonic-gate 		    { dt_scope_push(NULL, CTF_ERR); } DT_TOK_ASGN
2420Sstevel@tonic-gate 		    assignment_expression ';' {
2430Sstevel@tonic-gate 			/*
2440Sstevel@tonic-gate 			 * We push a new declaration scope before shifting the
2450Sstevel@tonic-gate 			 * assignment_expression in order to preserve ds_class
2460Sstevel@tonic-gate 			 * and ds_ident for use in dt_node_inline().  Once the
2470Sstevel@tonic-gate 			 * entire inline_definition rule is matched, pop the
2480Sstevel@tonic-gate 			 * scope and construct the inline using the saved decl.
2490Sstevel@tonic-gate 			 */
2500Sstevel@tonic-gate 			dt_scope_pop();
2510Sstevel@tonic-gate 			$$ = dt_node_inline($6);
2520Sstevel@tonic-gate 		}
2530Sstevel@tonic-gate 	;
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate translator_definition:
2560Sstevel@tonic-gate 		DT_KEY_XLATOR type_name DT_TOK_LT type_name
2570Sstevel@tonic-gate 		    DT_TOK_IDENT DT_TOK_GT '{' translator_member_list '}' ';' {
2580Sstevel@tonic-gate 			$$ = dt_node_xlator($2, $4, $5, $8);
2590Sstevel@tonic-gate 		}
2600Sstevel@tonic-gate 	|	DT_KEY_XLATOR type_name DT_TOK_LT type_name
2610Sstevel@tonic-gate 		    DT_TOK_IDENT DT_TOK_GT '{' '}' ';' {
2620Sstevel@tonic-gate 			$$ = dt_node_xlator($2, $4, $5, NULL);
2630Sstevel@tonic-gate 		}
2640Sstevel@tonic-gate 	;
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate translator_member_list:
2670Sstevel@tonic-gate 		translator_member
2680Sstevel@tonic-gate 	|	translator_member_list translator_member { $$ = LINK($1,$2); }
2690Sstevel@tonic-gate 	;
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate translator_member:
2720Sstevel@tonic-gate 		DT_TOK_IDENT DT_TOK_ASGN assignment_expression ';' {
2730Sstevel@tonic-gate 			$$ = dt_node_member(NULL, $1, $3);
2740Sstevel@tonic-gate 		}
2750Sstevel@tonic-gate 	;
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate provider_definition:
2780Sstevel@tonic-gate 		DT_KEY_PROVIDER DT_TOK_IDENT '{' provider_probe_list '}' ';' {
2790Sstevel@tonic-gate 			$$ = dt_node_provider($2, $4);
2800Sstevel@tonic-gate 		}
2810Sstevel@tonic-gate 	|	DT_KEY_PROVIDER DT_TOK_IDENT '{' '}' ';' {
2820Sstevel@tonic-gate 			$$ = dt_node_provider($2, NULL);
2830Sstevel@tonic-gate 		}
2840Sstevel@tonic-gate 	;
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate provider_probe_list:
2870Sstevel@tonic-gate 		provider_probe
2880Sstevel@tonic-gate 	|	provider_probe_list provider_probe { $$ = LINK($1, $2); }
2890Sstevel@tonic-gate 	;
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate provider_probe:
2920Sstevel@tonic-gate 		DT_KEY_PROBE DT_TOK_IDENT function DT_TOK_COLON function ';' {
293265Smws 			$$ = dt_node_probe($2, 2, $3, $5);
2940Sstevel@tonic-gate 		}
2950Sstevel@tonic-gate 	|	DT_KEY_PROBE DT_TOK_IDENT function ';' {
296265Smws 			$$ = dt_node_probe($2, 1, $3, NULL);
2970Sstevel@tonic-gate 		}
2980Sstevel@tonic-gate 	;
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate 
3010Sstevel@tonic-gate probe_definition:
3020Sstevel@tonic-gate 		probe_specifiers {
3030Sstevel@tonic-gate 			/*
3040Sstevel@tonic-gate 			 * If the input stream is a file, do not permit a probe
3050Sstevel@tonic-gate 			 * specification without / <pred> / or { <act> } after
3060Sstevel@tonic-gate 			 * it.  This can only occur if the next token is EOF or
3070Sstevel@tonic-gate 			 * an ambiguous predicate was slurped up as a comment.
3080Sstevel@tonic-gate 			 * We cannot perform this check if input() is a string
3090Sstevel@tonic-gate 			 * because dtrace(1M) [-fmnP] also use the compiler and
3100Sstevel@tonic-gate 			 * things like dtrace -n BEGIN have to be accepted.
3110Sstevel@tonic-gate 			 */
3120Sstevel@tonic-gate 			if (yypcb->pcb_fileptr != NULL) {
3130Sstevel@tonic-gate 				dnerror($1, D_SYNTAX, "expected predicate and/"
3140Sstevel@tonic-gate 				    "or actions following probe description\n");
3150Sstevel@tonic-gate 			}
3160Sstevel@tonic-gate 			$$ = dt_node_clause($1, NULL, NULL);
3170Sstevel@tonic-gate 		}
3180Sstevel@tonic-gate 	|	probe_specifiers '{' statement_list '}' {
3190Sstevel@tonic-gate 			$$ = dt_node_clause($1, NULL, $3);
3200Sstevel@tonic-gate 		}
3210Sstevel@tonic-gate 	|	probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED {
3220Sstevel@tonic-gate 			dnerror($3, D_SYNTAX, "expected actions { } following "
3230Sstevel@tonic-gate 			    "probe description and predicate\n");
3240Sstevel@tonic-gate 		}
3250Sstevel@tonic-gate 	|	probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED
3260Sstevel@tonic-gate 		    '{' statement_list '}' {
3270Sstevel@tonic-gate 			$$ = dt_node_clause($1, $3, $6);
3280Sstevel@tonic-gate 		}
3290Sstevel@tonic-gate 	;
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate probe_specifiers:
3320Sstevel@tonic-gate 		probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; }
3330Sstevel@tonic-gate 	;
3340Sstevel@tonic-gate 
3350Sstevel@tonic-gate probe_specifier_list:
3360Sstevel@tonic-gate 		probe_specifier
3370Sstevel@tonic-gate 	|	probe_specifier_list DT_TOK_COMMA probe_specifier {
3380Sstevel@tonic-gate 			$$ = LINK($1, $3);
3390Sstevel@tonic-gate 		}
3400Sstevel@tonic-gate 	;
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate probe_specifier:
3430Sstevel@tonic-gate 		DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); }
3440Sstevel@tonic-gate 	|	DT_TOK_INT   { $$ = dt_node_pdesc_by_id($1); }
3450Sstevel@tonic-gate 	;
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate statement_list:	statement { $$ = $1; }
3480Sstevel@tonic-gate 	|	statement_list ';' statement { $$ = LINK($1, $3); }
3490Sstevel@tonic-gate 	;
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate statement:	/* empty */ { $$ = NULL; }
3520Sstevel@tonic-gate 	|	expression { $$ = dt_node_statement($1); }
3530Sstevel@tonic-gate 	;
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate argument_expression_list:
3560Sstevel@tonic-gate 		assignment_expression
3570Sstevel@tonic-gate 	|	argument_expression_list DT_TOK_COMMA assignment_expression {
3580Sstevel@tonic-gate 			$$ = LINK($1, $3);
3590Sstevel@tonic-gate 		}
3600Sstevel@tonic-gate 	;
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate primary_expression:
3630Sstevel@tonic-gate 		DT_TOK_IDENT { $$ = dt_node_ident($1); }
3640Sstevel@tonic-gate 	|	DT_TOK_AGG { $$ = dt_node_ident($1); }
3650Sstevel@tonic-gate 	|	DT_TOK_INT { $$ = dt_node_int($1); }
3660Sstevel@tonic-gate 	|	DT_TOK_STRING { $$ = dt_node_string($1); }
3670Sstevel@tonic-gate 	|	DT_KEY_SELF { $$ = dt_node_ident(DUP("self")); }
3680Sstevel@tonic-gate 	|	DT_KEY_THIS { $$ = dt_node_ident(DUP("this")); }
3690Sstevel@tonic-gate 	|	DT_TOK_LPAR expression DT_TOK_RPAR { $$ = $2; }
3700Sstevel@tonic-gate 	;
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate postfix_expression:
3730Sstevel@tonic-gate 		primary_expression
3740Sstevel@tonic-gate 	|	postfix_expression
3750Sstevel@tonic-gate 		    DT_TOK_LBRAC argument_expression_list DT_TOK_RBRAC {
3760Sstevel@tonic-gate 			$$ = OP2(DT_TOK_LBRAC, $1, $3);
3770Sstevel@tonic-gate 		}
3780Sstevel@tonic-gate 	|	postfix_expression DT_TOK_LPAR DT_TOK_RPAR {
3790Sstevel@tonic-gate 			$$ = dt_node_func($1, NULL);
3800Sstevel@tonic-gate 		}
3810Sstevel@tonic-gate 	|	postfix_expression
3820Sstevel@tonic-gate 		    DT_TOK_LPAR argument_expression_list DT_TOK_RPAR {
3830Sstevel@tonic-gate 			$$ = dt_node_func($1, $3);
3840Sstevel@tonic-gate 		}
3850Sstevel@tonic-gate 	|	postfix_expression DT_TOK_DOT DT_TOK_IDENT {
3860Sstevel@tonic-gate 			$$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
3870Sstevel@tonic-gate 		}
3880Sstevel@tonic-gate 	|	postfix_expression DT_TOK_DOT DT_TOK_TNAME {
3890Sstevel@tonic-gate 			$$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
3900Sstevel@tonic-gate 		}
3910Sstevel@tonic-gate 	|	postfix_expression DT_TOK_PTR DT_TOK_IDENT {
3920Sstevel@tonic-gate 			$$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
3930Sstevel@tonic-gate 		}
3940Sstevel@tonic-gate 	|	postfix_expression DT_TOK_PTR DT_TOK_TNAME {
3950Sstevel@tonic-gate 			$$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
3960Sstevel@tonic-gate 		}
3970Sstevel@tonic-gate 	|	postfix_expression DT_TOK_ADDADD {
3980Sstevel@tonic-gate 			$$ = OP1(DT_TOK_POSTINC, $1);
3990Sstevel@tonic-gate 		}
4000Sstevel@tonic-gate 	|	postfix_expression DT_TOK_SUBSUB {
4010Sstevel@tonic-gate 			$$ = OP1(DT_TOK_POSTDEC, $1);
4020Sstevel@tonic-gate 		}
4030Sstevel@tonic-gate 	|	DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA
4040Sstevel@tonic-gate 		    DT_TOK_IDENT DT_TOK_RPAR {
4050Sstevel@tonic-gate 			$$ = dt_node_offsetof($3, $5);
4060Sstevel@tonic-gate 		}
4070Sstevel@tonic-gate 	|	DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA
4080Sstevel@tonic-gate 		    DT_TOK_TNAME DT_TOK_RPAR {
4090Sstevel@tonic-gate 			$$ = dt_node_offsetof($3, $5);
4100Sstevel@tonic-gate 		}
4110Sstevel@tonic-gate 	|	DT_TOK_XLATE DT_TOK_LT type_name DT_TOK_GT
4120Sstevel@tonic-gate 		    DT_TOK_LPAR expression DT_TOK_RPAR {
4130Sstevel@tonic-gate 			$$ = OP2(DT_TOK_XLATE, dt_node_type($3), $6);
4140Sstevel@tonic-gate 		}
4150Sstevel@tonic-gate 	;
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate unary_expression:
4180Sstevel@tonic-gate 		postfix_expression
4190Sstevel@tonic-gate 	|	DT_TOK_ADDADD unary_expression { $$ = OP1(DT_TOK_PREINC, $2); }
4200Sstevel@tonic-gate 	|	DT_TOK_SUBSUB unary_expression { $$ = OP1(DT_TOK_PREDEC, $2); }
4210Sstevel@tonic-gate 	|	unary_operator cast_expression { $$ = OP1($1, $2); }
4220Sstevel@tonic-gate 	|	DT_TOK_SIZEOF unary_expression { $$ = OP1(DT_TOK_SIZEOF, $2); }
4230Sstevel@tonic-gate 	|	DT_TOK_SIZEOF DT_TOK_LPAR type_name DT_TOK_RPAR {
4240Sstevel@tonic-gate 			$$ = OP1(DT_TOK_SIZEOF, dt_node_type($3));
4250Sstevel@tonic-gate 		}
4260Sstevel@tonic-gate 	|	DT_TOK_STRINGOF unary_expression {
4270Sstevel@tonic-gate 			$$ = OP1(DT_TOK_STRINGOF, $2);
4280Sstevel@tonic-gate 		}
4290Sstevel@tonic-gate 	;
4300Sstevel@tonic-gate 
4310Sstevel@tonic-gate unary_operator:	DT_TOK_BAND { $$ = DT_TOK_ADDROF; }
4320Sstevel@tonic-gate 	|	DT_TOK_MUL { $$ = DT_TOK_DEREF; }
4330Sstevel@tonic-gate 	|	DT_TOK_ADD { $$ = DT_TOK_IPOS; }
4340Sstevel@tonic-gate 	|	DT_TOK_SUB { $$ = DT_TOK_INEG; }
4350Sstevel@tonic-gate 	|	DT_TOK_BNEG { $$ = DT_TOK_BNEG; }
4360Sstevel@tonic-gate 	|	DT_TOK_LNEG { $$ = DT_TOK_LNEG; }
4370Sstevel@tonic-gate 	;
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate cast_expression:
4400Sstevel@tonic-gate 		unary_expression
4410Sstevel@tonic-gate 	|	DT_TOK_LPAR type_name DT_TOK_RPAR cast_expression {
4420Sstevel@tonic-gate 			$$ = OP2(DT_TOK_LPAR, dt_node_type($2), $4);
4430Sstevel@tonic-gate 		}
4440Sstevel@tonic-gate 	;
4450Sstevel@tonic-gate 
4460Sstevel@tonic-gate multiplicative_expression:
4470Sstevel@tonic-gate 		cast_expression
4480Sstevel@tonic-gate 	|	multiplicative_expression DT_TOK_MUL cast_expression {
4490Sstevel@tonic-gate 			$$ = OP2(DT_TOK_MUL, $1, $3);
4500Sstevel@tonic-gate 		}
4510Sstevel@tonic-gate 	|	multiplicative_expression DT_TOK_DIV cast_expression {
4520Sstevel@tonic-gate 			$$ = OP2(DT_TOK_DIV, $1, $3);
4530Sstevel@tonic-gate 		}
4540Sstevel@tonic-gate 	|	multiplicative_expression DT_TOK_MOD cast_expression {
4550Sstevel@tonic-gate 			$$ = OP2(DT_TOK_MOD, $1, $3);
4560Sstevel@tonic-gate 		}
4570Sstevel@tonic-gate 	;
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate additive_expression:
4600Sstevel@tonic-gate 		multiplicative_expression
4610Sstevel@tonic-gate 	|	additive_expression DT_TOK_ADD multiplicative_expression {
4620Sstevel@tonic-gate 			$$ = OP2(DT_TOK_ADD, $1, $3);
4630Sstevel@tonic-gate 		}
4640Sstevel@tonic-gate 	|	additive_expression DT_TOK_SUB multiplicative_expression {
4650Sstevel@tonic-gate 			$$ = OP2(DT_TOK_SUB, $1, $3);
4660Sstevel@tonic-gate 		}
4670Sstevel@tonic-gate 	;
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate shift_expression:
4700Sstevel@tonic-gate 		additive_expression
4710Sstevel@tonic-gate 	|	shift_expression DT_TOK_LSH additive_expression {
4720Sstevel@tonic-gate 			$$ = OP2(DT_TOK_LSH, $1, $3);
4730Sstevel@tonic-gate 		}
4740Sstevel@tonic-gate 	|	shift_expression DT_TOK_RSH additive_expression {
4750Sstevel@tonic-gate 			$$ = OP2(DT_TOK_RSH, $1, $3);
4760Sstevel@tonic-gate 		}
4770Sstevel@tonic-gate 	;
4780Sstevel@tonic-gate 
4790Sstevel@tonic-gate relational_expression:
4800Sstevel@tonic-gate 		shift_expression
4810Sstevel@tonic-gate 	|	relational_expression DT_TOK_LT shift_expression {
4820Sstevel@tonic-gate 			$$ = OP2(DT_TOK_LT, $1, $3);
4830Sstevel@tonic-gate 		}
4840Sstevel@tonic-gate 	|	relational_expression DT_TOK_GT shift_expression {
4850Sstevel@tonic-gate 			$$ = OP2(DT_TOK_GT, $1, $3);
4860Sstevel@tonic-gate 		}
4870Sstevel@tonic-gate 	|	relational_expression DT_TOK_LE shift_expression {
4880Sstevel@tonic-gate 			$$ = OP2(DT_TOK_LE, $1, $3);
4890Sstevel@tonic-gate 		}
4900Sstevel@tonic-gate 	|	relational_expression DT_TOK_GE shift_expression {
4910Sstevel@tonic-gate 			$$ = OP2(DT_TOK_GE, $1, $3);
4920Sstevel@tonic-gate 		}
4930Sstevel@tonic-gate 	;
4940Sstevel@tonic-gate 
4950Sstevel@tonic-gate equality_expression:
4960Sstevel@tonic-gate 		relational_expression
4970Sstevel@tonic-gate 	|	equality_expression DT_TOK_EQU relational_expression {
4980Sstevel@tonic-gate 			$$ = OP2(DT_TOK_EQU, $1, $3);
4990Sstevel@tonic-gate 		}
5000Sstevel@tonic-gate 	|	equality_expression DT_TOK_NEQ relational_expression {
5010Sstevel@tonic-gate 			$$ = OP2(DT_TOK_NEQ, $1, $3);
5020Sstevel@tonic-gate 		}
5030Sstevel@tonic-gate 	;
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate and_expression:
5060Sstevel@tonic-gate 		equality_expression
5070Sstevel@tonic-gate 	|	and_expression DT_TOK_BAND equality_expression {
5080Sstevel@tonic-gate 			$$ = OP2(DT_TOK_BAND, $1, $3);
5090Sstevel@tonic-gate 		}
5100Sstevel@tonic-gate 	;
5110Sstevel@tonic-gate 
5120Sstevel@tonic-gate exclusive_or_expression:
5130Sstevel@tonic-gate 		and_expression
5140Sstevel@tonic-gate 	|	exclusive_or_expression DT_TOK_XOR and_expression {
5150Sstevel@tonic-gate 			$$ = OP2(DT_TOK_XOR, $1, $3);
5160Sstevel@tonic-gate 		}
5170Sstevel@tonic-gate 	;
5180Sstevel@tonic-gate 
5190Sstevel@tonic-gate inclusive_or_expression:
5200Sstevel@tonic-gate 		exclusive_or_expression
5210Sstevel@tonic-gate 	|	inclusive_or_expression DT_TOK_BOR exclusive_or_expression {
5220Sstevel@tonic-gate 			$$ = OP2(DT_TOK_BOR, $1, $3);
5230Sstevel@tonic-gate 		}
5240Sstevel@tonic-gate 	;
5250Sstevel@tonic-gate 
5260Sstevel@tonic-gate logical_and_expression:
5270Sstevel@tonic-gate 		inclusive_or_expression
5280Sstevel@tonic-gate 	|	logical_and_expression DT_TOK_LAND inclusive_or_expression {
5290Sstevel@tonic-gate 			$$ = OP2(DT_TOK_LAND, $1, $3);
5300Sstevel@tonic-gate 		}
5310Sstevel@tonic-gate 	;
5320Sstevel@tonic-gate 
5330Sstevel@tonic-gate logical_xor_expression:
5340Sstevel@tonic-gate 		logical_and_expression
5350Sstevel@tonic-gate 	|	logical_xor_expression DT_TOK_LXOR logical_and_expression {
5360Sstevel@tonic-gate 			$$ = OP2(DT_TOK_LXOR, $1, $3);
5370Sstevel@tonic-gate 		}
5380Sstevel@tonic-gate 	;
5390Sstevel@tonic-gate 
5400Sstevel@tonic-gate logical_or_expression:
5410Sstevel@tonic-gate 		logical_xor_expression
5420Sstevel@tonic-gate 	|	logical_or_expression DT_TOK_LOR logical_xor_expression {
5430Sstevel@tonic-gate 			$$ = OP2(DT_TOK_LOR, $1, $3);
5440Sstevel@tonic-gate 		}
5450Sstevel@tonic-gate 	;
5460Sstevel@tonic-gate 
5470Sstevel@tonic-gate constant_expression: conditional_expression
5480Sstevel@tonic-gate 	;
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate conditional_expression:
5510Sstevel@tonic-gate 		logical_or_expression
5520Sstevel@tonic-gate 	|	logical_or_expression DT_TOK_QUESTION expression DT_TOK_COLON
5530Sstevel@tonic-gate 		    conditional_expression { $$ = OP3($1, $3, $5); }
5540Sstevel@tonic-gate 	;
5550Sstevel@tonic-gate 
5560Sstevel@tonic-gate assignment_expression:
5570Sstevel@tonic-gate 		conditional_expression
5580Sstevel@tonic-gate 	|	unary_expression assignment_operator assignment_expression {
5590Sstevel@tonic-gate 			$$ = OP2($2, $1, $3);
5600Sstevel@tonic-gate 		}
5610Sstevel@tonic-gate 	;
5620Sstevel@tonic-gate 
5630Sstevel@tonic-gate assignment_operator:
5640Sstevel@tonic-gate 		DT_TOK_ASGN   { $$ = DT_TOK_ASGN; }
5650Sstevel@tonic-gate 	|	DT_TOK_MUL_EQ { $$ = DT_TOK_MUL_EQ; }
5660Sstevel@tonic-gate 	|	DT_TOK_DIV_EQ { $$ = DT_TOK_DIV_EQ; }
5670Sstevel@tonic-gate 	|	DT_TOK_MOD_EQ { $$ = DT_TOK_MOD_EQ; }
5680Sstevel@tonic-gate 	|	DT_TOK_ADD_EQ { $$ = DT_TOK_ADD_EQ; }
5690Sstevel@tonic-gate 	|	DT_TOK_SUB_EQ { $$ = DT_TOK_SUB_EQ; }
5700Sstevel@tonic-gate 	|	DT_TOK_LSH_EQ { $$ = DT_TOK_LSH_EQ; }
5710Sstevel@tonic-gate 	|	DT_TOK_RSH_EQ { $$ = DT_TOK_RSH_EQ; }
5720Sstevel@tonic-gate 	|	DT_TOK_AND_EQ { $$ = DT_TOK_AND_EQ; }
5730Sstevel@tonic-gate 	|	DT_TOK_XOR_EQ { $$ = DT_TOK_XOR_EQ; }
5740Sstevel@tonic-gate 	|	DT_TOK_OR_EQ  { $$ = DT_TOK_OR_EQ; }
5750Sstevel@tonic-gate 	;
5760Sstevel@tonic-gate 
5770Sstevel@tonic-gate expression:	assignment_expression
5780Sstevel@tonic-gate 	|	expression DT_TOK_COMMA assignment_expression {
5790Sstevel@tonic-gate 			$$ = OP2(DT_TOK_COMMA, $1, $3);
5800Sstevel@tonic-gate 		}
5810Sstevel@tonic-gate 	;
5820Sstevel@tonic-gate 
5830Sstevel@tonic-gate declaration:	declaration_specifiers ';' {
5840Sstevel@tonic-gate 			$$ = dt_node_decl();
5850Sstevel@tonic-gate 			dt_decl_free(dt_decl_pop());
5860Sstevel@tonic-gate 			yybegin(YYS_CLAUSE);
5870Sstevel@tonic-gate 		}
5880Sstevel@tonic-gate 	|	declaration_specifiers init_declarator_list ';' {
5890Sstevel@tonic-gate 			$$ = $2;
5900Sstevel@tonic-gate 			dt_decl_free(dt_decl_pop());
5910Sstevel@tonic-gate 			yybegin(YYS_CLAUSE);
5920Sstevel@tonic-gate 		}
5930Sstevel@tonic-gate 	;
5940Sstevel@tonic-gate 
5950Sstevel@tonic-gate declaration_specifiers:
5960Sstevel@tonic-gate 		d_storage_class_specifier
5970Sstevel@tonic-gate 	|	d_storage_class_specifier declaration_specifiers
5980Sstevel@tonic-gate 	|	type_specifier
5990Sstevel@tonic-gate 	|	type_specifier declaration_specifiers
6000Sstevel@tonic-gate 	|	type_qualifier
6010Sstevel@tonic-gate 	|	type_qualifier declaration_specifiers
6020Sstevel@tonic-gate 	;
6030Sstevel@tonic-gate 
6040Sstevel@tonic-gate parameter_declaration_specifiers:
6050Sstevel@tonic-gate 		storage_class_specifier
6060Sstevel@tonic-gate 	|	storage_class_specifier declaration_specifiers
6070Sstevel@tonic-gate 	|	type_specifier
6080Sstevel@tonic-gate 	|	type_specifier declaration_specifiers
6090Sstevel@tonic-gate 	|	type_qualifier
6100Sstevel@tonic-gate 	|	type_qualifier declaration_specifiers
6110Sstevel@tonic-gate 	;
6120Sstevel@tonic-gate 
6130Sstevel@tonic-gate storage_class_specifier:
6140Sstevel@tonic-gate 		DT_KEY_AUTO { dt_decl_class(DT_DC_AUTO); }
6150Sstevel@tonic-gate 	|	DT_KEY_REGISTER { dt_decl_class(DT_DC_REGISTER); }
6160Sstevel@tonic-gate 	|	DT_KEY_STATIC { dt_decl_class(DT_DC_STATIC); }
6170Sstevel@tonic-gate 	|	DT_KEY_EXTERN { dt_decl_class(DT_DC_EXTERN); }
6180Sstevel@tonic-gate 	|	DT_KEY_TYPEDEF { dt_decl_class(DT_DC_TYPEDEF); }
6190Sstevel@tonic-gate 	;
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate d_storage_class_specifier:
6220Sstevel@tonic-gate 		storage_class_specifier
6230Sstevel@tonic-gate 	|	DT_KEY_SELF { dt_decl_class(DT_DC_SELF); }
6240Sstevel@tonic-gate 	|	DT_KEY_THIS { dt_decl_class(DT_DC_THIS); }
6250Sstevel@tonic-gate 	;
6260Sstevel@tonic-gate 
6270Sstevel@tonic-gate type_specifier:	DT_KEY_VOID { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("void")); }
6280Sstevel@tonic-gate 	|	DT_KEY_CHAR { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("char")); }
6290Sstevel@tonic-gate 	|	DT_KEY_SHORT { $$ = dt_decl_attr(DT_DA_SHORT); }
6300Sstevel@tonic-gate 	|	DT_KEY_INT { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("int")); }
6310Sstevel@tonic-gate 	|	DT_KEY_LONG { $$ = dt_decl_attr(DT_DA_LONG); }
6320Sstevel@tonic-gate 	|	DT_KEY_FLOAT { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("float")); }
6330Sstevel@tonic-gate 	|	DT_KEY_DOUBLE { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("double")); }
6340Sstevel@tonic-gate 	|	DT_KEY_SIGNED { $$ = dt_decl_attr(DT_DA_SIGNED); }
6350Sstevel@tonic-gate 	|	DT_KEY_UNSIGNED { $$ = dt_decl_attr(DT_DA_UNSIGNED); }
6360Sstevel@tonic-gate 	|	DT_KEY_STRING {
6370Sstevel@tonic-gate 			$$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string"));
6380Sstevel@tonic-gate 		}
6390Sstevel@tonic-gate 	|	DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_TYPEDEF, $1); }
6400Sstevel@tonic-gate 	|	struct_or_union_specifier
6410Sstevel@tonic-gate 	|	enum_specifier
6420Sstevel@tonic-gate 	;
6430Sstevel@tonic-gate 
6440Sstevel@tonic-gate type_qualifier:	DT_KEY_CONST { $$ = dt_decl_attr(DT_DA_CONST); }
6450Sstevel@tonic-gate 	|	DT_KEY_RESTRICT { $$ = dt_decl_attr(DT_DA_RESTRICT); }
6460Sstevel@tonic-gate 	|	DT_KEY_VOLATILE { $$ = dt_decl_attr(DT_DA_VOLATILE); }
6470Sstevel@tonic-gate 	;
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate struct_or_union_specifier:
6500Sstevel@tonic-gate 		struct_or_union_definition struct_declaration_list '}' {
6510Sstevel@tonic-gate 			$$ = dt_scope_pop();
6520Sstevel@tonic-gate 		}
6530Sstevel@tonic-gate 	|	struct_or_union DT_TOK_IDENT { $$ = dt_decl_spec($1, $2); }
6540Sstevel@tonic-gate 	|	struct_or_union DT_TOK_TNAME { $$ = dt_decl_spec($1, $2); }
6550Sstevel@tonic-gate 	;
6560Sstevel@tonic-gate 
6570Sstevel@tonic-gate struct_or_union_definition:
6580Sstevel@tonic-gate 		struct_or_union '{' { dt_decl_sou($1, NULL); }
6590Sstevel@tonic-gate 	|	struct_or_union DT_TOK_IDENT '{' { dt_decl_sou($1, $2); }
6600Sstevel@tonic-gate 	|	struct_or_union DT_TOK_TNAME '{' { dt_decl_sou($1, $2); }
6610Sstevel@tonic-gate 	;
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate struct_or_union:
6640Sstevel@tonic-gate 		DT_KEY_STRUCT { $$ = CTF_K_STRUCT; }
6650Sstevel@tonic-gate 	|	DT_KEY_UNION { $$ = CTF_K_UNION; }
6660Sstevel@tonic-gate 	;
6670Sstevel@tonic-gate 
6680Sstevel@tonic-gate struct_declaration_list:
6690Sstevel@tonic-gate 		struct_declaration
6700Sstevel@tonic-gate 	|	struct_declaration_list struct_declaration
6710Sstevel@tonic-gate 	;
6720Sstevel@tonic-gate 
6730Sstevel@tonic-gate init_declarator_list:
6740Sstevel@tonic-gate 		init_declarator
6750Sstevel@tonic-gate 	|	init_declarator_list DT_TOK_COMMA init_declarator {
6760Sstevel@tonic-gate 			$$ = LINK($1, $3);
6770Sstevel@tonic-gate 		}
6780Sstevel@tonic-gate 	;
6790Sstevel@tonic-gate 
6800Sstevel@tonic-gate init_declarator:
6810Sstevel@tonic-gate 		declarator {
6820Sstevel@tonic-gate 			$$ = dt_node_decl();
6830Sstevel@tonic-gate 			dt_decl_reset();
6840Sstevel@tonic-gate 		}
6850Sstevel@tonic-gate 	;
6860Sstevel@tonic-gate 
6870Sstevel@tonic-gate struct_declaration:
6880Sstevel@tonic-gate 		specifier_qualifier_list struct_declarator_list ';' {
6890Sstevel@tonic-gate 			dt_decl_free(dt_decl_pop());
6900Sstevel@tonic-gate 		}
6910Sstevel@tonic-gate 	;
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate specifier_qualifier_list:
6940Sstevel@tonic-gate 		type_specifier
6950Sstevel@tonic-gate 	|	type_specifier specifier_qualifier_list { $$ = $2; }
6960Sstevel@tonic-gate 	|	type_qualifier
6970Sstevel@tonic-gate 	|	type_qualifier specifier_qualifier_list { $$ = $2; }
6980Sstevel@tonic-gate 	;
6990Sstevel@tonic-gate 
7000Sstevel@tonic-gate struct_declarator_list:
7010Sstevel@tonic-gate 		struct_declarator
7020Sstevel@tonic-gate 	|	struct_declarator_list DT_TOK_COMMA struct_declarator
7030Sstevel@tonic-gate 	;
7040Sstevel@tonic-gate 
7050Sstevel@tonic-gate struct_declarator:
7060Sstevel@tonic-gate 		declarator { dt_decl_member(NULL); }
7070Sstevel@tonic-gate 	|	DT_TOK_COLON constant_expression { dt_decl_member($2); }
7080Sstevel@tonic-gate 	|	declarator DT_TOK_COLON constant_expression {
7090Sstevel@tonic-gate 			dt_decl_member($3);
7100Sstevel@tonic-gate 		}
7110Sstevel@tonic-gate 	;
7120Sstevel@tonic-gate 
7130Sstevel@tonic-gate enum_specifier:
7140Sstevel@tonic-gate 		enum_definition enumerator_list '}' { $$ = dt_scope_pop(); }
7150Sstevel@tonic-gate 	|	DT_KEY_ENUM DT_TOK_IDENT { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
7160Sstevel@tonic-gate 	|	DT_KEY_ENUM DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
7170Sstevel@tonic-gate 	;
7180Sstevel@tonic-gate 
7190Sstevel@tonic-gate enum_definition:
7200Sstevel@tonic-gate 		DT_KEY_ENUM '{' { dt_decl_enum(NULL); }
7210Sstevel@tonic-gate 	|	DT_KEY_ENUM DT_TOK_IDENT '{' { dt_decl_enum($2); }
7220Sstevel@tonic-gate 	|	DT_KEY_ENUM DT_TOK_TNAME '{' { dt_decl_enum($2); }
7230Sstevel@tonic-gate 	;
7240Sstevel@tonic-gate 
7250Sstevel@tonic-gate enumerator_list:
7260Sstevel@tonic-gate 		enumerator
7270Sstevel@tonic-gate 	|	enumerator_list DT_TOK_COMMA enumerator
7280Sstevel@tonic-gate 	;
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate enumerator:	DT_TOK_IDENT { dt_decl_enumerator($1, NULL); }
7310Sstevel@tonic-gate 	|	DT_TOK_IDENT DT_TOK_ASGN expression {
7320Sstevel@tonic-gate 			dt_decl_enumerator($1, $3);
7330Sstevel@tonic-gate 		}
7340Sstevel@tonic-gate 	;
7350Sstevel@tonic-gate 
7360Sstevel@tonic-gate declarator:	direct_declarator
7370Sstevel@tonic-gate 	|	pointer direct_declarator
7380Sstevel@tonic-gate 	;
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate direct_declarator:
7410Sstevel@tonic-gate 		DT_TOK_IDENT { $$ = dt_decl_ident($1); }
7420Sstevel@tonic-gate 	|	lparen declarator DT_TOK_RPAR { $$ = $2; }
7430Sstevel@tonic-gate 	|	direct_declarator array { dt_decl_array($2); }
7440Sstevel@tonic-gate 	|	direct_declarator function { dt_decl_func($1, $2); }
7450Sstevel@tonic-gate 	;
7460Sstevel@tonic-gate 
7470Sstevel@tonic-gate lparen:		DT_TOK_LPAR { dt_decl_top()->dd_attr |= DT_DA_PAREN; }
7480Sstevel@tonic-gate 	;
7490Sstevel@tonic-gate 
7500Sstevel@tonic-gate pointer:	DT_TOK_MUL { $$ = dt_decl_ptr(); }
7510Sstevel@tonic-gate 	|	DT_TOK_MUL type_qualifier_list { $$ = dt_decl_ptr(); }
7520Sstevel@tonic-gate 	|	DT_TOK_MUL pointer { $$ = dt_decl_ptr(); }
7530Sstevel@tonic-gate 	|	DT_TOK_MUL type_qualifier_list pointer { $$ = dt_decl_ptr(); }
7540Sstevel@tonic-gate 	;
7550Sstevel@tonic-gate 
7560Sstevel@tonic-gate type_qualifier_list:
7570Sstevel@tonic-gate 		type_qualifier
7580Sstevel@tonic-gate 	|	type_qualifier_list type_qualifier { $$ = $2; }
7590Sstevel@tonic-gate 	;
7600Sstevel@tonic-gate 
7610Sstevel@tonic-gate parameter_type_list:
7620Sstevel@tonic-gate 		parameter_list
7630Sstevel@tonic-gate 	|	DT_TOK_ELLIPSIS { $$ = dt_node_vatype(); }
7640Sstevel@tonic-gate 	|	parameter_list DT_TOK_COMMA DT_TOK_ELLIPSIS {
7650Sstevel@tonic-gate 			$$ = LINK($1, dt_node_vatype());
7660Sstevel@tonic-gate 		}
7670Sstevel@tonic-gate 	;
7680Sstevel@tonic-gate 
7690Sstevel@tonic-gate parameter_list:	parameter_declaration
7700Sstevel@tonic-gate 	|	parameter_list DT_TOK_COMMA parameter_declaration {
7710Sstevel@tonic-gate 			$$ = LINK($1, $3);
7720Sstevel@tonic-gate 		}
7730Sstevel@tonic-gate 	;
7740Sstevel@tonic-gate 
7750Sstevel@tonic-gate parameter_declaration:
7760Sstevel@tonic-gate 		parameter_declaration_specifiers {
7770Sstevel@tonic-gate 			$$ = dt_node_type(NULL);
7780Sstevel@tonic-gate 		}
7790Sstevel@tonic-gate 	|	parameter_declaration_specifiers declarator {
7800Sstevel@tonic-gate 			$$ = dt_node_type(NULL);
7810Sstevel@tonic-gate 		}
7820Sstevel@tonic-gate 	|	parameter_declaration_specifiers abstract_declarator {
7830Sstevel@tonic-gate 			$$ = dt_node_type(NULL);
7840Sstevel@tonic-gate 		}
7850Sstevel@tonic-gate 	;
7860Sstevel@tonic-gate 
7870Sstevel@tonic-gate type_name:	specifier_qualifier_list {
7880Sstevel@tonic-gate 			$$ = dt_decl_pop();
7890Sstevel@tonic-gate 		}
7900Sstevel@tonic-gate 	|	specifier_qualifier_list abstract_declarator {
7910Sstevel@tonic-gate 			$$ = dt_decl_pop();
7920Sstevel@tonic-gate 		}
7930Sstevel@tonic-gate 	;
7940Sstevel@tonic-gate 
7950Sstevel@tonic-gate abstract_declarator:
7960Sstevel@tonic-gate 		pointer
7970Sstevel@tonic-gate 	|	direct_abstract_declarator
7980Sstevel@tonic-gate 	|	pointer direct_abstract_declarator
7990Sstevel@tonic-gate 	;
8000Sstevel@tonic-gate 
8010Sstevel@tonic-gate direct_abstract_declarator:
8020Sstevel@tonic-gate 		lparen abstract_declarator DT_TOK_RPAR { $$ = $2; }
8030Sstevel@tonic-gate 	|	direct_abstract_declarator array { dt_decl_array($2); }
8040Sstevel@tonic-gate 	|	array { dt_decl_array($1); $$ = NULL; }
8050Sstevel@tonic-gate 	|	direct_abstract_declarator function { dt_decl_func($1, $2); }
8060Sstevel@tonic-gate 	|	function { dt_decl_func(NULL, $1); }
8070Sstevel@tonic-gate 	;
8080Sstevel@tonic-gate 
809*1222Smws array:		DT_TOK_LBRAC { dt_scope_push(NULL, CTF_ERR); }
810*1222Smws 		    array_parameters DT_TOK_RBRAC {
8110Sstevel@tonic-gate 			dt_scope_pop();
8120Sstevel@tonic-gate 			$$ = $3;
8130Sstevel@tonic-gate 		}
8140Sstevel@tonic-gate 	;
8150Sstevel@tonic-gate 
816*1222Smws array_parameters:
817*1222Smws 		/* empty */ 		{ $$ = NULL; }
818*1222Smws 	|	constant_expression	{ $$ = $1; }
819*1222Smws 	|	parameter_type_list	{ $$ = $1; }
820*1222Smws 	;
821*1222Smws 
822*1222Smws function:	DT_TOK_LPAR { dt_scope_push(NULL, CTF_ERR); }
823*1222Smws 		    function_parameters DT_TOK_RPAR {
8240Sstevel@tonic-gate 			dt_scope_pop();
8250Sstevel@tonic-gate 			$$ = $3;
8260Sstevel@tonic-gate 		}
8270Sstevel@tonic-gate 	;
8280Sstevel@tonic-gate 
829*1222Smws function_parameters:
830*1222Smws 		/* empty */ 		{ $$ = NULL; }
831*1222Smws 	|	parameter_type_list	{ $$ = $1; }
832*1222Smws 	;
833*1222Smws 
8340Sstevel@tonic-gate %%
835