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 217 dtrace_program: d_expression DT_TOK_EOF { return (dt_node_root($1)); } 218 | d_program DT_TOK_EOF { return (dt_node_root($1)); } 219 | d_type DT_TOK_EOF { return (dt_node_root($1)); } 220 ; 221 222 d_expression: DT_CTX_DEXPR { $$ = NULL; } 223 | DT_CTX_DEXPR expression { $$ = $2; } 224 ; 225 226 d_program: DT_CTX_DPROG { $$ = dt_node_program(NULL); } 227 | DT_CTX_DPROG translation_unit { $$ = dt_node_program($2); } 228 ; 229 230 d_type: DT_CTX_DTYPE { $$ = NULL; } 231 | DT_CTX_DTYPE type_name { $$ = (dt_node_t *)$2; } 232 ; 233 234 translation_unit: 235 external_declaration 236 | translation_unit external_declaration { $$ = LINK($1, $2); } 237 ; 238 239 external_declaration: 240 inline_definition 241 | translator_definition 242 | provider_definition 243 | probe_definition 244 | declaration 245 ; 246 247 inline_definition: 248 DT_KEY_INLINE declaration_specifiers declarator 249 { dt_scope_push(NULL, CTF_ERR); } DT_TOK_ASGN 250 assignment_expression ';' { 251 /* 252 * We push a new declaration scope before shifting the 253 * assignment_expression in order to preserve ds_class 254 * and ds_ident for use in dt_node_inline(). Once the 255 * entire inline_definition rule is matched, pop the 256 * scope and construct the inline using the saved decl. 257 */ 258 dt_scope_pop(); 259 $$ = dt_node_inline($6); 260 } 261 ; 262 263 translator_definition: 264 DT_KEY_XLATOR type_name DT_TOK_LT type_name 265 DT_TOK_IDENT DT_TOK_GT '{' translator_member_list '}' ';' { 266 $$ = dt_node_xlator($2, $4, $5, $8); 267 } 268 | DT_KEY_XLATOR type_name DT_TOK_LT type_name 269 DT_TOK_IDENT DT_TOK_GT '{' '}' ';' { 270 $$ = dt_node_xlator($2, $4, $5, NULL); 271 } 272 ; 273 274 translator_member_list: 275 translator_member 276 | translator_member_list translator_member { $$ = LINK($1,$2); } 277 ; 278 279 translator_member: 280 DT_TOK_IDENT DT_TOK_ASGN assignment_expression ';' { 281 $$ = dt_node_member(NULL, $1, $3); 282 } 283 ; 284 285 provider_definition: 286 DT_KEY_PROVIDER DT_TOK_IDENT '{' provider_probe_list '}' ';' { 287 $$ = dt_node_provider($2, $4); 288 } 289 | DT_KEY_PROVIDER DT_TOK_IDENT '{' '}' ';' { 290 $$ = dt_node_provider($2, NULL); 291 } 292 ; 293 294 provider_probe_list: 295 provider_probe 296 | provider_probe_list provider_probe { $$ = LINK($1, $2); } 297 ; 298 299 provider_probe: 300 DT_KEY_PROBE DT_TOK_IDENT function DT_TOK_COLON function ';' { 301 $$ = dt_node_probe($2, 2, $3, $5); 302 } 303 | DT_KEY_PROBE DT_TOK_IDENT function ';' { 304 $$ = dt_node_probe($2, 1, $3, NULL); 305 } 306 ; 307 308 309 probe_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 342 probe_specifiers: 343 probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; } 344 ; 345 346 probe_specifier_list: 347 probe_specifier 348 | probe_specifier_list DT_TOK_COMMA probe_specifier { 349 $$ = LINK($1, $3); 350 } 351 ; 352 353 probe_specifier: 354 DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); } 355 | DT_TOK_INT { $$ = dt_node_pdesc_by_id($1); } 356 ; 357 358 statement_list_impl: /* empty */ { $$ = NULL; } 359 | statement_list_impl statement { $$ = LINK($1, $2); } 360 ; 361 362 statement_list: 363 statement_list_impl { $$ = $1; } 364 | statement_list_impl expression { 365 $$ = LINK($1, dt_node_statement($2)); 366 } 367 ; 368 369 statement_or_block: 370 statement 371 | '{' statement_list '}' { $$ = $2; } 372 373 statement: ';' { $$ = 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 384 argument_expression_list: 385 assignment_expression 386 | argument_expression_list DT_TOK_COMMA assignment_expression { 387 $$ = LINK($1, $3); 388 } 389 ; 390 391 primary_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 401 postfix_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 456 unary_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 470 unary_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 478 cast_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 485 multiplicative_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 498 additive_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 508 shift_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 518 relational_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 534 equality_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 544 and_expression: 545 equality_expression 546 | and_expression DT_TOK_BAND equality_expression { 547 $$ = OP2(DT_TOK_BAND, $1, $3); 548 } 549 ; 550 551 exclusive_or_expression: 552 and_expression 553 | exclusive_or_expression DT_TOK_XOR and_expression { 554 $$ = OP2(DT_TOK_XOR, $1, $3); 555 } 556 ; 557 558 inclusive_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 565 logical_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 572 logical_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 579 logical_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 586 constant_expression: conditional_expression 587 ; 588 589 conditional_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 595 assignment_expression: 596 conditional_expression 597 | unary_expression assignment_operator assignment_expression { 598 $$ = OP2($2, $1, $3); 599 } 600 ; 601 602 assignment_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 616 expression: assignment_expression 617 | expression DT_TOK_COMMA assignment_expression { 618 $$ = OP2(DT_TOK_COMMA, $1, $3); 619 } 620 ; 621 622 declaration: 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 634 declaration_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 643 parameter_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 652 storage_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 660 d_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 666 type_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 684 type_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 689 struct_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 697 struct_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 703 struct_or_union: 704 DT_KEY_STRUCT { $$ = CTF_K_STRUCT; } 705 | DT_KEY_UNION { $$ = CTF_K_UNION; } 706 ; 707 708 struct_declaration_list: 709 struct_declaration 710 | struct_declaration_list struct_declaration 711 ; 712 713 init_declarator_list: 714 init_declarator 715 | init_declarator_list DT_TOK_COMMA init_declarator { 716 $$ = LINK($1, $3); 717 } 718 ; 719 720 init_declarator: 721 declarator { 722 $$ = dt_node_decl(); 723 dt_decl_reset(); 724 } 725 ; 726 727 struct_declaration: 728 specifier_qualifier_list struct_declarator_list ';' { 729 dt_decl_free(dt_decl_pop()); 730 } 731 ; 732 733 specifier_qualifier_list: 734 type_specifier 735 | type_specifier specifier_qualifier_list { $$ = $2; } 736 | type_qualifier 737 | type_qualifier specifier_qualifier_list { $$ = $2; } 738 ; 739 740 struct_declarator_list: 741 struct_declarator 742 | struct_declarator_list DT_TOK_COMMA struct_declarator 743 ; 744 745 struct_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 753 enum_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 759 enum_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 765 enumerator_list: 766 enumerator 767 | enumerator_list DT_TOK_COMMA enumerator 768 ; 769 770 enumerator: 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 776 declarator: direct_declarator 777 | pointer direct_declarator 778 ; 779 780 direct_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 787 lparen: DT_TOK_LPAR { dt_decl_top()->dd_attr |= DT_DA_PAREN; } 788 ; 789 790 pointer: 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 796 type_qualifier_list: 797 type_qualifier 798 | type_qualifier_list type_qualifier { $$ = $2; } 799 ; 800 801 parameter_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 809 parameter_list: parameter_declaration 810 | parameter_list DT_TOK_COMMA parameter_declaration { 811 $$ = LINK($1, $3); 812 } 813 ; 814 815 parameter_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 827 type_name: specifier_qualifier_list { 828 $$ = dt_decl_pop(); 829 } 830 | specifier_qualifier_list abstract_declarator { 831 $$ = dt_decl_pop(); 832 } 833 ; 834 835 abstract_declarator: 836 pointer 837 | direct_abstract_declarator 838 | pointer direct_abstract_declarator 839 ; 840 841 direct_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 849 array: DT_TOK_LBRAC { dt_scope_push(NULL, CTF_ERR); } 850 array_parameters DT_TOK_RBRAC { 851 dt_scope_pop(); 852 $$ = $3; 853 } 854 ; 855 856 array_parameters: 857 /* empty */ { $$ = NULL; } 858 | constant_expression { $$ = $1; } 859 | parameter_type_list { $$ = $1; } 860 ; 861 862 function: DT_TOK_LPAR { dt_scope_push(NULL, CTF_ERR); } 863 function_parameters DT_TOK_RPAR { 864 dt_scope_pop(); 865 $$ = $3; 866 } 867 ; 868 869 function_parameters: 870 /* empty */ { $$ = NULL; } 871 | parameter_type_list { $$ = $1; } 872 ; 873 874 dtrace_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