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