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