]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - cddl/contrib/opensolaris/lib/libdtrace/common/dt_grammar.y
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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  * Copyright (c) 2013 by Delphix. All rights reserved.
28  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
29  */
30
31 #include <dt_impl.h>
32
33 #define OP1(op, c)      dt_node_op1(op, c)
34 #define OP2(op, l, r)   dt_node_op2(op, l, r)
35 #define OP3(x, y, z)    dt_node_op3(x, y, z)
36 #define LINK(l, r)      dt_node_link(l, r)
37 #define DUP(s)          strdup(s)
38
39 %}
40
41 %union {
42         dt_node_t *l_node;
43         dt_decl_t *l_decl;
44         char *l_str;
45         uintmax_t l_int;
46         int l_tok;
47 }
48
49 %token  DT_TOK_COMMA DT_TOK_ELLIPSIS
50 %token  DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ
51 %token  DT_TOK_DIV_EQ DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ
52 %token  DT_TOK_LSH_EQ DT_TOK_RSH_EQ DT_TOK_QUESTION DT_TOK_COLON
53 %token  DT_TOK_LOR DT_TOK_LXOR DT_TOK_LAND
54 %token  DT_TOK_BOR DT_TOK_XOR DT_TOK_BAND DT_TOK_EQU DT_TOK_NEQ
55 %token  DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE DT_TOK_LSH DT_TOK_RSH
56 %token  DT_TOK_ADD DT_TOK_SUB DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
57 %token  DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
58 %token  DT_TOK_PREINC DT_TOK_POSTINC DT_TOK_PREDEC DT_TOK_POSTDEC
59 %token  DT_TOK_IPOS DT_TOK_INEG DT_TOK_DEREF DT_TOK_ADDROF
60 %token  DT_TOK_OFFSETOF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
61 %token  DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
62
63 %token <l_str>  DT_TOK_STRING
64 %token <l_str>  DT_TOK_IDENT
65 %token <l_str>  DT_TOK_PSPEC
66 %token <l_str>  DT_TOK_AGG
67 %token <l_str>  DT_TOK_TNAME
68 %token <l_int>  DT_TOK_INT
69
70 %token  DT_KEY_AUTO
71 %token  DT_KEY_BREAK
72 %token  DT_KEY_CASE
73 %token  DT_KEY_CHAR
74 %token  DT_KEY_CONST
75 %token  DT_KEY_CONTINUE
76 %token  DT_KEY_COUNTER
77 %token  DT_KEY_DEFAULT
78 %token  DT_KEY_DO
79 %token  DT_KEY_DOUBLE
80 %token  DT_KEY_ELSE
81 %token  DT_KEY_ENUM
82 %token  DT_KEY_EXTERN
83 %token  DT_KEY_FLOAT
84 %token  DT_KEY_FOR
85 %token  DT_KEY_GOTO
86 %token  DT_KEY_IF
87 %token  DT_KEY_IMPORT
88 %token  DT_KEY_INLINE
89 %token  DT_KEY_INT
90 %token  DT_KEY_LONG
91 %token  DT_KEY_PROBE
92 %token  DT_KEY_PROVIDER
93 %token  DT_KEY_REGISTER
94 %token  DT_KEY_RESTRICT
95 %token  DT_KEY_RETURN
96 %token  DT_KEY_SELF
97 %token  DT_KEY_SHORT
98 %token  DT_KEY_SIGNED
99 %token  DT_KEY_STATIC
100 %token  DT_KEY_STRING
101 %token  DT_KEY_STRUCT
102 %token  DT_KEY_SWITCH
103 %token  DT_KEY_THIS
104 %token  DT_KEY_TYPEDEF
105 %token  DT_KEY_UNION
106 %token  DT_KEY_UNSIGNED
107 %token  DT_KEY_USERLAND
108 %token  DT_KEY_VOID
109 %token  DT_KEY_VOLATILE
110 %token  DT_KEY_WHILE
111 %token  DT_KEY_XLATOR
112
113 %token  DT_TOK_EPRED
114 %token  DT_CTX_DEXPR
115 %token  DT_CTX_DPROG
116 %token  DT_CTX_DTYPE
117 %token  DT_TOK_EOF      0
118
119 %left   DT_TOK_COMMA
120 %right  DT_TOK_ASGN DT_TOK_ADD_EQ DT_TOK_SUB_EQ DT_TOK_MUL_EQ DT_TOK_DIV_EQ
121         DT_TOK_MOD_EQ DT_TOK_AND_EQ DT_TOK_XOR_EQ DT_TOK_OR_EQ DT_TOK_LSH_EQ
122         DT_TOK_RSH_EQ
123 %left   DT_TOK_QUESTION DT_TOK_COLON
124 %left   DT_TOK_LOR
125 %left   DT_TOK_LXOR
126 %left   DT_TOK_LAND
127 %left   DT_TOK_BOR
128 %left   DT_TOK_XOR
129 %left   DT_TOK_BAND
130 %left   DT_TOK_EQU DT_TOK_NEQ
131 %left   DT_TOK_LT DT_TOK_LE DT_TOK_GT DT_TOK_GE
132 %left   DT_TOK_LSH DT_TOK_RSH
133 %left   DT_TOK_ADD DT_TOK_SUB
134 %left   DT_TOK_MUL DT_TOK_DIV DT_TOK_MOD
135 %right  DT_TOK_LNEG DT_TOK_BNEG DT_TOK_ADDADD DT_TOK_SUBSUB
136         DT_TOK_IPOS DT_TOK_INEG
137 %right  DT_TOK_DEREF DT_TOK_ADDROF DT_TOK_SIZEOF DT_TOK_STRINGOF DT_TOK_XLATE
138 %left   DT_TOK_LPAR DT_TOK_RPAR DT_TOK_LBRAC DT_TOK_RBRAC DT_TOK_PTR DT_TOK_DOT
139
140 %type   <l_node>        d_expression
141 %type   <l_node>        d_program
142 %type   <l_node>        d_type
143
144 %type   <l_node>        translation_unit
145 %type   <l_node>        external_declaration
146 %type   <l_node>        inline_definition
147 %type   <l_node>        translator_definition
148 %type   <l_node>        translator_member_list
149 %type   <l_node>        translator_member
150 %type   <l_node>        provider_definition
151 %type   <l_node>        provider_probe_list
152 %type   <l_node>        provider_probe
153 %type   <l_node>        probe_definition
154 %type   <l_node>        probe_specifiers
155 %type   <l_node>        probe_specifier_list
156 %type   <l_node>        probe_specifier
157 %type   <l_node>        statement_list
158 %type   <l_node>        statement
159 %type   <l_node>        declaration
160 %type   <l_node>        init_declarator_list
161 %type   <l_node>        init_declarator
162
163 %type   <l_decl>        type_specifier
164 %type   <l_decl>        type_qualifier
165 %type   <l_decl>        struct_or_union_specifier
166 %type   <l_decl>        specifier_qualifier_list
167 %type   <l_decl>        enum_specifier
168 %type   <l_decl>        declarator
169 %type   <l_decl>        direct_declarator
170 %type   <l_decl>        pointer
171 %type   <l_decl>        type_qualifier_list
172 %type   <l_decl>        type_name
173 %type   <l_decl>        abstract_declarator
174 %type   <l_decl>        direct_abstract_declarator
175
176 %type   <l_node>        parameter_type_list
177 %type   <l_node>        parameter_list
178 %type   <l_node>        parameter_declaration
179
180 %type   <l_node>        array
181 %type   <l_node>        array_parameters
182 %type   <l_node>        function
183 %type   <l_node>        function_parameters
184
185 %type   <l_node>        expression
186 %type   <l_node>        assignment_expression
187 %type   <l_node>        conditional_expression
188 %type   <l_node>        constant_expression
189 %type   <l_node>        logical_or_expression
190 %type   <l_node>        logical_xor_expression
191 %type   <l_node>        logical_and_expression
192 %type   <l_node>        inclusive_or_expression
193 %type   <l_node>        exclusive_or_expression
194 %type   <l_node>        and_expression
195 %type   <l_node>        equality_expression
196 %type   <l_node>        relational_expression
197 %type   <l_node>        shift_expression
198 %type   <l_node>        additive_expression
199 %type   <l_node>        multiplicative_expression
200 %type   <l_node>        cast_expression
201 %type   <l_node>        unary_expression
202 %type   <l_node>        postfix_expression
203 %type   <l_node>        primary_expression
204 %type   <l_node>        argument_expression_list
205
206 %type   <l_tok>         assignment_operator
207 %type   <l_tok>         unary_operator
208 %type   <l_tok>         struct_or_union
209
210 %type   <l_str>         dtrace_keyword_ident
211
212 %%
213
214 dtrace_program: d_expression DT_TOK_EOF { return (dt_node_root($1)); }
215         |       d_program DT_TOK_EOF { return (dt_node_root($1)); }
216         |       d_type DT_TOK_EOF { return (dt_node_root($1)); }
217         ;
218
219 d_expression:   DT_CTX_DEXPR { $$ = NULL; }
220         |       DT_CTX_DEXPR expression { $$ = $2; }
221         ;
222
223 d_program:      DT_CTX_DPROG { $$ = dt_node_program(NULL); }
224         |       DT_CTX_DPROG translation_unit { $$ = dt_node_program($2); }
225         ;
226
227 d_type:         DT_CTX_DTYPE { $$ = NULL; }
228         |       DT_CTX_DTYPE type_name { $$ = (dt_node_t *)$2; }
229         ;
230
231 translation_unit:
232                 external_declaration
233         |       translation_unit external_declaration { $$ = LINK($1, $2); }
234         ;
235
236 external_declaration:
237                 inline_definition
238         |       translator_definition
239         |       provider_definition
240         |       probe_definition
241         |       declaration
242         ;
243
244 inline_definition:
245                 DT_KEY_INLINE declaration_specifiers declarator
246                     { dt_scope_push(NULL, CTF_ERR); } DT_TOK_ASGN
247                     assignment_expression ';' {
248                         /*
249                          * We push a new declaration scope before shifting the
250                          * assignment_expression in order to preserve ds_class
251                          * and ds_ident for use in dt_node_inline().  Once the
252                          * entire inline_definition rule is matched, pop the
253                          * scope and construct the inline using the saved decl.
254                          */
255                         dt_scope_pop();
256                         $$ = dt_node_inline($6);
257                 }
258         ;
259
260 translator_definition:
261                 DT_KEY_XLATOR type_name DT_TOK_LT type_name
262                     DT_TOK_IDENT DT_TOK_GT '{' translator_member_list '}' ';' {
263                         $$ = dt_node_xlator($2, $4, $5, $8);
264                 }
265         |       DT_KEY_XLATOR type_name DT_TOK_LT type_name
266                     DT_TOK_IDENT DT_TOK_GT '{' '}' ';' {
267                         $$ = dt_node_xlator($2, $4, $5, NULL);
268                 }
269         ;
270
271 translator_member_list:
272                 translator_member
273         |       translator_member_list translator_member { $$ = LINK($1,$2); }
274         ;
275
276 translator_member:
277                 DT_TOK_IDENT DT_TOK_ASGN assignment_expression ';' {
278                         $$ = dt_node_member(NULL, $1, $3);
279                 }
280         ;
281
282 provider_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
291 provider_probe_list:
292                 provider_probe
293         |       provider_probe_list provider_probe { $$ = LINK($1, $2); }
294         ;
295
296 provider_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
306 probe_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
336 probe_specifiers:
337                 probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; }
338         ;
339
340 probe_specifier_list:
341                 probe_specifier
342         |       probe_specifier_list DT_TOK_COMMA probe_specifier {
343                         $$ = LINK($1, $3);
344                 }
345         ;
346
347 probe_specifier:
348                 DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); }
349         |       DT_TOK_INT   { $$ = dt_node_pdesc_by_id($1); }
350         ;
351
352 statement_list: statement { $$ = $1; }
353         |       statement_list ';' statement { $$ = LINK($1, $3); }
354         ;
355
356 statement:      /* empty */ { $$ = NULL; }
357         |       expression { $$ = dt_node_statement($1); }
358         ;
359
360 argument_expression_list:
361                 assignment_expression
362         |       argument_expression_list DT_TOK_COMMA assignment_expression {
363                         $$ = LINK($1, $3);
364                 }
365         ;
366
367 primary_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
377 postfix_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
432 unary_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
446 unary_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
454 cast_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
461 multiplicative_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
474 additive_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
484 shift_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
494 relational_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
510 equality_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
520 and_expression:
521                 equality_expression
522         |       and_expression DT_TOK_BAND equality_expression {
523                         $$ = OP2(DT_TOK_BAND, $1, $3);
524                 }
525         ;
526
527 exclusive_or_expression:
528                 and_expression
529         |       exclusive_or_expression DT_TOK_XOR and_expression {
530                         $$ = OP2(DT_TOK_XOR, $1, $3);
531                 }
532         ;
533
534 inclusive_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
541 logical_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
548 logical_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
555 logical_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
562 constant_expression: conditional_expression
563         ;
564
565 conditional_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
571 assignment_expression:
572                 conditional_expression
573         |       unary_expression assignment_operator assignment_expression {
574                         $$ = OP2($2, $1, $3);
575                 }
576         ;
577
578 assignment_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
592 expression:     assignment_expression
593         |       expression DT_TOK_COMMA assignment_expression {
594                         $$ = OP2(DT_TOK_COMMA, $1, $3);
595                 }
596         ;
597
598 declaration:    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
610 declaration_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
619 parameter_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
628 storage_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
636 d_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
642 type_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
660 type_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
665 struct_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
673 struct_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
679 struct_or_union:
680                 DT_KEY_STRUCT { $$ = CTF_K_STRUCT; }
681         |       DT_KEY_UNION { $$ = CTF_K_UNION; }
682         ;
683
684 struct_declaration_list:
685                 struct_declaration
686         |       struct_declaration_list struct_declaration
687         ;
688
689 init_declarator_list:
690                 init_declarator
691         |       init_declarator_list DT_TOK_COMMA init_declarator {
692                         $$ = LINK($1, $3);
693                 }
694         ;
695
696 init_declarator:
697                 declarator {
698                         $$ = dt_node_decl();
699                         dt_decl_reset();
700                 }
701         ;
702
703 struct_declaration:
704                 specifier_qualifier_list struct_declarator_list ';' {
705                         dt_decl_free(dt_decl_pop());
706                 }
707         ;
708
709 specifier_qualifier_list:
710                 type_specifier
711         |       type_specifier specifier_qualifier_list { $$ = $2; }
712         |       type_qualifier
713         |       type_qualifier specifier_qualifier_list { $$ = $2; }
714         ;
715
716 struct_declarator_list:
717                 struct_declarator
718         |       struct_declarator_list DT_TOK_COMMA struct_declarator
719         ;
720
721 struct_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
729 enum_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
735 enum_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
741 enumerator_list:
742                 enumerator
743         |       enumerator_list DT_TOK_COMMA enumerator
744         ;
745
746 enumerator:     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
752 declarator:     direct_declarator
753         |       pointer direct_declarator
754         ;
755
756 direct_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
763 lparen:         DT_TOK_LPAR { dt_decl_top()->dd_attr |= DT_DA_PAREN; }
764         ;
765
766 pointer:        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
772 type_qualifier_list:
773                 type_qualifier
774         |       type_qualifier_list type_qualifier { $$ = $2; }
775         ;
776
777 parameter_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
785 parameter_list: parameter_declaration
786         |       parameter_list DT_TOK_COMMA parameter_declaration {
787                         $$ = LINK($1, $3);
788                 }
789         ;
790
791 parameter_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
803 type_name:      specifier_qualifier_list {
804                         $$ = dt_decl_pop();
805                 }
806         |       specifier_qualifier_list abstract_declarator {
807                         $$ = dt_decl_pop();
808                 }
809         ;
810
811 abstract_declarator:
812                 pointer
813         |       direct_abstract_declarator
814         |       pointer direct_abstract_declarator
815         ;
816
817 direct_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
825 array:          DT_TOK_LBRAC { dt_scope_push(NULL, CTF_ERR); }
826                     array_parameters DT_TOK_RBRAC {
827                         dt_scope_pop();
828                         $$ = $3;
829                 }
830         ;
831
832 array_parameters:
833                 /* empty */             { $$ = NULL; }
834         |       constant_expression     { $$ = $1; }
835         |       parameter_type_list     { $$ = $1; }
836         ;
837
838 function:       DT_TOK_LPAR { dt_scope_push(NULL, CTF_ERR); }
839                     function_parameters DT_TOK_RPAR {
840                         dt_scope_pop();
841                         $$ = $3;
842                 }
843         ;
844
845 function_parameters:
846                 /* empty */             { $$ = NULL; }
847         |       parameter_type_list     { $$ = $1; }
848         ;
849
850 dtrace_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 %%