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