dt_grammar.y revision 272671
145095Ssos%{
2124403Ssos/*
345095Ssos * CDDL HEADER START
445095Ssos *
545095Ssos * The contents of this file are subject to the terms of the
645095Ssos * Common Development and Distribution License, Version 1.0 only
745095Ssos * (the "License").  You may not use this file except in compliance
845095Ssos * with the License.
945095Ssos *
1045095Ssos * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1145095Ssos * or http://www.opensolaris.org/os/licensing.
1245095Ssos * See the License for the specific language governing permissions
1345095Ssos * and limitations under the License.
1445095Ssos *
1545095Ssos * When distributing Covered Code, include this CDDL HEADER in each
1645095Ssos * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1745095Ssos * If applicable, add the following below this CDDL HEADER, with the
1845095Ssos * fields enclosed by brackets "[]" replaced with your own identifying
1945095Ssos * information: Portions Copyright [yyyy] [name of copyright owner]
2045095Ssos *
2145095Ssos * CDDL HEADER END
2245095Ssos *
2345095Ssos * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
2445095Ssos * Use is subject to license terms.
2545095Ssos */
2645095Ssos/*
2745095Ssos * Copyright (c) 2013 by Delphix. All rights reserved.
2845095Ssos * Copyright (c) 2013, Joyent, Inc. All rights reserved.
29119418Sobrien */
30119418Sobrien
31119418Sobrien#include <dt_impl.h>
3245095Ssos
3345095Ssos#define	OP1(op, c)	dt_node_op1(op, c)
3474302Ssos#define	OP2(op, l, r)	dt_node_op2(op, l, r)
35111188Ssos#define	OP3(x, y, z)	dt_node_op3(x, y, z)
3695533Smike#define	LINK(l, r)	dt_node_link(l, r)
3745095Ssos#define	DUP(s)		strdup(s)
38117126Sscottl
39124403Ssos%}
40119404Ssos
41124534Ssos%union {
4245798Ssos	dt_node_t *l_node;
4366106Ssos	dt_decl_t *l_decl;
4472106Ssos	char *l_str;
45119404Ssos	uintmax_t l_int;
4645095Ssos	int l_tok;
47111188Ssos}
4845095Ssos
4952067Ssos%token	DT_TOK_COMMA DT_TOK_ELLIPSIS
50119453Ssos%token	DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ
51112791Ssos%token	DT_TOK_DIV_EQ DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ
52133637Ssos%token	DT_TOK_LSH_EQ DT_TOK_RSH_EQ DT_TOK_QUESTION DT_TOK_COLON
53121310Ssos%token	DT_TOK_LOR DT_TOK_LXOR DT_TOK_LAND
54121310Ssos%token	DT_TOK_BOR DT_TOK_XOR DT_TOK_BAND DT_TOK_EQU DT_TOK_NEQ
5552067Ssos%token	DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE DT_TOK_LSH DT_TOK_RSH
56111188Ssos%token	DT_TOK_ADD DT_TOK_SUB DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
57111188Ssos%token	DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
58111188Ssos%token	DT_TOK_PREINC DT_TOK_POSTINC DT_TOK_PREDEC DT_TOK_POSTDEC
5952067Ssos%token	DT_TOK_IPOS DT_TOK_INEG DT_TOK_DEREF DT_TOK_ADDROF
60111188Ssos%token	DT_TOK_OFFSETOF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
61133556Ssos%token	DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
6245720Speter
6393882Ssos%token <l_str>	DT_TOK_STRING
6493882Ssos%token <l_str>	DT_TOK_IDENT
6593882Ssos%token <l_str>	DT_TOK_PSPEC
6693882Ssos%token <l_str>	DT_TOK_AGG
6793882Ssos%token <l_str>	DT_TOK_TNAME
68119453Ssos%token <l_int>	DT_TOK_INT
69111188Ssos
70111188Ssos%token	DT_KEY_AUTO
71119453Ssos%token	DT_KEY_BREAK
72119453Ssos%token	DT_KEY_CASE
73119453Ssos%token	DT_KEY_CHAR
74133637Ssos%token	DT_KEY_CONST
75121310Ssos%token	DT_KEY_CONTINUE
76121310Ssos%token	DT_KEY_COUNTER
77119453Ssos%token	DT_KEY_DEFAULT
78135034Ssos%token	DT_KEY_DO
79135034Ssos%token	DT_KEY_DOUBLE
80119453Ssos%token	DT_KEY_ELSE
81111188Ssos%token	DT_KEY_ENUM
82111188Ssos%token	DT_KEY_EXTERN
8393882Ssos%token	DT_KEY_FLOAT
8493882Ssos%token	DT_KEY_FOR
8566070Ssos%token	DT_KEY_GOTO
8693882Ssos%token	DT_KEY_IF
8766070Ssos%token	DT_KEY_IMPORT
8893882Ssos%token	DT_KEY_INLINE
8993882Ssos%token	DT_KEY_INT
9093882Ssos%token	DT_KEY_LONG
9193882Ssos%token	DT_KEY_PROBE
92119453Ssos%token	DT_KEY_PROVIDER
93112791Ssos%token	DT_KEY_REGISTER
9493882Ssos%token	DT_KEY_RESTRICT
9593882Ssos%token	DT_KEY_RETURN
9693882Ssos%token	DT_KEY_SELF
97134090Ssos%token	DT_KEY_SHORT
98120883Ssos%token	DT_KEY_SIGNED
99135034Ssos%token	DT_KEY_STATIC
100134090Ssos%token	DT_KEY_STRING
101120883Ssos%token	DT_KEY_STRUCT
102119453Ssos%token	DT_KEY_SWITCH
103119453Ssos%token	DT_KEY_THIS
104120883Ssos%token	DT_KEY_TYPEDEF
105119453Ssos%token	DT_KEY_UNION
106120883Ssos%token	DT_KEY_UNSIGNED
107120883Ssos%token	DT_KEY_USERLAND
108119453Ssos%token	DT_KEY_VOID
109119453Ssos%token	DT_KEY_VOLATILE
110123034Ssos%token	DT_KEY_WHILE
111119453Ssos%token	DT_KEY_XLATOR
112135034Ssos
113134090Ssos%token	DT_TOK_EPRED
114119453Ssos%token	DT_CTX_DEXPR
115119453Ssos%token	DT_CTX_DPROG
116119453Ssos%token	DT_CTX_DTYPE
117119453Ssos%token	DT_TOK_EOF	0
118119453Ssos
119119453Ssos%left	DT_TOK_COMMA
120119453Ssos%right	DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ DT_TOK_DIV_EQ
121119453Ssos	DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ DT_TOK_LSH_EQ
122119453Ssos	DT_TOK_RSH_EQ
123128183Ssos%left	DT_TOK_QUESTION DT_TOK_COLON
124119453Ssos%left	DT_TOK_LOR
125112791Ssos%left	DT_TOK_LXOR
126119453Ssos%left	DT_TOK_LAND
127128183Ssos%left	DT_TOK_BOR
128119453Ssos%left	DT_TOK_XOR
129119453Ssos%left	DT_TOK_BAND
130128183Ssos%left	DT_TOK_EQU DT_TOK_NEQ
131128183Ssos%left	DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE
132128183Ssos%left	DT_TOK_LSH DT_TOK_RSH
133128183Ssos%left	DT_TOK_ADD DT_TOK_SUB
134128183Ssos%left	DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
135128183Ssos%right	DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
136128183Ssos	DT_TOK_IPOS DT_TOK_INEG
137128183Ssos%right	DT_TOK_DEREF DT_TOK_ADDROF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
138128183Ssos%left	DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
139128183Ssos
140128183Ssos%type	<l_node>	d_expression
141128183Ssos%type	<l_node>	d_program
142128183Ssos%type	<l_node>	d_type
143128183Ssos
144128183Ssos%type	<l_node>	translation_unit
145128183Ssos%type	<l_node>	external_declaration
146128183Ssos%type	<l_node>	inline_definition
147128183Ssos%type	<l_node>	translator_definition
148119453Ssos%type	<l_node>	translator_member_list
14993882Ssos%type	<l_node>	translator_member
150119453Ssos%type	<l_node>	provider_definition
151128183Ssos%type	<l_node>	provider_probe_list
152119453Ssos%type	<l_node>	provider_probe
153119453Ssos%type	<l_node>	probe_definition
154119453Ssos%type	<l_node>	probe_specifiers
15566070Ssos%type	<l_node>	probe_specifier_list
15666070Ssos%type	<l_node>	probe_specifier
157111188Ssos%type	<l_node>	statement_list
158112791Ssos%type	<l_node>	statement
15945095Ssos%type	<l_node>	declaration
160128183Ssos%type	<l_node>	init_declarator_list
161128183Ssos%type	<l_node>	init_declarator
162128183Ssos
163128183Ssos%type	<l_decl>	type_specifier
164128183Ssos%type	<l_decl>	type_qualifier
165128183Ssos%type	<l_decl>	struct_or_union_specifier
166128183Ssos%type	<l_decl>	specifier_qualifier_list
167128183Ssos%type	<l_decl>	enum_specifier
168128183Ssos%type	<l_decl>	declarator
169128183Ssos%type	<l_decl>	direct_declarator
170128183Ssos%type	<l_decl>	pointer
171112791Ssos%type	<l_decl>	type_qualifier_list
172112791Ssos%type	<l_decl>	type_name
173112791Ssos%type	<l_decl>	abstract_declarator
174112791Ssos%type	<l_decl>	direct_abstract_declarator
175112791Ssos
176112791Ssos%type	<l_node>	parameter_type_list
17793882Ssos%type	<l_node>	parameter_list
178112791Ssos%type	<l_node>	parameter_declaration
179112791Ssos
180112791Ssos%type	<l_node>	array
18193882Ssos%type	<l_node>	array_parameters
182112791Ssos%type	<l_node>	function
183112791Ssos%type	<l_node>	function_parameters
184112791Ssos
18593882Ssos%type	<l_node>	expression
186112791Ssos%type	<l_node>	assignment_expression
187112791Ssos%type	<l_node>	conditional_expression
188112791Ssos%type	<l_node>	constant_expression
18993882Ssos%type	<l_node>	logical_or_expression
190112791Ssos%type	<l_node>	logical_xor_expression
191112791Ssos%type	<l_node>	logical_and_expression
192112791Ssos%type	<l_node>	inclusive_or_expression
19393882Ssos%type	<l_node>	exclusive_or_expression
19493882Ssos%type	<l_node>	and_expression
19593882Ssos%type	<l_node>	equality_expression
19693882Ssos%type	<l_node>	relational_expression
197133637Ssos%type	<l_node>	shift_expression
19893882Ssos%type	<l_node>	additive_expression
199133637Ssos%type	<l_node>	multiplicative_expression
200133637Ssos%type	<l_node>	cast_expression
201133637Ssos%type	<l_node>	unary_expression
20293882Ssos%type	<l_node>	postfix_expression
203133637Ssos%type	<l_node>	primary_expression
20493882Ssos%type	<l_node>	argument_expression_list
205133637Ssos
20693882Ssos%type	<l_tok>		assignment_operator
207133637Ssos%type	<l_tok>		unary_operator
208133637Ssos%type	<l_tok>		struct_or_union
20993882Ssos
210133637Ssos%type	<l_str>		dtrace_keyword_ident
21193882Ssos
21293882Ssos%%
213111188Ssos
214121310Ssosdtrace_program: d_expression DT_TOK_EOF { return (dt_node_root($1)); }
21545095Ssos	|	d_program DT_TOK_EOF { return (dt_node_root($1)); }
21693882Ssos	|	d_type DT_TOK_EOF { return (dt_node_root($1)); }
217133637Ssos	;
21845095Ssos
219133637Ssosd_expression:	DT_CTX_DEXPR { $$ = NULL; }
220121310Ssos	|	DT_CTX_DEXPR expression { $$ = $2; }
22145095Ssos	;
22266070Ssos
22345095Ssosd_program:	DT_CTX_DPROG { $$ = dt_node_program(NULL); }
224119404Ssos	|	DT_CTX_DPROG translation_unit { $$ = dt_node_program($2); }
22545095Ssos	;
22645095Ssos
227121310Ssosd_type:		DT_CTX_DTYPE { $$ = NULL; }
228121310Ssos	|	DT_CTX_DTYPE type_name { $$ = (dt_node_t *)$2; }
229121310Ssos	;
230121310Ssos
231121310Ssostranslation_unit:
232119404Ssos		external_declaration
233119404Ssos	|	translation_unit external_declaration { $$ = LINK($1, $2); }
234119404Ssos	;
235119404Ssos
236119404Ssosexternal_declaration:
237119404Ssos		inline_definition
23845095Ssos	|	translator_definition
239121310Ssos	|	provider_definition
24095010Ssos	|	probe_definition
241121310Ssos	|	declaration
24295010Ssos	;
243112791Ssos
244133637Ssosinline_definition:
24595010Ssos		DT_KEY_INLINE declaration_specifiers declarator
24693882Ssos		    { dt_scope_push(NULL, CTF_ERR); } DT_TOK_ASGN
247112791Ssos		    assignment_expression ';' {
248112791Ssos			/*
24995010Ssos			 * We push a new declaration scope before shifting the
250121310Ssos			 * assignment_expression in order to preserve ds_class
251133184Ssos			 * and ds_ident for use in dt_node_inline().  Once the
25295010Ssos			 * entire inline_definition rule is matched, pop the
25345095Ssos			 * scope and construct the inline using the saved decl.
25445095Ssos			 */
25566070Ssos			dt_scope_pop();
256121310Ssos			$$ = dt_node_inline($6);
25745095Ssos		}
258119404Ssos	;
259119404Ssos
260112791Ssostranslator_definition:
261112791Ssos		DT_KEY_XLATOR type_name DT_TOK_LT type_name
26293882Ssos		    DT_TOK_IDENT DT_TOK_GT '{' translator_member_list '}' ';' {
263112791Ssos			$$ = dt_node_xlator($2, $4, $5, $8);
264119404Ssos		}
265121310Ssos	|	DT_KEY_XLATOR type_name DT_TOK_LT type_name
266133184Ssos		    DT_TOK_IDENT DT_TOK_GT '{' '}' ';' {
267112791Ssos			$$ = dt_node_xlator($2, $4, $5, NULL);
26845095Ssos		}
269	;
270
271translator_member_list:
272		translator_member
273	|	translator_member_list translator_member { $$ = LINK($1,$2); }
274	;
275
276translator_member:
277		DT_TOK_IDENT DT_TOK_ASGN assignment_expression ';' {
278			$$ = dt_node_member(NULL, $1, $3);
279		}
280	;
281
282provider_definition:
283		DT_KEY_PROVIDER DT_TOK_IDENT '{' provider_probe_list '}' ';' {
284			$$ = dt_node_provider($2, $4);
285		}
286	|	DT_KEY_PROVIDER DT_TOK_IDENT '{' '}' ';' {
287			$$ = dt_node_provider($2, NULL);
288		}
289	;
290
291provider_probe_list:
292		provider_probe
293	|	provider_probe_list provider_probe { $$ = LINK($1, $2); }
294	;
295
296provider_probe:
297		DT_KEY_PROBE DT_TOK_IDENT function DT_TOK_COLON function ';' {
298			$$ = dt_node_probe($2, 2, $3, $5);
299		}
300	|	DT_KEY_PROBE DT_TOK_IDENT function ';' {
301			$$ = dt_node_probe($2, 1, $3, NULL);
302		}
303	;
304
305
306probe_definition:
307		probe_specifiers {
308			/*
309			 * If the input stream is a file, do not permit a probe
310			 * specification without / <pred> / or { <act> } after
311			 * it.  This can only occur if the next token is EOF or
312			 * an ambiguous predicate was slurped up as a comment.
313			 * We cannot perform this check if input() is a string
314			 * because dtrace(1M) [-fmnP] also use the compiler and
315			 * things like dtrace -n BEGIN have to be accepted.
316			 */
317			if (yypcb->pcb_fileptr != NULL) {
318				dnerror($1, D_SYNTAX, "expected predicate and/"
319				    "or actions following probe description\n");
320			}
321			$$ = dt_node_clause($1, NULL, NULL);
322		}
323	|	probe_specifiers '{' statement_list '}' {
324			$$ = dt_node_clause($1, NULL, $3);
325		}
326	|	probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED {
327			dnerror($3, D_SYNTAX, "expected actions { } following "
328			    "probe description and predicate\n");
329		}
330	|	probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED
331		    '{' statement_list '}' {
332			$$ = dt_node_clause($1, $3, $6);
333		}
334	;
335
336probe_specifiers:
337		probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; }
338	;
339
340probe_specifier_list:
341		probe_specifier
342	|	probe_specifier_list DT_TOK_COMMA probe_specifier {
343			$$ = LINK($1, $3);
344		}
345	;
346
347probe_specifier:
348		DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); }
349	|	DT_TOK_INT   { $$ = dt_node_pdesc_by_id($1); }
350	;
351
352statement_list:	statement { $$ = $1; }
353	|	statement_list ';' statement { $$ = LINK($1, $3); }
354	;
355
356statement:	/* empty */ { $$ = NULL; }
357	|	expression { $$ = dt_node_statement($1); }
358	;
359
360argument_expression_list:
361		assignment_expression
362	|	argument_expression_list DT_TOK_COMMA assignment_expression {
363			$$ = LINK($1, $3);
364		}
365	;
366
367primary_expression:
368		DT_TOK_IDENT { $$ = dt_node_ident($1); }
369	|	DT_TOK_AGG { $$ = dt_node_ident($1); }
370	|	DT_TOK_INT { $$ = dt_node_int($1); }
371	|	DT_TOK_STRING { $$ = dt_node_string($1); }
372	|	DT_KEY_SELF { $$ = dt_node_ident(DUP("self")); }
373	|	DT_KEY_THIS { $$ = dt_node_ident(DUP("this")); }
374	|	DT_TOK_LPAR expression DT_TOK_RPAR { $$ = $2; }
375	;
376
377postfix_expression:
378		primary_expression
379	|	postfix_expression
380		    DT_TOK_LBRAC argument_expression_list DT_TOK_RBRAC {
381			$$ = OP2(DT_TOK_LBRAC, $1, $3);
382		}
383	|	postfix_expression DT_TOK_LPAR DT_TOK_RPAR {
384			$$ = dt_node_func($1, NULL);
385		}
386	|	postfix_expression
387		    DT_TOK_LPAR argument_expression_list DT_TOK_RPAR {
388			$$ = dt_node_func($1, $3);
389		}
390	|	postfix_expression DT_TOK_DOT DT_TOK_IDENT {
391			$$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
392		}
393	|	postfix_expression DT_TOK_DOT DT_TOK_TNAME {
394			$$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
395		}
396	|	postfix_expression DT_TOK_DOT dtrace_keyword_ident {
397			$$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
398		}
399	|	postfix_expression DT_TOK_PTR DT_TOK_IDENT {
400			$$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
401		}
402	|	postfix_expression DT_TOK_PTR DT_TOK_TNAME {
403			$$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
404		}
405	|	postfix_expression DT_TOK_PTR dtrace_keyword_ident {
406			$$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
407		}
408	|	postfix_expression DT_TOK_ADDADD {
409			$$ = OP1(DT_TOK_POSTINC, $1);
410		}
411	|	postfix_expression DT_TOK_SUBSUB {
412			$$ = OP1(DT_TOK_POSTDEC, $1);
413		}
414	|	DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA
415		    DT_TOK_IDENT DT_TOK_RPAR {
416			$$ = dt_node_offsetof($3, $5);
417		}
418	|	DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA
419		    DT_TOK_TNAME DT_TOK_RPAR {
420			$$ = dt_node_offsetof($3, $5);
421		}
422	|	DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA
423		    dtrace_keyword_ident DT_TOK_RPAR {
424			$$ = dt_node_offsetof($3, $5);
425		}
426	|	DT_TOK_XLATE DT_TOK_LT type_name DT_TOK_GT
427		    DT_TOK_LPAR expression DT_TOK_RPAR {
428			$$ = OP2(DT_TOK_XLATE, dt_node_type($3), $6);
429		}
430	;
431
432unary_expression:
433		postfix_expression
434	|	DT_TOK_ADDADD unary_expression { $$ = OP1(DT_TOK_PREINC, $2); }
435	|	DT_TOK_SUBSUB unary_expression { $$ = OP1(DT_TOK_PREDEC, $2); }
436	|	unary_operator cast_expression { $$ = OP1($1, $2); }
437	|	DT_TOK_SIZEOF unary_expression { $$ = OP1(DT_TOK_SIZEOF, $2); }
438	|	DT_TOK_SIZEOF DT_TOK_LPAR type_name DT_TOK_RPAR {
439			$$ = OP1(DT_TOK_SIZEOF, dt_node_type($3));
440		}
441	|	DT_TOK_STRINGOF unary_expression {
442			$$ = OP1(DT_TOK_STRINGOF, $2);
443		}
444	;
445
446unary_operator:	DT_TOK_BAND { $$ = DT_TOK_ADDROF; }
447	|	DT_TOK_MUL { $$ = DT_TOK_DEREF; }
448	|	DT_TOK_ADD { $$ = DT_TOK_IPOS; }
449	|	DT_TOK_SUB { $$ = DT_TOK_INEG; }
450	|	DT_TOK_BNEG { $$ = DT_TOK_BNEG; }
451	|	DT_TOK_LNEG { $$ = DT_TOK_LNEG; }
452	;
453
454cast_expression:
455		unary_expression
456	|	DT_TOK_LPAR type_name DT_TOK_RPAR cast_expression {
457			$$ = OP2(DT_TOK_LPAR, dt_node_type($2), $4);
458		}
459	;
460
461multiplicative_expression:
462		cast_expression
463	|	multiplicative_expression DT_TOK_MUL cast_expression {
464			$$ = OP2(DT_TOK_MUL, $1, $3);
465		}
466	|	multiplicative_expression DT_TOK_DIV cast_expression {
467			$$ = OP2(DT_TOK_DIV, $1, $3);
468		}
469	|	multiplicative_expression DT_TOK_MOD cast_expression {
470			$$ = OP2(DT_TOK_MOD, $1, $3);
471		}
472	;
473
474additive_expression:
475		multiplicative_expression
476	|	additive_expression DT_TOK_ADD multiplicative_expression {
477			$$ = OP2(DT_TOK_ADD, $1, $3);
478		}
479	|	additive_expression DT_TOK_SUB multiplicative_expression {
480			$$ = OP2(DT_TOK_SUB, $1, $3);
481		}
482	;
483
484shift_expression:
485		additive_expression
486	|	shift_expression DT_TOK_LSH additive_expression {
487			$$ = OP2(DT_TOK_LSH, $1, $3);
488		}
489	|	shift_expression DT_TOK_RSH additive_expression {
490			$$ = OP2(DT_TOK_RSH, $1, $3);
491		}
492	;
493
494relational_expression:
495		shift_expression
496	|	relational_expression DT_TOK_LT shift_expression {
497			$$ = OP2(DT_TOK_LT, $1, $3);
498		}
499	|	relational_expression DT_TOK_GT shift_expression {
500			$$ = OP2(DT_TOK_GT, $1, $3);
501		}
502	|	relational_expression DT_TOK_LE shift_expression {
503			$$ = OP2(DT_TOK_LE, $1, $3);
504		}
505	|	relational_expression DT_TOK_GE shift_expression {
506			$$ = OP2(DT_TOK_GE, $1, $3);
507		}
508	;
509
510equality_expression:
511		relational_expression
512	|	equality_expression DT_TOK_EQU relational_expression {
513			$$ = OP2(DT_TOK_EQU, $1, $3);
514		}
515	|	equality_expression DT_TOK_NEQ relational_expression {
516			$$ = OP2(DT_TOK_NEQ, $1, $3);
517		}
518	;
519
520and_expression:
521		equality_expression
522	|	and_expression DT_TOK_BAND equality_expression {
523			$$ = OP2(DT_TOK_BAND, $1, $3);
524		}
525	;
526
527exclusive_or_expression:
528		and_expression
529	|	exclusive_or_expression DT_TOK_XOR and_expression {
530			$$ = OP2(DT_TOK_XOR, $1, $3);
531		}
532	;
533
534inclusive_or_expression:
535		exclusive_or_expression
536	|	inclusive_or_expression DT_TOK_BOR exclusive_or_expression {
537			$$ = OP2(DT_TOK_BOR, $1, $3);
538		}
539	;
540
541logical_and_expression:
542		inclusive_or_expression
543	|	logical_and_expression DT_TOK_LAND inclusive_or_expression {
544			$$ = OP2(DT_TOK_LAND, $1, $3);
545		}
546	;
547
548logical_xor_expression:
549		logical_and_expression
550	|	logical_xor_expression DT_TOK_LXOR logical_and_expression {
551			$$ = OP2(DT_TOK_LXOR, $1, $3);
552		}
553	;
554
555logical_or_expression:
556		logical_xor_expression
557	|	logical_or_expression DT_TOK_LOR logical_xor_expression {
558			$$ = OP2(DT_TOK_LOR, $1, $3);
559		}
560	;
561
562constant_expression: conditional_expression
563	;
564
565conditional_expression:
566		logical_or_expression
567	|	logical_or_expression DT_TOK_QUESTION expression DT_TOK_COLON
568		    conditional_expression { $$ = OP3($1, $3, $5); }
569	;
570
571assignment_expression:
572		conditional_expression
573	|	unary_expression assignment_operator assignment_expression {
574			$$ = OP2($2, $1, $3);
575		}
576	;
577
578assignment_operator:
579		DT_TOK_ASGN   { $$ = DT_TOK_ASGN; }
580	|	DT_TOK_MUL_EQ { $$ = DT_TOK_MUL_EQ; }
581	|	DT_TOK_DIV_EQ { $$ = DT_TOK_DIV_EQ; }
582	|	DT_TOK_MOD_EQ { $$ = DT_TOK_MOD_EQ; }
583	|	DT_TOK_ADD_EQ { $$ = DT_TOK_ADD_EQ; }
584	|	DT_TOK_SUB_EQ { $$ = DT_TOK_SUB_EQ; }
585	|	DT_TOK_LSH_EQ { $$ = DT_TOK_LSH_EQ; }
586	|	DT_TOK_RSH_EQ { $$ = DT_TOK_RSH_EQ; }
587	|	DT_TOK_AND_EQ { $$ = DT_TOK_AND_EQ; }
588	|	DT_TOK_XOR_EQ { $$ = DT_TOK_XOR_EQ; }
589	|	DT_TOK_OR_EQ  { $$ = DT_TOK_OR_EQ; }
590	;
591
592expression:	assignment_expression
593	|	expression DT_TOK_COMMA assignment_expression {
594			$$ = OP2(DT_TOK_COMMA, $1, $3);
595		}
596	;
597
598declaration:	declaration_specifiers ';' {
599			$$ = dt_node_decl();
600			dt_decl_free(dt_decl_pop());
601			yybegin(YYS_CLAUSE);
602		}
603	|	declaration_specifiers init_declarator_list ';' {
604			$$ = $2;
605			dt_decl_free(dt_decl_pop());
606			yybegin(YYS_CLAUSE);
607		}
608	;
609
610declaration_specifiers:
611		d_storage_class_specifier
612	|	d_storage_class_specifier declaration_specifiers
613	|	type_specifier
614	|	type_specifier declaration_specifiers
615	|	type_qualifier
616	|	type_qualifier declaration_specifiers
617	;
618
619parameter_declaration_specifiers:
620		storage_class_specifier
621	|	storage_class_specifier declaration_specifiers
622	|	type_specifier
623	|	type_specifier declaration_specifiers
624	|	type_qualifier
625	|	type_qualifier declaration_specifiers
626	;
627
628storage_class_specifier:
629		DT_KEY_AUTO { dt_decl_class(DT_DC_AUTO); }
630	|	DT_KEY_REGISTER { dt_decl_class(DT_DC_REGISTER); }
631	|	DT_KEY_STATIC { dt_decl_class(DT_DC_STATIC); }
632	|	DT_KEY_EXTERN { dt_decl_class(DT_DC_EXTERN); }
633	|	DT_KEY_TYPEDEF { dt_decl_class(DT_DC_TYPEDEF); }
634	;
635
636d_storage_class_specifier:
637		storage_class_specifier
638	|	DT_KEY_SELF { dt_decl_class(DT_DC_SELF); }
639	|	DT_KEY_THIS { dt_decl_class(DT_DC_THIS); }
640	;
641
642type_specifier:	DT_KEY_VOID { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("void")); }
643	|	DT_KEY_CHAR { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("char")); }
644	|	DT_KEY_SHORT { $$ = dt_decl_attr(DT_DA_SHORT); }
645	|	DT_KEY_INT { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("int")); }
646	|	DT_KEY_LONG { $$ = dt_decl_attr(DT_DA_LONG); }
647	|	DT_KEY_FLOAT { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("float")); }
648	|	DT_KEY_DOUBLE { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("double")); }
649	|	DT_KEY_SIGNED { $$ = dt_decl_attr(DT_DA_SIGNED); }
650	|	DT_KEY_UNSIGNED { $$ = dt_decl_attr(DT_DA_UNSIGNED); }
651	|	DT_KEY_USERLAND { $$ = dt_decl_attr(DT_DA_USER); }
652	|	DT_KEY_STRING {
653			$$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string"));
654		}
655	|	DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_TYPEDEF, $1); }
656	|	struct_or_union_specifier
657	|	enum_specifier
658	;
659
660type_qualifier:	DT_KEY_CONST { $$ = dt_decl_attr(DT_DA_CONST); }
661	|	DT_KEY_RESTRICT { $$ = dt_decl_attr(DT_DA_RESTRICT); }
662	|	DT_KEY_VOLATILE { $$ = dt_decl_attr(DT_DA_VOLATILE); }
663	;
664
665struct_or_union_specifier:
666		struct_or_union_definition struct_declaration_list '}' {
667			$$ = dt_scope_pop();
668		}
669	|	struct_or_union DT_TOK_IDENT { $$ = dt_decl_spec($1, $2); }
670	|	struct_or_union DT_TOK_TNAME { $$ = dt_decl_spec($1, $2); }
671	;
672
673struct_or_union_definition:
674		struct_or_union '{' { dt_decl_sou($1, NULL); }
675	|	struct_or_union DT_TOK_IDENT '{' { dt_decl_sou($1, $2); }
676	|	struct_or_union DT_TOK_TNAME '{' { dt_decl_sou($1, $2); }
677	;
678
679struct_or_union:
680		DT_KEY_STRUCT { $$ = CTF_K_STRUCT; }
681	|	DT_KEY_UNION { $$ = CTF_K_UNION; }
682	;
683
684struct_declaration_list:
685		struct_declaration
686	|	struct_declaration_list struct_declaration
687	;
688
689init_declarator_list:
690		init_declarator
691	|	init_declarator_list DT_TOK_COMMA init_declarator {
692			$$ = LINK($1, $3);
693		}
694	;
695
696init_declarator:
697		declarator {
698			$$ = dt_node_decl();
699			dt_decl_reset();
700		}
701	;
702
703struct_declaration:
704		specifier_qualifier_list struct_declarator_list ';' {
705			dt_decl_free(dt_decl_pop());
706		}
707	;
708
709specifier_qualifier_list:
710		type_specifier
711	|	type_specifier specifier_qualifier_list { $$ = $2; }
712	|	type_qualifier
713	|	type_qualifier specifier_qualifier_list { $$ = $2; }
714	;
715
716struct_declarator_list:
717		struct_declarator
718	|	struct_declarator_list DT_TOK_COMMA struct_declarator
719	;
720
721struct_declarator:
722		declarator { dt_decl_member(NULL); }
723	|	DT_TOK_COLON constant_expression { dt_decl_member($2); }
724	|	declarator DT_TOK_COLON constant_expression {
725			dt_decl_member($3);
726		}
727	;
728
729enum_specifier:
730		enum_definition enumerator_list '}' { $$ = dt_scope_pop(); }
731	|	DT_KEY_ENUM DT_TOK_IDENT { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
732	|	DT_KEY_ENUM DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
733	;
734
735enum_definition:
736		DT_KEY_ENUM '{' { dt_decl_enum(NULL); }
737	|	DT_KEY_ENUM DT_TOK_IDENT '{' { dt_decl_enum($2); }
738	|	DT_KEY_ENUM DT_TOK_TNAME '{' { dt_decl_enum($2); }
739	;
740
741enumerator_list:
742		enumerator
743	|	enumerator_list DT_TOK_COMMA enumerator
744	;
745
746enumerator:	DT_TOK_IDENT { dt_decl_enumerator($1, NULL); }
747	|	DT_TOK_IDENT DT_TOK_ASGN expression {
748			dt_decl_enumerator($1, $3);
749		}
750	;
751
752declarator:	direct_declarator
753	|	pointer direct_declarator
754	;
755
756direct_declarator:
757		DT_TOK_IDENT { $$ = dt_decl_ident($1); }
758	|	lparen declarator DT_TOK_RPAR { $$ = $2; }
759	|	direct_declarator array { dt_decl_array($2); }
760	|	direct_declarator function { dt_decl_func($1, $2); }
761	;
762
763lparen:		DT_TOK_LPAR { dt_decl_top()->dd_attr |= DT_DA_PAREN; }
764	;
765
766pointer:	DT_TOK_MUL { $$ = dt_decl_ptr(); }
767	|	DT_TOK_MUL type_qualifier_list { $$ = dt_decl_ptr(); }
768	|	DT_TOK_MUL pointer { $$ = dt_decl_ptr(); }
769	|	DT_TOK_MUL type_qualifier_list pointer { $$ = dt_decl_ptr(); }
770	;
771
772type_qualifier_list:
773		type_qualifier
774	|	type_qualifier_list type_qualifier { $$ = $2; }
775	;
776
777parameter_type_list:
778		parameter_list
779	|	DT_TOK_ELLIPSIS { $$ = dt_node_vatype(); }
780	|	parameter_list DT_TOK_COMMA DT_TOK_ELLIPSIS {
781			$$ = LINK($1, dt_node_vatype());
782		}
783	;
784
785parameter_list:	parameter_declaration
786	|	parameter_list DT_TOK_COMMA parameter_declaration {
787			$$ = LINK($1, $3);
788		}
789	;
790
791parameter_declaration:
792		parameter_declaration_specifiers {
793			$$ = dt_node_type(NULL);
794		}
795	|	parameter_declaration_specifiers declarator {
796			$$ = dt_node_type(NULL);
797		}
798	|	parameter_declaration_specifiers abstract_declarator {
799			$$ = dt_node_type(NULL);
800		}
801	;
802
803type_name:	specifier_qualifier_list {
804			$$ = dt_decl_pop();
805		}
806	|	specifier_qualifier_list abstract_declarator {
807			$$ = dt_decl_pop();
808		}
809	;
810
811abstract_declarator:
812		pointer
813	|	direct_abstract_declarator
814	|	pointer direct_abstract_declarator
815	;
816
817direct_abstract_declarator:
818		lparen abstract_declarator DT_TOK_RPAR { $$ = $2; }
819	|	direct_abstract_declarator array { dt_decl_array($2); }
820	|	array { dt_decl_array($1); $$ = NULL; }
821	|	direct_abstract_declarator function { dt_decl_func($1, $2); }
822	|	function { dt_decl_func(NULL, $1); }
823	;
824
825array:		DT_TOK_LBRAC { dt_scope_push(NULL, CTF_ERR); }
826		    array_parameters DT_TOK_RBRAC {
827			dt_scope_pop();
828			$$ = $3;
829		}
830	;
831
832array_parameters:
833		/* empty */ 		{ $$ = NULL; }
834	|	constant_expression	{ $$ = $1; }
835	|	parameter_type_list	{ $$ = $1; }
836	;
837
838function:	DT_TOK_LPAR { dt_scope_push(NULL, CTF_ERR); }
839		    function_parameters DT_TOK_RPAR {
840			dt_scope_pop();
841			$$ = $3;
842		}
843	;
844
845function_parameters:
846		/* empty */ 		{ $$ = NULL; }
847	|	parameter_type_list	{ $$ = $1; }
848	;
849
850dtrace_keyword_ident:
851	  DT_KEY_PROBE { $$ = DUP("probe"); }
852	| DT_KEY_PROVIDER { $$ = DUP("provider"); }
853	| DT_KEY_SELF { $$ = DUP("self"); }
854	| DT_KEY_STRING { $$ = DUP("string"); }
855	| DT_TOK_STRINGOF { $$ = DUP("stringof"); }
856	| DT_KEY_USERLAND { $$ = DUP("userland"); }
857	| DT_TOK_XLATE { $$ = DUP("xlate"); }
858	| DT_KEY_XLATOR { $$ = DUP("translator"); }
859	;
860
861%%
862