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