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 %% 839