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