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, 2016 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 probe_definition: 307 probe_specifiers { 308 /* 309 * If the input stream is a file, do not permit a probe 310 * specification without / <pred> / or { <act> } after 311 * it. This can only occur if the next token is EOF or 312 * an ambiguous predicate was slurped up as a comment. 313 * We cannot perform this check if input() is a string 314 * because dtrace(8) [-fmnP] also use the compiler and 315 * things like dtrace -n BEGIN have to be accepted. 316 */ 317 if (yypcb->pcb_fileptr != NULL) { 318 dnerror($1, D_SYNTAX, "expected predicate and/" 319 "or actions following probe description\n"); 320 } 321 $$ = dt_node_clause($1, NULL, NULL); 322 yybegin(YYS_CLAUSE); 323 } 324 | probe_specifiers '{' statement_list '}' { 325 $$ = dt_node_clause($1, NULL, $3); 326 yybegin(YYS_CLAUSE); 327 } 328 | probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED { 329 dnerror($3, D_SYNTAX, "expected actions { } following " 330 "probe description and predicate\n"); 331 } 332 | probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED 333 '{' statement_list '}' { 334 $$ = dt_node_clause($1, $3, $6); 335 yybegin(YYS_CLAUSE); 336 } 337 ; 338 339 probe_specifiers: 340 probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; } 341 ; 342 343 probe_specifier_list: 344 probe_specifier 345 | probe_specifier_list DT_TOK_COMMA probe_specifier { 346 $$ = LINK($1, $3); 347 } 348 ; 349 350 probe_specifier: 351 DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); } 352 | DT_TOK_INT { $$ = dt_node_pdesc_by_id($1); } 353 ; 354 355 statement_list_impl: /* empty */ { $$ = NULL; } 356 | statement_list_impl statement { $$ = LINK($1, $2); } 357 ; 358 359 statement_list: 360 statement_list_impl { $$ = $1; } 361 | statement_list_impl expression { 362 $$ = LINK($1, dt_node_statement($2)); 363 } 364 ; 365 366 statement_or_block: 367 statement 368 | '{' statement_list '}' { $$ = $2; } 369 370 statement: ';' { $$ = NULL; } 371 | expression ';' { $$ = dt_node_statement($1); } 372 | DT_KEY_IF DT_TOK_LPAR expression DT_TOK_RPAR statement_or_block { 373 $$ = dt_node_if($3, $5, NULL); 374 } 375 | DT_KEY_IF DT_TOK_LPAR expression DT_TOK_RPAR 376 statement_or_block DT_KEY_ELSE statement_or_block { 377 $$ = dt_node_if($3, $5, $7); 378 } 379 ; 380 381 argument_expression_list: 382 assignment_expression 383 | argument_expression_list DT_TOK_COMMA assignment_expression { 384 $$ = LINK($1, $3); 385 } 386 ; 387 388 primary_expression: 389 DT_TOK_IDENT { $$ = dt_node_ident($1); } 390 | DT_TOK_AGG { $$ = dt_node_ident($1); } 391 | DT_TOK_INT { $$ = dt_node_int($1); } 392 | DT_TOK_STRING { $$ = dt_node_string($1); } 393 | DT_KEY_SELF { $$ = dt_node_ident(DUP("self")); } 394 | DT_KEY_THIS { $$ = dt_node_ident(DUP("this")); } 395 | DT_TOK_LPAR expression DT_TOK_RPAR { $$ = $2; } 396 ; 397 398 postfix_expression: 399 primary_expression 400 | postfix_expression 401 DT_TOK_LBRAC argument_expression_list DT_TOK_RBRAC { 402 $$ = OP2(DT_TOK_LBRAC, $1, $3); 403 } 404 | postfix_expression DT_TOK_LPAR DT_TOK_RPAR { 405 $$ = dt_node_func($1, NULL); 406 } 407 | postfix_expression 408 DT_TOK_LPAR argument_expression_list DT_TOK_RPAR { 409 $$ = dt_node_func($1, $3); 410 } 411 | postfix_expression DT_TOK_DOT DT_TOK_IDENT { 412 $$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3)); 413 } 414 | postfix_expression DT_TOK_DOT DT_TOK_TNAME { 415 $$ = OP2(DT_TOK_DOT, $1, dt_node_ident($3)); 416 } 417 | postfix_expression DT_TOK_PTR DT_TOK_IDENT { 418 $$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3)); 419 } 420 | postfix_expression DT_TOK_PTR DT_TOK_TNAME { 421 $$ = OP2(DT_TOK_PTR, $1, dt_node_ident($3)); 422 } 423 | postfix_expression DT_TOK_ADDADD { 424 $$ = OP1(DT_TOK_POSTINC, $1); 425 } 426 | postfix_expression DT_TOK_SUBSUB { 427 $$ = OP1(DT_TOK_POSTDEC, $1); 428 } 429 | DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA 430 DT_TOK_IDENT DT_TOK_RPAR { 431 $$ = dt_node_offsetof($3, $5); 432 } 433 | DT_TOK_OFFSETOF DT_TOK_LPAR type_name DT_TOK_COMMA 434 DT_TOK_TNAME DT_TOK_RPAR { 435 $$ = dt_node_offsetof($3, $5); 436 } 437 | DT_TOK_XLATE DT_TOK_LT type_name DT_TOK_GT 438 DT_TOK_LPAR expression DT_TOK_RPAR { 439 $$ = OP2(DT_TOK_XLATE, dt_node_type($3), $6); 440 } 441 ; 442 443 unary_expression: 444 postfix_expression 445 | DT_TOK_ADDADD unary_expression { $$ = OP1(DT_TOK_PREINC, $2); } 446 | DT_TOK_SUBSUB unary_expression { $$ = OP1(DT_TOK_PREDEC, $2); } 447 | unary_operator cast_expression { $$ = OP1($1, $2); } 448 | DT_TOK_SIZEOF unary_expression { $$ = OP1(DT_TOK_SIZEOF, $2); } 449 | DT_TOK_SIZEOF DT_TOK_LPAR type_name DT_TOK_RPAR { 450 $$ = OP1(DT_TOK_SIZEOF, dt_node_type($3)); 451 } 452 | DT_TOK_STRINGOF unary_expression { 453 $$ = OP1(DT_TOK_STRINGOF, $2); 454 } 455 ; 456 457 unary_operator: DT_TOK_BAND { $$ = DT_TOK_ADDROF; } 458 | DT_TOK_MUL { $$ = DT_TOK_DEREF; } 459 | DT_TOK_ADD { $$ = DT_TOK_IPOS; } 460 | DT_TOK_SUB { $$ = DT_TOK_INEG; } 461 | DT_TOK_BNEG { $$ = DT_TOK_BNEG; } 462 | DT_TOK_LNEG { $$ = DT_TOK_LNEG; } 463 ; 464 465 cast_expression: 466 unary_expression 467 | DT_TOK_LPAR type_name DT_TOK_RPAR cast_expression { 468 $$ = OP2(DT_TOK_LPAR, dt_node_type($2), $4); 469 } 470 ; 471 472 multiplicative_expression: 473 cast_expression 474 | multiplicative_expression DT_TOK_MUL cast_expression { 475 $$ = OP2(DT_TOK_MUL, $1, $3); 476 } 477 | multiplicative_expression DT_TOK_DIV cast_expression { 478 $$ = OP2(DT_TOK_DIV, $1, $3); 479 } 480 | multiplicative_expression DT_TOK_MOD cast_expression { 481 $$ = OP2(DT_TOK_MOD, $1, $3); 482 } 483 ; 484 485 additive_expression: 486 multiplicative_expression 487 | additive_expression DT_TOK_ADD multiplicative_expression { 488 $$ = OP2(DT_TOK_ADD, $1, $3); 489 } 490 | additive_expression DT_TOK_SUB multiplicative_expression { 491 $$ = OP2(DT_TOK_SUB, $1, $3); 492 } 493 ; 494 495 shift_expression: 496 additive_expression 497 | shift_expression DT_TOK_LSH additive_expression { 498 $$ = OP2(DT_TOK_LSH, $1, $3); 499 } 500 | shift_expression DT_TOK_RSH additive_expression { 501 $$ = OP2(DT_TOK_RSH, $1, $3); 502 } 503 ; 504 505 relational_expression: 506 shift_expression 507 | relational_expression DT_TOK_LT shift_expression { 508 $$ = OP2(DT_TOK_LT, $1, $3); 509 } 510 | relational_expression DT_TOK_GT shift_expression { 511 $$ = OP2(DT_TOK_GT, $1, $3); 512 } 513 | relational_expression DT_TOK_LE shift_expression { 514 $$ = OP2(DT_TOK_LE, $1, $3); 515 } 516 | relational_expression DT_TOK_GE shift_expression { 517 $$ = OP2(DT_TOK_GE, $1, $3); 518 } 519 ; 520 521 equality_expression: 522 relational_expression 523 | equality_expression DT_TOK_EQU relational_expression { 524 $$ = OP2(DT_TOK_EQU, $1, $3); 525 } 526 | equality_expression DT_TOK_NEQ relational_expression { 527 $$ = OP2(DT_TOK_NEQ, $1, $3); 528 } 529 ; 530 531 and_expression: 532 equality_expression 533 | and_expression DT_TOK_BAND equality_expression { 534 $$ = OP2(DT_TOK_BAND, $1, $3); 535 } 536 ; 537 538 exclusive_or_expression: 539 and_expression 540 | exclusive_or_expression DT_TOK_XOR and_expression { 541 $$ = OP2(DT_TOK_XOR, $1, $3); 542 } 543 ; 544 545 inclusive_or_expression: 546 exclusive_or_expression 547 | inclusive_or_expression DT_TOK_BOR exclusive_or_expression { 548 $$ = OP2(DT_TOK_BOR, $1, $3); 549 } 550 ; 551 552 logical_and_expression: 553 inclusive_or_expression 554 | logical_and_expression DT_TOK_LAND inclusive_or_expression { 555 $$ = OP2(DT_TOK_LAND, $1, $3); 556 } 557 ; 558 559 logical_xor_expression: 560 logical_and_expression 561 | logical_xor_expression DT_TOK_LXOR logical_and_expression { 562 $$ = OP2(DT_TOK_LXOR, $1, $3); 563 } 564 ; 565 566 logical_or_expression: 567 logical_xor_expression 568 | logical_or_expression DT_TOK_LOR logical_xor_expression { 569 $$ = OP2(DT_TOK_LOR, $1, $3); 570 } 571 ; 572 573 constant_expression: conditional_expression 574 ; 575 576 conditional_expression: 577 logical_or_expression 578 | logical_or_expression DT_TOK_QUESTION expression DT_TOK_COLON 579 conditional_expression { $$ = OP3($1, $3, $5); } 580 ; 581 582 assignment_expression: 583 conditional_expression 584 | unary_expression assignment_operator assignment_expression { 585 $$ = OP2($2, $1, $3); 586 } 587 ; 588 589 assignment_operator: 590 DT_TOK_ASGN { $$ = DT_TOK_ASGN; } 591 | DT_TOK_MUL_EQ { $$ = DT_TOK_MUL_EQ; } 592 | DT_TOK_DIV_EQ { $$ = DT_TOK_DIV_EQ; } 593 | DT_TOK_MOD_EQ { $$ = DT_TOK_MOD_EQ; } 594 | DT_TOK_ADD_EQ { $$ = DT_TOK_ADD_EQ; } 595 | DT_TOK_SUB_EQ { $$ = DT_TOK_SUB_EQ; } 596 | DT_TOK_LSH_EQ { $$ = DT_TOK_LSH_EQ; } 597 | DT_TOK_RSH_EQ { $$ = DT_TOK_RSH_EQ; } 598 | DT_TOK_AND_EQ { $$ = DT_TOK_AND_EQ; } 599 | DT_TOK_XOR_EQ { $$ = DT_TOK_XOR_EQ; } 600 | DT_TOK_OR_EQ { $$ = DT_TOK_OR_EQ; } 601 ; 602 603 expression: assignment_expression 604 | expression DT_TOK_COMMA assignment_expression { 605 $$ = OP2(DT_TOK_COMMA, $1, $3); 606 } 607 ; 608 609 declaration: declaration_specifiers ';' { 610 $$ = dt_node_decl(); 611 dt_decl_free(dt_decl_pop()); 612 yybegin(YYS_CLAUSE); 613 } 614 | declaration_specifiers init_declarator_list ';' { 615 $$ = $2; 616 dt_decl_free(dt_decl_pop()); 617 yybegin(YYS_CLAUSE); 618 } 619 ; 620 621 declaration_specifiers: 622 d_storage_class_specifier 623 | d_storage_class_specifier declaration_specifiers 624 | type_specifier 625 | type_specifier declaration_specifiers 626 | type_qualifier 627 | type_qualifier declaration_specifiers 628 ; 629 630 parameter_declaration_specifiers: 631 storage_class_specifier 632 | storage_class_specifier declaration_specifiers 633 | type_specifier 634 | type_specifier declaration_specifiers 635 | type_qualifier 636 | type_qualifier declaration_specifiers 637 ; 638 639 storage_class_specifier: 640 DT_KEY_AUTO { dt_decl_class(DT_DC_AUTO); } 641 | DT_KEY_REGISTER { dt_decl_class(DT_DC_REGISTER); } 642 | DT_KEY_STATIC { dt_decl_class(DT_DC_STATIC); } 643 | DT_KEY_EXTERN { dt_decl_class(DT_DC_EXTERN); } 644 | DT_KEY_TYPEDEF { dt_decl_class(DT_DC_TYPEDEF); } 645 ; 646 647 d_storage_class_specifier: 648 storage_class_specifier 649 | DT_KEY_SELF { dt_decl_class(DT_DC_SELF); } 650 | DT_KEY_THIS { dt_decl_class(DT_DC_THIS); } 651 ; 652 653 type_specifier: DT_KEY_VOID { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("void")); } 654 | DT_KEY_CHAR { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("char")); } 655 | DT_KEY_SHORT { $$ = dt_decl_attr(DT_DA_SHORT); } 656 | DT_KEY_INT { $$ = dt_decl_spec(CTF_K_INTEGER, DUP("int")); } 657 | DT_KEY_LONG { $$ = dt_decl_attr(DT_DA_LONG); } 658 | DT_KEY_FLOAT { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("float")); } 659 | DT_KEY_DOUBLE { $$ = dt_decl_spec(CTF_K_FLOAT, DUP("double")); } 660 | DT_KEY_SIGNED { $$ = dt_decl_attr(DT_DA_SIGNED); } 661 | DT_KEY_UNSIGNED { $$ = dt_decl_attr(DT_DA_UNSIGNED); } 662 | DT_KEY_USERLAND { $$ = dt_decl_attr(DT_DA_USER); } 663 | DT_KEY_STRING { 664 $$ = dt_decl_spec(CTF_K_TYPEDEF, DUP("string")); 665 } 666 | DT_TOK_TNAME { $$ = dt_decl_spec(CTF_K_TYPEDEF, $1); } 667 | struct_or_union_specifier 668 | enum_specifier 669 ; 670 671 type_qualifier: DT_KEY_CONST { $$ = dt_decl_attr(DT_DA_CONST); } 672 | DT_KEY_RESTRICT { $$ = dt_decl_attr(DT_DA_RESTRICT); } 673 | DT_KEY_VOLATILE { $$ = dt_decl_attr(DT_DA_VOLATILE); } 674 ; 675 676 struct_or_union_specifier: 677 struct_or_union_definition struct_declaration_list '}' { 678 $$ = dt_scope_pop(); 679 } 680 | struct_or_union DT_TOK_IDENT { $$ = dt_decl_spec($1, $2); } 681 | struct_or_union DT_TOK_TNAME { $$ = dt_decl_spec($1, $2); } 682 ; 683 684 struct_or_union_definition: 685 struct_or_union '{' { dt_decl_sou($1, NULL); } 686 | struct_or_union DT_TOK_IDENT '{' { dt_decl_sou($1, $2); } 687 | struct_or_union DT_TOK_TNAME '{' { dt_decl_sou($1, $2); } 688 ; 689 690 struct_or_union: 691 DT_KEY_STRUCT { $$ = CTF_K_STRUCT; } 692 | DT_KEY_UNION { $$ = CTF_K_UNION; } 693 ; 694 695 struct_declaration_list: 696 struct_declaration 697 | struct_declaration_list struct_declaration 698 ; 699 700 init_declarator_list: 701 init_declarator 702 | init_declarator_list DT_TOK_COMMA init_declarator { 703 $$ = LINK($1, $3); 704 } 705 ; 706 707 init_declarator: 708 declarator { 709 $$ = dt_node_decl(); 710 dt_decl_reset(); 711 } 712 ; 713 714 struct_declaration: 715 specifier_qualifier_list struct_declarator_list ';' { 716 dt_decl_free(dt_decl_pop()); 717 } 718 ; 719 720 specifier_qualifier_list: 721 type_specifier 722 | type_specifier specifier_qualifier_list { $$ = $2; } 723 | type_qualifier 724 | type_qualifier specifier_qualifier_list { $$ = $2; } 725 ; 726 727 struct_declarator_list: 728 struct_declarator 729 | struct_declarator_list DT_TOK_COMMA struct_declarator 730 ; 731 732 struct_declarator: 733 declarator { dt_decl_member(NULL); } 734 | DT_TOK_COLON constant_expression { dt_decl_member($2); } 735 | declarator DT_TOK_COLON constant_expression { 736 dt_decl_member($3); 737 } 738 ; 739 740 enum_specifier: 741 enum_definition enumerator_list '}' { $$ = dt_scope_pop(); } 742 | enum_definition enumerator_list DT_TOK_COMMA '}' { $$ = 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 %% 863