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 %%
 208 
 209 dtrace_program: d_expression DT_TOK_EOF { return (dt_node_root($1)); }
 210         |       d_program DT_TOK_EOF { return (dt_node_root($1)); }
 211         |       d_type DT_TOK_EOF { return (dt_node_root($1)); }
 212         ;
 213 
 214 d_expression:   DT_CTX_DEXPR { $$ = NULL; }
 215         |       DT_CTX_DEXPR expression { $$ = $2; }
 216         ;
 217 
 218 d_program:      DT_CTX_DPROG { $$ = dt_node_program(NULL); }
 219         |       DT_CTX_DPROG translation_unit { $$ = dt_node_program($2); }
 220         ;
 221 
 222 d_type:         DT_CTX_DTYPE { $$ = NULL; }
 223         |       DT_CTX_DTYPE type_name { $$ = (dt_node_t *)$2; }
 224         ;
 225 
 226 translation_unit:
 227                 external_declaration
 228         |       translation_unit external_declaration { $$ = LINK($1, $2); }
 229         ;
 230 
 231 external_declaration:
 232                 inline_definition
 233         |       translator_definition
 234         |       provider_definition
 235         |       probe_definition
 236         |       declaration
 237         ;
 238 
 239 inline_definition:
 240                 DT_KEY_INLINE declaration_specifiers declarator
 241                     { dt_scope_push(NULL, CTF_ERR); } DT_TOK_ASGN
 242                     assignment_expression ';' {
 243                         /*
 244                          * We push a new declaration scope before shifting the
 245                          * assignment_expression in order to preserve ds_class
 246                          * and ds_ident for use in dt_node_inline().  Once the
 247                          * entire inline_definition rule is matched, pop the
 248                          * scope and construct the inline using the saved decl.
 249                          */
 250                         dt_scope_pop();
 251                         $$ = dt_node_inline($6);
 252                 }
 253         ;
 254 
 255 translator_definition:
 256                 DT_KEY_XLATOR type_name DT_TOK_LT type_name
 257                     DT_TOK_IDENT DT_TOK_GT '{' translator_member_list '}' ';' {
 258                         $$ = dt_node_xlator($2, $4, $5, $8);
 259                 }
 260         |       DT_KEY_XLATOR type_name DT_TOK_LT type_name
 261                     DT_TOK_IDENT DT_TOK_GT '{' '}' ';' {
 262                         $$ = dt_node_xlator($2, $4, $5, NULL);
 263                 }
 264         ;
 265 
 266 translator_member_list:
 267                 translator_member
 268         |       translator_member_list translator_member { $$ = LINK($1,$2); }
 269         ;
 270 
 271 translator_member:
 272                 DT_TOK_IDENT DT_TOK_ASGN assignment_expression ';' {
 273                         $$ = dt_node_member(NULL, $1, $3);
 274                 }
 275         ;
 276 
 277 provider_definition:
 278                 DT_KEY_PROVIDER DT_TOK_IDENT '{' provider_probe_list '}' ';' {
 279                         $$ = dt_node_provider($2, $4);
 280                 }
 281         |       DT_KEY_PROVIDER DT_TOK_IDENT '{' '}' ';' {
 282                         $$ = dt_node_provider($2, NULL);
 283                 }
 284         ;
 285 
 286 provider_probe_list:
 287                 provider_probe
 288         |       provider_probe_list provider_probe { $$ = LINK($1, $2); }
 289         ;
 290 
 291 provider_probe:
 292                 DT_KEY_PROBE DT_TOK_IDENT function DT_TOK_COLON function ';' {
 293                         $$ = dt_node_probe($2, 2, $3, $5);
 294                 }
 295         |       DT_KEY_PROBE DT_TOK_IDENT function ';' {
 296                         $$ = dt_node_probe($2, 1, $3, NULL);
 297                 }
 298         ;
 299         
 300 
 301 probe_definition:
 302                 probe_specifiers {
 303                         /*
 304                          * If the input stream is a file, do not permit a probe
 305                          * specification without / <pred> / or { <act> } after
 306                          * it.  This can only occur if the next token is EOF or
 307                          * an ambiguous predicate was slurped up as a comment.
 308                          * We cannot perform this check if input() is a string
 309                          * because dtrace(1M) [-fmnP] also use the compiler and
 310                          * things like dtrace -n BEGIN have to be accepted.
 311                          */
 312                         if (yypcb->pcb_fileptr != NULL) {
 313                                 dnerror($1, D_SYNTAX, "expected predicate and/"
 314                                     "or actions following probe description\n");
 315                         }
 316                         $$ = dt_node_clause($1, NULL, NULL);
 317                 }
 318         |       probe_specifiers '{' statement_list '}' {
 319                         $$ = dt_node_clause($1, NULL, $3);
 320                 }
 321         |       probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED {
 322                         dnerror($3, D_SYNTAX, "expected actions { } following "
 323                             "probe description and predicate\n");
 324                 }
 325         |       probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED
 326                     '{' statement_list '}' {
 327                         $$ = dt_node_clause($1, $3, $6);
 328                 }
 329         ;
 330 
 331 probe_specifiers:
 332                 probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; }
 333         ;
 334 
 335 probe_specifier_list:
 336                 probe_specifier
 337         |       probe_specifier_list DT_TOK_COMMA probe_specifier {
 338                         $$ = LINK($1, $3);
 339                 }
 340         ;
 341 
 342 probe_specifier:
 343                 DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); }
 344         |       DT_TOK_INT   { $$ = dt_node_pdesc_by_id($1); }
 345         ;
 346 
 347 statement_list: statement { $$ = $1; }
 348         |       statement_list ';' statement { $$ = LINK($1, $3); }
 349         ;
 350 
 351 statement:      /* empty */ { $$ = NULL; }
 352         |       expression { $$ = dt_node_statement($1); }
 353         ;
 354 
 355 argument_expression_list:
 356                 assignment_expression
 357         |       argument_expression_list DT_TOK_COMMA assignment_expression {
 358                         $$ = LINK($1, $3);
 359                 }
 360         ;
 361 
 362 primary_expression:
 363                 DT_TOK_IDENT { $$ = dt_node_ident($1); }
 364         |       DT_TOK_AGG { $$ = dt_node_ident($1); }
 365         |       DT_TOK_INT { $$ = dt_node_int($1); }
 366         |       DT_TOK_STRING { $$ = dt_node_string($1); }
 367         |       DT_KEY_SELF { $$ = dt_node_ident(DUP("self")); }
 368         |       DT_KEY_THIS { $$ = dt_node_ident(DUP("this")); }
 369         |       DT_TOK_LPAR expression DT_TOK_RPAR { $$ = $2; }
 370         ;
 371 
 372 postfix_expression:
 373                 primary_expression
 374         |       postfix_expression
 375                     DT_TOK_LBRAC argument_expression_list DT_TOK_RBRAC {
 376                         $$ = OP2(DT_TOK_LBRAC, $1, $3);
 377                 }
 378         |       postfix_expression DT_TOK_LPAR DT_TOK_RPAR {
 379                         $$ = dt_node_func($1, NULL);
 380                 }
 381         |       postfix_expression
 382                     DT_TOK_LPAR argument_expression_list DT_TOK_RPAR {
 383                         $$ = dt_node_func($1, $3);
 384                 }
 385         |       postfix_expression DT_TOK_DOT DT_TOK_IDENT {
 386                         $$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
 387                 }
 388         |       postfix_expression DT_TOK_DOT DT_TOK_TNAME {
 389                         $$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3));
 390                 }
 391         |       postfix_expression DT_TOK_PTR DT_TOK_IDENT {
 392                         $$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
 393                 }
 394         |       postfix_expression DT_TOK_PTR DT_TOK_TNAME {
 395                         $$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3));
 396                 }
 397         |       postfix_expression DT_TOK_ADDADD {
 398                         $$ = OP1(DT_TOK_POSTINC, $1);
 399                 }
 400         |       postfix_expression DT_TOK_SUBSUB {
 401                         $$ = OP1(DT_TOK_POSTDEC, $1);
 402                 }
 403         |       DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA 
 404                     DT_TOK_IDENT DT_TOK_RPAR {
 405                         $$ = dt_node_offsetof($3, $5);
 406                 }
 407         |       DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA 
 408                     DT_TOK_TNAME DT_TOK_RPAR {
 409                         $$ = dt_node_offsetof($3, $5);
 410                 }
 411         |       DT_TOK_XLATE DT_TOK_LT type_name DT_TOK_GT
 412                     DT_TOK_LPAR expression DT_TOK_RPAR {
 413                         $$ = OP2(DT_TOK_XLATE, dt_node_type($3), $6);
 414                 }
 415         ;
 416 
 417 unary_expression:
 418                 postfix_expression
 419         |       DT_TOK_ADDADD unary_expression { $$ = OP1(DT_TOK_PREINC, $2); }
 420         |       DT_TOK_SUBSUB unary_expression { $$ = OP1(DT_TOK_PREDEC, $2); }
 421         |       unary_operator cast_expression { $$ = OP1($1, $2); }
 422         |       DT_TOK_SIZEOF unary_expression { $$ = OP1(DT_TOK_SIZEOF, $2); }
 423         |       DT_TOK_SIZEOF DT_TOK_LPAR type_name DT_TOK_RPAR {
 424                         $$ = OP1(DT_TOK_SIZEOF, dt_node_type($3));
 425                 }
 426         |       DT_TOK_STRINGOF unary_expression {
 427                         $$ = OP1(DT_TOK_STRINGOF, $2);
 428                 }
 429         ;
 430 
 431 unary_operator: DT_TOK_BAND { $$ = DT_TOK_ADDROF; }
 432         |       DT_TOK_MUL { $$ = DT_TOK_DEREF; }
 433         |       DT_TOK_ADD { $$ = DT_TOK_IPOS; }
 434         |       DT_TOK_SUB { $$ = DT_TOK_INEG; }
 435         |       DT_TOK_BNEG { $$ = DT_TOK_BNEG; }
 436         |       DT_TOK_LNEG { $$ = DT_TOK_LNEG; }
 437         ;
 438 
 439 cast_expression:
 440                 unary_expression
 441         |       DT_TOK_LPAR type_name DT_TOK_RPAR cast_expression {
 442                         $$ = OP2(DT_TOK_LPAR, dt_node_type($2), $4);
 443                 }
 444         ;
 445 
 446 multiplicative_expression:
 447                 cast_expression
 448         |       multiplicative_expression DT_TOK_MUL cast_expression {
 449                         $$ = OP2(DT_TOK_MUL, $1, $3);
 450                 }
 451         |       multiplicative_expression DT_TOK_DIV cast_expression {
 452                         $$ = OP2(DT_TOK_DIV, $1, $3);
 453                 }
 454         |       multiplicative_expression DT_TOK_MOD cast_expression {
 455                         $$ = OP2(DT_TOK_MOD, $1, $3);
 456                 }
 457         ;
 458 
 459 additive_expression:
 460                 multiplicative_expression
 461         |       additive_expression DT_TOK_ADD multiplicative_expression {
 462                         $$ = OP2(DT_TOK_ADD, $1, $3);
 463                 }
 464         |       additive_expression DT_TOK_SUB multiplicative_expression {
 465                         $$ = OP2(DT_TOK_SUB, $1, $3);
 466                 }
 467         ;
 468 
 469 shift_expression:
 470                 additive_expression
 471         |       shift_expression DT_TOK_LSH additive_expression {
 472                         $$ = OP2(DT_TOK_LSH, $1, $3);
 473                 }
 474         |       shift_expression DT_TOK_RSH additive_expression {
 475                         $$ = OP2(DT_TOK_RSH, $1, $3);
 476                 }
 477         ;
 478 
 479 relational_expression:
 480                 shift_expression
 481         |       relational_expression DT_TOK_LT shift_expression {
 482                         $$ = OP2(DT_TOK_LT, $1, $3);
 483                 }
 484         |       relational_expression DT_TOK_GT shift_expression {
 485                         $$ = OP2(DT_TOK_GT, $1, $3);
 486                 }
 487         |       relational_expression DT_TOK_LE shift_expression {
 488                         $$ = OP2(DT_TOK_LE, $1, $3);
 489                 }
 490         |       relational_expression DT_TOK_GE shift_expression {
 491                         $$ = OP2(DT_TOK_GE, $1, $3);
 492                 }
 493         ;
 494 
 495 equality_expression:
 496                 relational_expression
 497         |       equality_expression DT_TOK_EQU relational_expression {
 498                         $$ = OP2(DT_TOK_EQU, $1, $3);
 499                 }
 500         |       equality_expression DT_TOK_NEQ relational_expression {
 501                         $$ = OP2(DT_TOK_NEQ, $1, $3);
 502                 }
 503         ;
 504 
 505 and_expression:
 506                 equality_expression
 507         |       and_expression DT_TOK_BAND equality_expression {
 508                         $$ = OP2(DT_TOK_BAND, $1, $3);
 509                 }
 510         ;
 511 
 512 exclusive_or_expression:
 513                 and_expression
 514         |       exclusive_or_expression DT_TOK_XOR and_expression {
 515                         $$ = OP2(DT_TOK_XOR, $1, $3);
 516                 }
 517         ;
 518 
 519 inclusive_or_expression:
 520                 exclusive_or_expression
 521         |       inclusive_or_expression DT_TOK_BOR exclusive_or_expression {
 522                         $$ = OP2(DT_TOK_BOR, $1, $3);
 523                 }
 524         ;
 525 
 526 logical_and_expression:
 527                 inclusive_or_expression
 528         |       logical_and_expression DT_TOK_LAND inclusive_or_expression {
 529                         $$ = OP2(DT_TOK_LAND, $1, $3);
 530                 }
 531         ;
 532 
 533 logical_xor_expression:
 534                 logical_and_expression
 535         |       logical_xor_expression DT_TOK_LXOR logical_and_expression {
 536                         $$ = OP2(DT_TOK_LXOR, $1, $3);
 537                 }
 538         ;
 539 
 540 logical_or_expression:
 541                 logical_xor_expression
 542         |       logical_or_expression DT_TOK_LOR logical_xor_expression {
 543                         $$ = OP2(DT_TOK_LOR, $1, $3);
 544                 }
 545         ;
 546 
 547 constant_expression: conditional_expression
 548         ;
 549 
 550 conditional_expression:
 551                 logical_or_expression
 552         |       logical_or_expression DT_TOK_QUESTION expression DT_TOK_COLON
 553                     conditional_expression { $$ = OP3($1, $3, $5); }
 554         ;
 555 
 556 assignment_expression:
 557                 conditional_expression
 558         |       unary_expression assignment_operator assignment_expression {
 559                         $$ = OP2($2, $1, $3);
 560                 }
 561         ;
 562 
 563 assignment_operator:
 564                 DT_TOK_ASGN   { $$ = DT_TOK_ASGN; }
 565         |       DT_TOK_MUL_EQ { $$ = DT_TOK_MUL_EQ; }
 566         |       DT_TOK_DIV_EQ { $$ = DT_TOK_DIV_EQ; }
 567         |       DT_TOK_MOD_EQ { $$ = DT_TOK_MOD_EQ; }
 568         |       DT_TOK_ADD_EQ { $$ = DT_TOK_ADD_EQ; }
 569         |       DT_TOK_SUB_EQ { $$ = DT_TOK_SUB_EQ; }
 570         |       DT_TOK_LSH_EQ { $$ = DT_TOK_LSH_EQ; }
 571         |       DT_TOK_RSH_EQ { $$ = DT_TOK_RSH_EQ; }
 572         |       DT_TOK_AND_EQ { $$ = DT_TOK_AND_EQ; }
 573         |       DT_TOK_XOR_EQ { $$ = DT_TOK_XOR_EQ; }
 574         |       DT_TOK_OR_EQ  { $$ = DT_TOK_OR_EQ; }
 575         ;
 576 
 577 expression:     assignment_expression
 578         |       expression DT_TOK_COMMA assignment_expression {
 579                         $$ = OP2(DT_TOK_COMMA, $1, $3);
 580                 }
 581         ;
 582 
 583 declaration:    declaration_specifiers ';' {
 584                         $$ = dt_node_decl();
 585                         dt_decl_free(dt_decl_pop());
 586                         yybegin(YYS_CLAUSE);
 587                 }
 588         |       declaration_specifiers init_declarator_list ';' {
 589                         $$ = $2;
 590                         dt_decl_free(dt_decl_pop());
 591                         yybegin(YYS_CLAUSE);
 592                 }
 593         ;
 594 
 595 declaration_specifiers:
 596                 d_storage_class_specifier
 597         |       d_storage_class_specifier declaration_specifiers
 598         |       type_specifier
 599         |       type_specifier declaration_specifiers
 600         |       type_qualifier
 601         |       type_qualifier declaration_specifiers
 602         ;
 603 
 604 parameter_declaration_specifiers:
 605                 storage_class_specifier
 606         |       storage_class_specifier declaration_specifiers
 607         |       type_specifier
 608         |       type_specifier declaration_specifiers
 609         |       type_qualifier
 610         |       type_qualifier declaration_specifiers
 611         ;
 612 
 613 storage_class_specifier:
 614                 DT_KEY_AUTO { dt_decl_class(DT_DC_AUTO); }
 615         |       DT_KEY_REGISTER { dt_decl_class(DT_DC_REGISTER); }
 616         |       DT_KEY_STATIC { dt_decl_class(DT_DC_STATIC); }
 617         |       DT_KEY_EXTERN { dt_decl_class(DT_DC_EXTERN); }
 618         |       DT_KEY_TYPEDEF { dt_decl_class(DT_DC_TYPEDEF); }
 619         ;
 620 
 621 d_storage_class_specifier:
 622                 storage_class_specifier
 623         |       DT_KEY_SELF { dt_decl_class(DT_DC_SELF); }
 624         |       DT_KEY_THIS { dt_decl_class(DT_DC_THIS); }
 625         ;
 626 
 627 type_specifier: DT_KEY_VOID { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("void")); }
 628         |       DT_KEY_CHAR { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("char")); }
 629         |       DT_KEY_SHORT { $$ = dt_decl_attr(DT_DA_SHORT); }
 630         |       DT_KEY_INT { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("int")); }
 631         |       DT_KEY_LONG { $$ = dt_decl_attr(DT_DA_LONG); }
 632         |       DT_KEY_FLOAT { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("float")); }
 633         |       DT_KEY_DOUBLE { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("double")); }
 634         |       DT_KEY_SIGNED { $$ = dt_decl_attr(DT_DA_SIGNED); }
 635         |       DT_KEY_UNSIGNED { $$ = dt_decl_attr(DT_DA_UNSIGNED); }
 636         |       DT_KEY_STRING {
 637                         $$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string"));
 638                 }
 639         |       DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_TYPEDEF, $1); }
 640         |       struct_or_union_specifier
 641         |       enum_specifier
 642         ;
 643 
 644 type_qualifier: DT_KEY_CONST { $$ = dt_decl_attr(DT_DA_CONST); }
 645         |       DT_KEY_RESTRICT { $$ = dt_decl_attr(DT_DA_RESTRICT); }
 646         |       DT_KEY_VOLATILE { $$ = dt_decl_attr(DT_DA_VOLATILE); }
 647         ;
 648 
 649 struct_or_union_specifier:
 650                 struct_or_union_definition struct_declaration_list '}' {
 651                         $$ = dt_scope_pop();
 652                 }
 653         |       struct_or_union DT_TOK_IDENT { $$ = dt_decl_spec($1, $2); }
 654         |       struct_or_union DT_TOK_TNAME { $$ = dt_decl_spec($1, $2); }
 655         ;
 656 
 657 struct_or_union_definition:
 658                 struct_or_union '{' { dt_decl_sou($1, NULL); }
 659         |       struct_or_union DT_TOK_IDENT '{' { dt_decl_sou($1, $2); }
 660         |       struct_or_union DT_TOK_TNAME '{' { dt_decl_sou($1, $2); }
 661         ;
 662 
 663 struct_or_union:
 664                 DT_KEY_STRUCT { $$ = CTF_K_STRUCT; }
 665         |       DT_KEY_UNION { $$ = CTF_K_UNION; }
 666         ;
 667 
 668 struct_declaration_list:
 669                 struct_declaration
 670         |       struct_declaration_list struct_declaration
 671         ;
 672 
 673 init_declarator_list:
 674                 init_declarator
 675         |       init_declarator_list DT_TOK_COMMA init_declarator {
 676                         $$ = LINK($1, $3);
 677                 }
 678         ;
 679 
 680 init_declarator:
 681                 declarator {
 682                         $$ = dt_node_decl();
 683                         dt_decl_reset();
 684                 }
 685         ;
 686 
 687 struct_declaration:
 688                 specifier_qualifier_list struct_declarator_list ';' {
 689                         dt_decl_free(dt_decl_pop());
 690                 }
 691         ;
 692 
 693 specifier_qualifier_list:
 694                 type_specifier
 695         |       type_specifier specifier_qualifier_list { $$ = $2; }
 696         |       type_qualifier
 697         |       type_qualifier specifier_qualifier_list { $$ = $2; }
 698         ;
 699 
 700 struct_declarator_list:
 701                 struct_declarator
 702         |       struct_declarator_list DT_TOK_COMMA struct_declarator
 703         ;
 704 
 705 struct_declarator:
 706                 declarator { dt_decl_member(NULL); }
 707         |       DT_TOK_COLON constant_expression { dt_decl_member($2); }
 708         |       declarator DT_TOK_COLON constant_expression {
 709                         dt_decl_member($3);
 710                 }
 711         ;
 712 
 713 enum_specifier:
 714                 enum_definition enumerator_list '}' { $$ = dt_scope_pop(); }
 715         |       DT_KEY_ENUM DT_TOK_IDENT { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
 716         |       DT_KEY_ENUM DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_ENUM, $2); }
 717         ;
 718 
 719 enum_definition:
 720                 DT_KEY_ENUM '{' { dt_decl_enum(NULL); }
 721         |       DT_KEY_ENUM DT_TOK_IDENT '{' { dt_decl_enum($2); }
 722         |       DT_KEY_ENUM DT_TOK_TNAME '{' { dt_decl_enum($2); }
 723         ;
 724 
 725 enumerator_list:
 726                 enumerator
 727         |       enumerator_list DT_TOK_COMMA enumerator
 728         ;
 729 
 730 enumerator:     DT_TOK_IDENT { dt_decl_enumerator($1, NULL); }
 731         |       DT_TOK_IDENT DT_TOK_ASGN expression {
 732                         dt_decl_enumerator($1, $3);
 733                 }
 734         ;
 735 
 736 declarator:     direct_declarator
 737         |       pointer direct_declarator
 738         ;
 739 
 740 direct_declarator:
 741                 DT_TOK_IDENT { $$ = dt_decl_ident($1); }
 742         |       lparen declarator DT_TOK_RPAR { $$ = $2; }
 743         |       direct_declarator array { dt_decl_array($2); }
 744         |       direct_declarator function { dt_decl_func($1, $2); }
 745         ;
 746 
 747 lparen:         DT_TOK_LPAR { dt_decl_top()->dd_attr |= DT_DA_PAREN; }
 748         ;
 749 
 750 pointer:        DT_TOK_MUL { $$ = dt_decl_ptr(); }
 751         |       DT_TOK_MUL type_qualifier_list { $$ = dt_decl_ptr(); }
 752         |       DT_TOK_MUL pointer { $$ = dt_decl_ptr(); }
 753         |       DT_TOK_MUL type_qualifier_list pointer { $$ = dt_decl_ptr(); }
 754         ;
 755 
 756 type_qualifier_list:
 757                 type_qualifier
 758         |       type_qualifier_list type_qualifier { $$ = $2; }
 759         ;
 760 
 761 parameter_type_list:
 762                 parameter_list
 763         |       DT_TOK_ELLIPSIS { $$ = dt_node_vatype(); }
 764         |       parameter_list DT_TOK_COMMA DT_TOK_ELLIPSIS {
 765                         $$ = LINK($1, dt_node_vatype());
 766                 }
 767         ;
 768 
 769 parameter_list: parameter_declaration
 770         |       parameter_list DT_TOK_COMMA parameter_declaration {
 771                         $$ = LINK($1, $3);
 772                 }
 773         ;
 774 
 775 parameter_declaration:
 776                 parameter_declaration_specifiers {
 777                         $$ = dt_node_type(NULL);
 778                 }
 779         |       parameter_declaration_specifiers declarator {
 780                         $$ = dt_node_type(NULL);
 781                 }
 782         |       parameter_declaration_specifiers abstract_declarator {
 783                         $$ = dt_node_type(NULL);
 784                 }
 785         ;
 786 
 787 type_name:      specifier_qualifier_list {
 788                         $$ = dt_decl_pop();
 789                 }
 790         |       specifier_qualifier_list abstract_declarator {
 791                         $$ = dt_decl_pop();
 792                 }
 793         ;
 794 
 795 abstract_declarator:
 796                 pointer
 797         |       direct_abstract_declarator
 798         |       pointer direct_abstract_declarator
 799         ;
 800 
 801 direct_abstract_declarator:
 802                 lparen abstract_declarator DT_TOK_RPAR { $$ = $2; }
 803         |       direct_abstract_declarator array { dt_decl_array($2); }
 804         |       array { dt_decl_array($1); $$ = NULL; }
 805         |       direct_abstract_declarator function { dt_decl_func($1, $2); }
 806         |       function { dt_decl_func(NULL, $1); }
 807         ;
 808 
 809 array:          DT_TOK_LBRAC { dt_scope_push(NULL, CTF_ERR); }
 810                     array_parameters DT_TOK_RBRAC {
 811                         dt_scope_pop();
 812                         $$ = $3;
 813                 }
 814         ;
 815 
 816 array_parameters:
 817                 /* empty */             { $$ = NULL; }
 818         |       constant_expression     { $$ = $1; }
 819         |       parameter_type_list     { $$ = $1; }
 820         ;
 821 
 822 function:       DT_TOK_LPAR { dt_scope_push(NULL, CTF_ERR); }
 823                     function_parameters DT_TOK_RPAR {
 824                         dt_scope_pop();
 825                         $$ = $3;
 826                 }
 827         ;
 828 
 829 function_parameters:
 830                 /* empty */             { $$ = NULL; }
 831         |       parameter_type_list     { $$ = $1; }
 832         ;
 833 
 834 %%