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