Print this page
7085 add support for "if" and "else" statements in dtrace


   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 }


 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


 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




   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 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 }


 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


 303                 }
 304         ;
 305         
 306 
 307 probe_definition:
 308                 probe_specifiers {
 309                         /*
 310                          * If the input stream is a file, do not permit a probe
 311                          * specification without / <pred> / or { <act> } after
 312                          * it.  This can only occur if the next token is EOF or
 313                          * an ambiguous predicate was slurped up as a comment.
 314                          * We cannot perform this check if input() is a string
 315                          * because dtrace(1M) [-fmnP] also use the compiler and
 316                          * things like dtrace -n BEGIN have to be accepted.
 317                          */
 318                         if (yypcb->pcb_fileptr != NULL) {
 319                                 dnerror($1, D_SYNTAX, "expected predicate and/"
 320                                     "or actions following probe description\n");
 321                         }
 322                         $$ = dt_node_clause($1, NULL, NULL);
 323                         yybegin(YYS_CLAUSE);
 324                 }
 325         |       probe_specifiers '{' statement_list '}' {
 326                         $$ = dt_node_clause($1, NULL, $3);
 327                         yybegin(YYS_CLAUSE);
 328                 }
 329         |       probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED {
 330                         dnerror($3, D_SYNTAX, "expected actions { } following "
 331                             "probe description and predicate\n");
 332                 }
 333         |       probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED
 334                     '{' statement_list '}' {
 335                         $$ = dt_node_clause($1, $3, $6);
 336                         yybegin(YYS_CLAUSE);
 337                 }
 338         ;
 339 
 340 probe_specifiers:
 341                 probe_specifier_list { yybegin(YYS_EXPR); $$ = $1; }
 342         ;
 343 
 344 probe_specifier_list:
 345                 probe_specifier
 346         |       probe_specifier_list DT_TOK_COMMA probe_specifier {
 347                         $$ = LINK($1, $3);
 348                 }
 349         ;
 350 
 351 probe_specifier:
 352                 DT_TOK_PSPEC { $$ = dt_node_pdesc_by_name($1); }
 353         |       DT_TOK_INT   { $$ = dt_node_pdesc_by_id($1); }
 354         ;
 355 
 356 statement_list_impl: /* empty */ { $$ = NULL; }
 357         |       statement_list_impl statement { $$ = LINK($1, $2); }
 358         ;
 359 
 360 statement_list:
 361                 statement_list_impl { $$ = $1; }
 362         |       statement_list_impl expression {
 363                         $$ = LINK($1, dt_node_statement($2));
 364                 }
 365         ;
 366 
 367 statement_or_block:
 368                 statement
 369         |       '{' statement_list '}' { $$ = $2; }
 370 
 371 statement:      ';' { $$ = NULL; }
 372         |       expression ';' { $$ = dt_node_statement($1); }
 373         |       DT_KEY_IF DT_TOK_LPAR expression DT_TOK_RPAR statement_or_block {
 374                         $$ = dt_node_if($3, $5, NULL);
 375                 }
 376         |       DT_KEY_IF DT_TOK_LPAR expression DT_TOK_RPAR
 377                 statement_or_block DT_KEY_ELSE statement_or_block {
 378                         $$ = dt_node_if($3, $5, $7);
 379                 }
 380         ;
 381 
 382 argument_expression_list:
 383                 assignment_expression
 384         |       argument_expression_list DT_TOK_COMMA assignment_expression {
 385                         $$ = LINK($1, $3);
 386                 }
 387         ;
 388 
 389 primary_expression:
 390                 DT_TOK_IDENT { $$ = dt_node_ident($1); }
 391         |       DT_TOK_AGG { $$ = dt_node_ident($1); }
 392         |       DT_TOK_INT { $$ = dt_node_int($1); }
 393         |       DT_TOK_STRING { $$ = dt_node_string($1); }
 394         |       DT_KEY_SELF { $$ = dt_node_ident(DUP("self")); }
 395         |       DT_KEY_THIS { $$ = dt_node_ident(DUP("this")); }
 396         |       DT_TOK_LPAR expression DT_TOK_RPAR { $$ = $2; }
 397         ;
 398 
 399 postfix_expression:
 400                 primary_expression
 401         |       postfix_expression