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