1 /* perly.y 2 * 3 * Copyright (c) 1991-2002, 2003, 2004, 2005, 2006 Larry Wall 4 * Copyright (c) 2007, 2008, 2009, 2010, 2011 by Larry Wall and others 5 * 6 * You may distribute under the terms of either the GNU General Public 7 * License or the Artistic License, as specified in the README file. 8 * 9 */ 10 11 /* 12 * 'I see,' laughed Strider. 'I look foul and feel fair. Is that it? 13 * All that is gold does not glitter, not all those who wander are lost.' 14 * 15 * [p.171 of _The Lord of the Rings_, I/x: "Strider"] 16 */ 17 18 /* 19 * This file holds the grammar for the Perl language. If edited, you need 20 * to run regen_perly.pl, which re-creates the files perly.h, perly.tab 21 * and perly.act which are derived from this. 22 * 23 * The main job of of this grammar is to call the various newFOO() 24 * functions in op.c to build a syntax tree of OP structs. 25 * It relies on the lexer in toke.c to do the tokenizing. 26 * 27 * Note: due to the way that the cleanup code works WRT to freeing ops on 28 * the parse stack, it is dangerous to assign to the $n variables within 29 * an action. 30 */ 31 32 /* Make the parser re-entrant. */ 33 34 %pure-parser 35 36 %start grammar 37 38 %union { 39 I32 ival; /* __DEFAULT__ (marker for regen_perly.pl; 40 must always be 1st union member) */ 41 char *pval; 42 OP *opval; 43 GV *gvval; 44 } 45 46 %token <ival> GRAMPROG GRAMEXPR GRAMBLOCK GRAMBARESTMT GRAMFULLSTMT GRAMSTMTSEQ 47 48 %token <ival> '{' '}' '[' ']' '-' '+' '@' '%' '&' '=' '.' 49 50 %token <opval> BAREWORD METHOD FUNCMETH THING PMFUNC PRIVATEREF QWLIST 51 %token <opval> FUNC0OP FUNC0SUB UNIOPSUB LSTOPSUB 52 %token <opval> PLUGEXPR PLUGSTMT 53 %token <opval> LABEL 54 %token <ival> FORMAT SUB SIGSUB ANONSUB ANON_SIGSUB PACKAGE USE 55 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR 56 %token <ival> GIVEN WHEN DEFAULT 57 %token <ival> LOOPEX DOTDOT YADAYADA 58 %token <ival> FUNC0 FUNC1 FUNC UNIOP LSTOP 59 %token <ival> RELOP EQOP MULOP ADDOP 60 %token <ival> DOLSHARP DO HASHBRACK NOAMP 61 %token <ival> LOCAL MY REQUIRE 62 %token <ival> COLONATTR FORMLBRACK FORMRBRACK 63 64 %type <ival> grammar remember mremember 65 %type <ival> startsub startanonsub startformsub 66 67 %type <ival> mintro 68 69 %type <opval> stmtseq fullstmt labfullstmt barestmt block mblock else 70 %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff 71 %type <opval> sliceme kvslice gelem 72 %type <opval> listexpr nexpr texpr iexpr mexpr mnexpr 73 %type <opval> optlistexpr optexpr optrepl indirob listop method 74 %type <opval> formname subname proto cont my_scalar my_var 75 %type <opval> refgen_topic formblock 76 %type <opval> subattrlist myattrlist myattrterm myterm 77 %type <opval> termbinop termunop anonymous termdo 78 %type <ival> sigslurpsigil 79 %type <opval> sigvarname sigdefault sigscalarelem sigslurpelem 80 %type <opval> sigelem siglist siglistornull subsignature optsubsignature 81 %type <opval> subbody optsubbody sigsubbody optsigsubbody 82 %type <opval> formstmtseq formline formarg 83 84 %nonassoc <ival> PREC_LOW 85 %nonassoc LOOPEX 86 87 %left <ival> OROP DOROP 88 %left <ival> ANDOP 89 %right <ival> NOTOP 90 %nonassoc LSTOP LSTOPSUB 91 %left <ival> ',' 92 %right <ival> ASSIGNOP 93 %right <ival> '?' ':' 94 %nonassoc DOTDOT 95 %left <ival> OROR DORDOR 96 %left <ival> ANDAND 97 %left <ival> BITOROP 98 %left <ival> BITANDOP 99 %nonassoc EQOP 100 %nonassoc RELOP 101 %nonassoc UNIOP UNIOPSUB 102 %nonassoc REQUIRE 103 %left <ival> SHIFTOP 104 %left ADDOP 105 %left MULOP 106 %left <ival> MATCHOP 107 %right <ival> '!' '~' UMINUS REFGEN 108 %right <ival> POWOP 109 %nonassoc <ival> PREINC PREDEC POSTINC POSTDEC POSTJOIN 110 %left <ival> ARROW 111 %nonassoc <ival> ')' 112 %left <ival> '(' 113 %left '[' '{' 114 115 %% /* RULES */ 116 117 /* Top-level choice of what kind of thing yyparse was called to parse */ 118 grammar : GRAMPROG 119 { 120 parser->expect = XSTATE; 121 $<ival>$ = 0; 122 } 123 remember stmtseq 124 { 125 newPROG(block_end($3,$4)); 126 PL_compiling.cop_seq = 0; 127 $$ = 0; 128 } 129 | GRAMEXPR 130 { 131 parser->expect = XTERM; 132 $<ival>$ = 0; 133 } 134 optexpr 135 { 136 PL_eval_root = $3; 137 $$ = 0; 138 } 139 | GRAMBLOCK 140 { 141 parser->expect = XBLOCK; 142 $<ival>$ = 0; 143 } 144 block 145 { 146 PL_pad_reset_pending = TRUE; 147 PL_eval_root = $3; 148 $$ = 0; 149 yyunlex(); 150 parser->yychar = yytoken = YYEOF; 151 } 152 | GRAMBARESTMT 153 { 154 parser->expect = XSTATE; 155 $<ival>$ = 0; 156 } 157 barestmt 158 { 159 PL_pad_reset_pending = TRUE; 160 PL_eval_root = $3; 161 $$ = 0; 162 yyunlex(); 163 parser->yychar = yytoken = YYEOF; 164 } 165 | GRAMFULLSTMT 166 { 167 parser->expect = XSTATE; 168 $<ival>$ = 0; 169 } 170 fullstmt 171 { 172 PL_pad_reset_pending = TRUE; 173 PL_eval_root = $3; 174 $$ = 0; 175 yyunlex(); 176 parser->yychar = yytoken = YYEOF; 177 } 178 | GRAMSTMTSEQ 179 { 180 parser->expect = XSTATE; 181 $<ival>$ = 0; 182 } 183 stmtseq 184 { 185 PL_eval_root = $3; 186 $$ = 0; 187 } 188 ; 189 190 /* An ordinary block */ 191 block : '{' remember stmtseq '}' 192 { if (parser->copline > (line_t)$1) 193 parser->copline = (line_t)$1; 194 $$ = block_end($2, $3); 195 } 196 ; 197 198 /* format body */ 199 formblock: '=' remember ';' FORMRBRACK formstmtseq ';' '.' 200 { if (parser->copline > (line_t)$1) 201 parser->copline = (line_t)$1; 202 $$ = block_end($2, $5); 203 } 204 ; 205 206 remember: /* NULL */ /* start a full lexical scope */ 207 { $$ = block_start(TRUE); 208 parser->parsed_sub = 0; } 209 ; 210 211 mblock : '{' mremember stmtseq '}' 212 { if (parser->copline > (line_t)$1) 213 parser->copline = (line_t)$1; 214 $$ = block_end($2, $3); 215 } 216 ; 217 218 mremember: /* NULL */ /* start a partial lexical scope */ 219 { $$ = block_start(FALSE); 220 parser->parsed_sub = 0; } 221 ; 222 223 /* A sequence of statements in the program */ 224 stmtseq : /* NULL */ 225 { $$ = NULL; } 226 | stmtseq fullstmt 227 { $$ = op_append_list(OP_LINESEQ, $1, $2); 228 PL_pad_reset_pending = TRUE; 229 if ($1 && $2) 230 PL_hints |= HINT_BLOCK_SCOPE; 231 } 232 ; 233 234 /* A sequence of format lines */ 235 formstmtseq: /* NULL */ 236 { $$ = NULL; } 237 | formstmtseq formline 238 { $$ = op_append_list(OP_LINESEQ, $1, $2); 239 PL_pad_reset_pending = TRUE; 240 if ($1 && $2) 241 PL_hints |= HINT_BLOCK_SCOPE; 242 } 243 ; 244 245 /* A statement in the program, including optional labels */ 246 fullstmt: barestmt 247 { 248 $$ = $1 ? newSTATEOP(0, NULL, $1) : NULL; 249 } 250 | labfullstmt 251 { $$ = $1; } 252 ; 253 254 labfullstmt: LABEL barestmt 255 { 256 SV *label = cSVOPx_sv($1); 257 $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8, 258 savepv(SvPVX_const(label)), $2); 259 op_free($1); 260 } 261 | LABEL labfullstmt 262 { 263 SV *label = cSVOPx_sv($1); 264 $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8, 265 savepv(SvPVX_const(label)), $2); 266 op_free($1); 267 } 268 ; 269 270 /* A bare statement, lacking label and other aspects of state op */ 271 barestmt: PLUGSTMT 272 { $$ = $1; } 273 | FORMAT startformsub formname formblock 274 { 275 CV *fmtcv = PL_compcv; 276 newFORM($2, $3, $4); 277 $$ = NULL; 278 if (CvOUTSIDE(fmtcv) && !CvEVAL(CvOUTSIDE(fmtcv))) { 279 pad_add_weakref(fmtcv); 280 } 281 parser->parsed_sub = 1; 282 } 283 | SUB subname startsub 284 /* sub declaration or definition not within scope 285 of 'use feature "signatures"'*/ 286 { 287 init_named_cv(PL_compcv, $2); 288 parser->in_my = 0; 289 parser->in_my_stash = NULL; 290 } 291 proto subattrlist optsubbody 292 { 293 SvREFCNT_inc_simple_void(PL_compcv); 294 $2->op_type == OP_CONST 295 ? newATTRSUB($3, $2, $5, $6, $7) 296 : newMYSUB($3, $2, $5, $6, $7) 297 ; 298 $$ = NULL; 299 intro_my(); 300 parser->parsed_sub = 1; 301 } 302 | SIGSUB subname startsub 303 /* sub declaration or definition under 'use feature 304 * "signatures"'. (Note that a signature isn't 305 * allowed in a declaration) 306 */ 307 { 308 init_named_cv(PL_compcv, $2); 309 parser->in_my = 0; 310 parser->in_my_stash = NULL; 311 } 312 subattrlist optsigsubbody 313 { 314 SvREFCNT_inc_simple_void(PL_compcv); 315 $2->op_type == OP_CONST 316 ? newATTRSUB($3, $2, NULL, $5, $6) 317 : newMYSUB( $3, $2, NULL, $5, $6) 318 ; 319 $$ = NULL; 320 intro_my(); 321 parser->parsed_sub = 1; 322 } 323 | PACKAGE BAREWORD BAREWORD ';' 324 { 325 package($3); 326 if ($2) 327 package_version($2); 328 $$ = NULL; 329 } 330 | USE startsub 331 { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ } 332 BAREWORD BAREWORD optlistexpr ';' 333 { 334 SvREFCNT_inc_simple_void(PL_compcv); 335 utilize($1, $2, $4, $5, $6); 336 parser->parsed_sub = 1; 337 $$ = NULL; 338 } 339 | IF '(' remember mexpr ')' mblock else 340 { 341 $$ = block_end($3, 342 newCONDOP(0, $4, op_scope($6), $7)); 343 parser->copline = (line_t)$1; 344 } 345 | UNLESS '(' remember mexpr ')' mblock else 346 { 347 $$ = block_end($3, 348 newCONDOP(0, $4, $7, op_scope($6))); 349 parser->copline = (line_t)$1; 350 } 351 | GIVEN '(' remember mexpr ')' mblock 352 { 353 $$ = block_end($3, newGIVENOP($4, op_scope($6), 0)); 354 parser->copline = (line_t)$1; 355 } 356 | WHEN '(' remember mexpr ')' mblock 357 { $$ = block_end($3, newWHENOP($4, op_scope($6))); } 358 | DEFAULT block 359 { $$ = newWHENOP(0, op_scope($2)); } 360 | WHILE '(' remember texpr ')' mintro mblock cont 361 { 362 $$ = block_end($3, 363 newWHILEOP(0, 1, NULL, 364 $4, $7, $8, $6)); 365 parser->copline = (line_t)$1; 366 } 367 | UNTIL '(' remember iexpr ')' mintro mblock cont 368 { 369 $$ = block_end($3, 370 newWHILEOP(0, 1, NULL, 371 $4, $7, $8, $6)); 372 parser->copline = (line_t)$1; 373 } 374 | FOR '(' remember mnexpr ';' 375 { parser->expect = XTERM; } 376 texpr ';' 377 { parser->expect = XTERM; } 378 mintro mnexpr ')' 379 mblock 380 { 381 OP *initop = $4; 382 OP *forop = newWHILEOP(0, 1, NULL, 383 scalar($7), $13, $11, $10); 384 if (initop) { 385 forop = op_prepend_elem(OP_LINESEQ, initop, 386 op_append_elem(OP_LINESEQ, 387 newOP(OP_UNSTACK, OPf_SPECIAL), 388 forop)); 389 } 390 PL_hints |= HINT_BLOCK_SCOPE; 391 $$ = block_end($3, forop); 392 parser->copline = (line_t)$1; 393 } 394 | FOR MY remember my_scalar '(' mexpr ')' mblock cont 395 { 396 $$ = block_end($3, newFOROP(0, $4, $6, $8, $9)); 397 parser->copline = (line_t)$1; 398 } 399 | FOR scalar '(' remember mexpr ')' mblock cont 400 { 401 $$ = block_end($4, newFOROP(0, 402 op_lvalue($2, OP_ENTERLOOP), $5, $7, $8)); 403 parser->copline = (line_t)$1; 404 } 405 | FOR my_refgen remember my_var 406 { parser->in_my = 0; $<opval>$ = my($4); } 407 '(' mexpr ')' mblock cont 408 { 409 $$ = block_end( 410 $3, 411 newFOROP(0, 412 op_lvalue( 413 newUNOP(OP_REFGEN, 0, 414 $<opval>5), 415 OP_ENTERLOOP), 416 $7, $9, $10) 417 ); 418 parser->copline = (line_t)$1; 419 } 420 | FOR REFGEN refgen_topic '(' remember mexpr ')' mblock cont 421 { 422 $$ = block_end($5, newFOROP( 423 0, op_lvalue(newUNOP(OP_REFGEN, 0, 424 $3), 425 OP_ENTERLOOP), $6, $8, $9)); 426 parser->copline = (line_t)$1; 427 } 428 | FOR '(' remember mexpr ')' mblock cont 429 { 430 $$ = block_end($3, 431 newFOROP(0, NULL, $4, $6, $7)); 432 parser->copline = (line_t)$1; 433 } 434 | block cont 435 { 436 /* a block is a loop that happens once */ 437 $$ = newWHILEOP(0, 1, NULL, 438 NULL, $1, $2, 0); 439 } 440 | PACKAGE BAREWORD BAREWORD '{' remember 441 { 442 package($3); 443 if ($2) { 444 package_version($2); 445 } 446 } 447 stmtseq '}' 448 { 449 /* a block is a loop that happens once */ 450 $$ = newWHILEOP(0, 1, NULL, 451 NULL, block_end($5, $7), NULL, 0); 452 if (parser->copline > (line_t)$4) 453 parser->copline = (line_t)$4; 454 } 455 | sideff ';' 456 { 457 $$ = $1; 458 } 459 | YADAYADA ';' 460 { 461 $$ = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0), 462 newSVOP(OP_CONST, 0, newSVpvs("Unimplemented"))); 463 } 464 | ';' 465 { 466 $$ = NULL; 467 parser->copline = NOLINE; 468 } 469 ; 470 471 /* Format line */ 472 formline: THING formarg 473 { OP *list; 474 if ($2) { 475 OP *term = $2; 476 list = op_append_elem(OP_LIST, $1, term); 477 } 478 else { 479 list = $1; 480 } 481 if (parser->copline == NOLINE) 482 parser->copline = CopLINE(PL_curcop)-1; 483 else parser->copline--; 484 $$ = newSTATEOP(0, NULL, 485 op_convert_list(OP_FORMLINE, 0, list)); 486 } 487 ; 488 489 formarg : /* NULL */ 490 { $$ = NULL; } 491 | FORMLBRACK stmtseq FORMRBRACK 492 { $$ = op_unscope($2); } 493 ; 494 495 /* An expression which may have a side-effect */ 496 sideff : error 497 { $$ = NULL; } 498 | expr 499 { $$ = $1; } 500 | expr IF expr 501 { $$ = newLOGOP(OP_AND, 0, $3, $1); } 502 | expr UNLESS expr 503 { $$ = newLOGOP(OP_OR, 0, $3, $1); } 504 | expr WHILE expr 505 { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); } 506 | expr UNTIL iexpr 507 { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1); } 508 | expr FOR expr 509 { $$ = newFOROP(0, NULL, $3, $1, NULL); 510 parser->copline = (line_t)$2; } 511 | expr WHEN expr 512 { $$ = newWHENOP($3, op_scope($1)); } 513 ; 514 515 /* else and elsif blocks */ 516 else : /* NULL */ 517 { $$ = NULL; } 518 | ELSE mblock 519 { 520 ($2)->op_flags |= OPf_PARENS; 521 $$ = op_scope($2); 522 } 523 | ELSIF '(' mexpr ')' mblock else 524 { parser->copline = (line_t)$1; 525 $$ = newCONDOP(0, 526 newSTATEOP(OPf_SPECIAL,NULL,$3), 527 op_scope($5), $6); 528 PL_hints |= HINT_BLOCK_SCOPE; 529 } 530 ; 531 532 /* Continue blocks */ 533 cont : /* NULL */ 534 { $$ = NULL; } 535 | CONTINUE block 536 { $$ = op_scope($2); } 537 ; 538 539 /* determine whether there are any new my declarations */ 540 mintro : /* NULL */ 541 { $$ = (PL_min_intro_pending && 542 PL_max_intro_pending >= PL_min_intro_pending); 543 intro_my(); } 544 545 /* Normal expression */ 546 nexpr : /* NULL */ 547 { $$ = NULL; } 548 | sideff 549 ; 550 551 /* Boolean expression */ 552 texpr : /* NULL means true */ 553 { YYSTYPE tmplval; 554 (void)scan_num("1", &tmplval); 555 $$ = tmplval.opval; } 556 | expr 557 ; 558 559 /* Inverted boolean expression */ 560 iexpr : expr 561 { $$ = invert(scalar($1)); } 562 ; 563 564 /* Expression with its own lexical scope */ 565 mexpr : expr 566 { $$ = $1; intro_my(); } 567 ; 568 569 mnexpr : nexpr 570 { $$ = $1; intro_my(); } 571 ; 572 573 formname: BAREWORD { $$ = $1; } 574 | /* NULL */ { $$ = NULL; } 575 ; 576 577 startsub: /* NULL */ /* start a regular subroutine scope */ 578 { $$ = start_subparse(FALSE, 0); 579 SAVEFREESV(PL_compcv); } 580 581 ; 582 583 startanonsub: /* NULL */ /* start an anonymous subroutine scope */ 584 { $$ = start_subparse(FALSE, CVf_ANON); 585 SAVEFREESV(PL_compcv); } 586 ; 587 588 startformsub: /* NULL */ /* start a format subroutine scope */ 589 { $$ = start_subparse(TRUE, 0); 590 SAVEFREESV(PL_compcv); } 591 ; 592 593 /* Name of a subroutine - must be a bareword, could be special */ 594 subname : BAREWORD 595 | PRIVATEREF 596 ; 597 598 /* Subroutine prototype */ 599 proto : /* NULL */ 600 { $$ = NULL; } 601 | THING 602 ; 603 604 /* Optional list of subroutine attributes */ 605 subattrlist: /* NULL */ 606 { $$ = NULL; } 607 | COLONATTR THING 608 { $$ = $2; } 609 | COLONATTR 610 { $$ = NULL; } 611 ; 612 613 /* List of attributes for a "my" variable declaration */ 614 myattrlist: COLONATTR THING 615 { $$ = $2; } 616 | COLONATTR 617 { $$ = NULL; } 618 ; 619 620 621 622 /* -------------------------------------- 623 * subroutine signature parsing 624 */ 625 626 /* the '' or 'foo' part of a '$' or '@foo' etc signature variable */ 627 sigvarname: /* NULL */ 628 { parser->in_my = 0; $$ = NULL; } 629 | PRIVATEREF 630 { parser->in_my = 0; $$ = $1; } 631 ; 632 633 sigslurpsigil: 634 '@' 635 { $$ = '@'; } 636 | '%' 637 { $$ = '%'; } 638 639 /* @, %, @foo, %foo */ 640 sigslurpelem: sigslurpsigil sigvarname sigdefault/* def only to catch errors */ 641 { 642 I32 sigil = $1; 643 OP *var = $2; 644 OP *defexpr = $3; 645 646 if (parser->sig_slurpy) 647 yyerror("Multiple slurpy parameters not allowed"); 648 parser->sig_slurpy = (char)sigil; 649 650 if (defexpr) 651 yyerror("A slurpy parameter may not have " 652 "a default value"); 653 654 $$ = var ? newSTATEOP(0, NULL, var) : NULL; 655 } 656 ; 657 658 /* default part of sub signature scalar element: i.e. '= default_expr' */ 659 sigdefault: /* NULL */ 660 { $$ = NULL; } 661 | ASSIGNOP 662 { $$ = newOP(OP_NULL, 0); } 663 | ASSIGNOP term 664 { $$ = $2; } 665 666 667 /* subroutine signature scalar element: e.g. '$x', '$=', '$x = $default' */ 668 sigscalarelem: 669 '$' sigvarname sigdefault 670 { 671 OP *var = $2; 672 OP *defexpr = $3; 673 674 if (parser->sig_slurpy) 675 yyerror("Slurpy parameter not last"); 676 677 parser->sig_elems++; 678 679 if (defexpr) { 680 parser->sig_optelems++; 681 682 if ( defexpr->op_type == OP_NULL 683 && !(defexpr->op_flags & OPf_KIDS)) 684 { 685 /* handle '$=' special case */ 686 if (var) 687 yyerror("Optional parameter " 688 "lacks default expression"); 689 op_free(defexpr); 690 } 691 else { 692 /* a normal '=default' expression */ 693 OP *defop = (OP*)alloc_LOGOP(OP_ARGDEFELEM, 694 defexpr, 695 LINKLIST(defexpr)); 696 /* re-purpose op_targ to hold @_ index */ 697 defop->op_targ = 698 (PADOFFSET)(parser->sig_elems - 1); 699 700 if (var) { 701 var->op_flags |= OPf_STACKED; 702 (void)op_sibling_splice(var, 703 NULL, 0, defop); 704 scalar(defop); 705 } 706 else 707 var = newUNOP(OP_NULL, 0, defop); 708 709 LINKLIST(var); 710 /* NB: normally the first child of a 711 * logop is executed before the logop, 712 * and it pushes a boolean result 713 * ready for the logop. For ARGDEFELEM, 714 * the op itself does the boolean 715 * calculation, so set the first op to 716 * it instead. 717 */ 718 var->op_next = defop; 719 defexpr->op_next = var; 720 } 721 } 722 else { 723 if (parser->sig_optelems) 724 yyerror("Mandatory parameter " 725 "follows optional parameter"); 726 } 727 728 $$ = var ? newSTATEOP(0, NULL, var) : NULL; 729 } 730 ; 731 732 733 /* subroutine signature element: e.g. '$x = $default' or '%h' */ 734 sigelem: sigscalarelem 735 { parser->in_my = KEY_sigvar; $$ = $1; } 736 | sigslurpelem 737 { parser->in_my = KEY_sigvar; $$ = $1; } 738 ; 739 740 /* list of subroutine signature elements */ 741 siglist: 742 siglist ',' 743 { $$ = $1; } 744 | siglist ',' sigelem 745 { 746 $$ = op_append_list(OP_LINESEQ, $1, $3); 747 } 748 | sigelem %prec PREC_LOW 749 { $$ = $1; } 750 ; 751 752 /* () or (....) */ 753 siglistornull: /* NULL */ 754 { $$ = NULL; } 755 | siglist 756 { $$ = $1; } 757 758 /* optional subroutine signature */ 759 optsubsignature: /* NULL */ 760 { $$ = NULL; } 761 | subsignature 762 { $$ = $1; } 763 764 /* Subroutine signature */ 765 subsignature: '(' 766 { 767 ENTER; 768 SAVEIV(parser->sig_elems); 769 SAVEIV(parser->sig_optelems); 770 SAVEI8(parser->sig_slurpy); 771 parser->sig_elems = 0; 772 parser->sig_optelems = 0; 773 parser->sig_slurpy = 0; 774 parser->in_my = KEY_sigvar; 775 } 776 siglistornull 777 ')' 778 { 779 OP *sigops = $3; 780 UNOP_AUX_item *aux; 781 OP *check; 782 783 if (!FEATURE_SIGNATURES_IS_ENABLED) 784 Perl_croak(aTHX_ "Experimental " 785 "subroutine signatures not enabled"); 786 787 /* We shouldn't get here otherwise */ 788 Perl_ck_warner_d(aTHX_ 789 packWARN(WARN_EXPERIMENTAL__SIGNATURES), 790 "The signatures feature is experimental"); 791 792 aux = (UNOP_AUX_item*)PerlMemShared_malloc( 793 sizeof(UNOP_AUX_item) * 3); 794 aux[0].iv = parser->sig_elems; 795 aux[1].iv = parser->sig_optelems; 796 aux[2].iv = parser->sig_slurpy; 797 check = newUNOP_AUX(OP_ARGCHECK, 0, NULL, aux); 798 sigops = op_prepend_elem(OP_LINESEQ, check, sigops); 799 sigops = op_prepend_elem(OP_LINESEQ, 800 newSTATEOP(0, NULL, NULL), 801 sigops); 802 /* a nextstate at the end handles context 803 * correctly for an empty sub body */ 804 $$ = op_append_elem(OP_LINESEQ, 805 sigops, 806 newSTATEOP(0, NULL, NULL)); 807 808 parser->in_my = 0; 809 /* tell the toker that attrributes can follow 810 * this sig, but only so that the toker 811 * can skip through any (illegal) trailing 812 * attribute text then give a useful error 813 * message about "attributes before sig", 814 * rather than falling over ina mess at 815 * unrecognised syntax. 816 */ 817 parser->expect = XATTRBLOCK; 818 parser->sig_seen = TRUE; 819 LEAVE; 820 } 821 ; 822 823 /* Optional subroutine body (for named subroutine declaration) */ 824 optsubbody: subbody { $$ = $1; } 825 | ';' { $$ = NULL; } 826 ; 827 828 829 /* Subroutine body (without signature) */ 830 subbody: remember '{' stmtseq '}' 831 { 832 if (parser->copline > (line_t)$2) 833 parser->copline = (line_t)$2; 834 $$ = block_end($1, $3); 835 } 836 ; 837 838 839 /* optional [ Subroutine body with optional signature ] (for named 840 * subroutine declaration) */ 841 optsigsubbody: sigsubbody { $$ = $1; } 842 | ';' { $$ = NULL; } 843 844 /* Subroutine body with optional signature */ 845 sigsubbody: remember optsubsignature '{' stmtseq '}' 846 { 847 if (parser->copline > (line_t)$3) 848 parser->copline = (line_t)$3; 849 $$ = block_end($1, 850 op_append_list(OP_LINESEQ, $2, $4)); 851 } 852 ; 853 854 855 /* Ordinary expressions; logical combinations */ 856 expr : expr ANDOP expr 857 { $$ = newLOGOP(OP_AND, 0, $1, $3); } 858 | expr OROP expr 859 { $$ = newLOGOP($2, 0, $1, $3); } 860 | expr DOROP expr 861 { $$ = newLOGOP(OP_DOR, 0, $1, $3); } 862 | listexpr %prec PREC_LOW 863 ; 864 865 /* Expressions are a list of terms joined by commas */ 866 listexpr: listexpr ',' 867 { $$ = $1; } 868 | listexpr ',' term 869 { 870 OP* term = $3; 871 $$ = op_append_elem(OP_LIST, $1, term); 872 } 873 | term %prec PREC_LOW 874 ; 875 876 /* List operators */ 877 listop : LSTOP indirob listexpr /* map {...} @args or print $fh @args */ 878 { $$ = op_convert_list($1, OPf_STACKED, 879 op_prepend_elem(OP_LIST, newGVREF($1,$2), $3) ); 880 } 881 | FUNC '(' indirob expr ')' /* print ($fh @args */ 882 { $$ = op_convert_list($1, OPf_STACKED, 883 op_prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); 884 } 885 | term ARROW method '(' optexpr ')' /* $foo->bar(list) */ 886 { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, 887 op_append_elem(OP_LIST, 888 op_prepend_elem(OP_LIST, scalar($1), $5), 889 newMETHOP(OP_METHOD, 0, $3))); 890 } 891 | term ARROW method /* $foo->bar */ 892 { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, 893 op_append_elem(OP_LIST, scalar($1), 894 newMETHOP(OP_METHOD, 0, $3))); 895 } 896 | METHOD indirob optlistexpr /* new Class @args */ 897 { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, 898 op_append_elem(OP_LIST, 899 op_prepend_elem(OP_LIST, $2, $3), 900 newMETHOP(OP_METHOD, 0, $1))); 901 } 902 | FUNCMETH indirob '(' optexpr ')' /* method $object (@args) */ 903 { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, 904 op_append_elem(OP_LIST, 905 op_prepend_elem(OP_LIST, $2, $4), 906 newMETHOP(OP_METHOD, 0, $1))); 907 } 908 | LSTOP optlistexpr /* print @args */ 909 { $$ = op_convert_list($1, 0, $2); } 910 | FUNC '(' optexpr ')' /* print (@args) */ 911 { $$ = op_convert_list($1, 0, $3); } 912 | LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */ 913 { SvREFCNT_inc_simple_void(PL_compcv); 914 $<opval>$ = newANONATTRSUB($2, 0, NULL, $3); } 915 optlistexpr %prec LSTOP /* ... @bar */ 916 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 917 op_append_elem(OP_LIST, 918 op_prepend_elem(OP_LIST, $<opval>4, $5), $1)); 919 } 920 ; 921 922 /* Names of methods. May use $object->$methodname */ 923 method : METHOD 924 | scalar 925 ; 926 927 /* Some kind of subscripted expression */ 928 subscripted: gelem '{' expr ';' '}' /* *main::{something} */ 929 /* In this and all the hash accessors, ';' is 930 * provided by the tokeniser */ 931 { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3)); } 932 | scalar '[' expr ']' /* $array[$element] */ 933 { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); 934 } 935 | term ARROW '[' expr ']' /* somearef->[$element] */ 936 { $$ = newBINOP(OP_AELEM, 0, 937 ref(newAVREF($1),OP_RV2AV), 938 scalar($4)); 939 } 940 | subscripted '[' expr ']' /* $foo->[$bar]->[$baz] */ 941 { $$ = newBINOP(OP_AELEM, 0, 942 ref(newAVREF($1),OP_RV2AV), 943 scalar($3)); 944 } 945 | scalar '{' expr ';' '}' /* $foo{bar();} */ 946 { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3)); 947 } 948 | term ARROW '{' expr ';' '}' /* somehref->{bar();} */ 949 { $$ = newBINOP(OP_HELEM, 0, 950 ref(newHVREF($1),OP_RV2HV), 951 jmaybe($4)); } 952 | subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */ 953 { $$ = newBINOP(OP_HELEM, 0, 954 ref(newHVREF($1),OP_RV2HV), 955 jmaybe($3)); } 956 | term ARROW '(' ')' /* $subref->() */ 957 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 958 newCVREF(0, scalar($1))); 959 if (parser->expect == XBLOCK) 960 parser->expect = XOPERATOR; 961 } 962 | term ARROW '(' expr ')' /* $subref->(@args) */ 963 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 964 op_append_elem(OP_LIST, $4, 965 newCVREF(0, scalar($1)))); 966 if (parser->expect == XBLOCK) 967 parser->expect = XOPERATOR; 968 } 969 970 | subscripted '(' expr ')' /* $foo->{bar}->(@args) */ 971 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 972 op_append_elem(OP_LIST, $3, 973 newCVREF(0, scalar($1)))); 974 if (parser->expect == XBLOCK) 975 parser->expect = XOPERATOR; 976 } 977 | subscripted '(' ')' /* $foo->{bar}->() */ 978 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 979 newCVREF(0, scalar($1))); 980 if (parser->expect == XBLOCK) 981 parser->expect = XOPERATOR; 982 } 983 | '(' expr ')' '[' expr ']' /* list slice */ 984 { $$ = newSLICEOP(0, $5, $2); } 985 | QWLIST '[' expr ']' /* list literal slice */ 986 { $$ = newSLICEOP(0, $3, $1); } 987 | '(' ')' '[' expr ']' /* empty list slice! */ 988 { $$ = newSLICEOP(0, $4, NULL); } 989 ; 990 991 /* Binary operators between terms */ 992 termbinop: term ASSIGNOP term /* $x = $y, $x += $y */ 993 { $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); } 994 | term POWOP term /* $x ** $y */ 995 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 996 | term MULOP term /* $x * $y, $x x $y */ 997 { if ($2 != OP_REPEAT) 998 scalar($1); 999 $$ = newBINOP($2, 0, $1, scalar($3)); 1000 } 1001 | term ADDOP term /* $x + $y */ 1002 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 1003 | term SHIFTOP term /* $x >> $y, $x << $y */ 1004 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 1005 | term RELOP term /* $x > $y, etc. */ 1006 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 1007 | term EQOP term /* $x == $y, $x eq $y */ 1008 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 1009 | term BITANDOP term /* $x & $y */ 1010 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 1011 | term BITOROP term /* $x | $y */ 1012 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 1013 | term DOTDOT term /* $x..$y, $x...$y */ 1014 { $$ = newRANGE($2, scalar($1), scalar($3)); } 1015 | term ANDAND term /* $x && $y */ 1016 { $$ = newLOGOP(OP_AND, 0, $1, $3); } 1017 | term OROR term /* $x || $y */ 1018 { $$ = newLOGOP(OP_OR, 0, $1, $3); } 1019 | term DORDOR term /* $x // $y */ 1020 { $$ = newLOGOP(OP_DOR, 0, $1, $3); } 1021 | term MATCHOP term /* $x =~ /$y/ */ 1022 { $$ = bind_match($2, $1, $3); } 1023 ; 1024 1025 /* Unary operators and terms */ 1026 termunop : '-' term %prec UMINUS /* -$x */ 1027 { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); } 1028 | '+' term %prec UMINUS /* +$x */ 1029 { $$ = $2; } 1030 1031 | '!' term /* !$x */ 1032 { $$ = newUNOP(OP_NOT, 0, scalar($2)); } 1033 | '~' term /* ~$x */ 1034 { $$ = newUNOP($1, 0, scalar($2)); } 1035 | term POSTINC /* $x++ */ 1036 { $$ = newUNOP(OP_POSTINC, 0, 1037 op_lvalue(scalar($1), OP_POSTINC)); } 1038 | term POSTDEC /* $x-- */ 1039 { $$ = newUNOP(OP_POSTDEC, 0, 1040 op_lvalue(scalar($1), OP_POSTDEC));} 1041 | term POSTJOIN /* implicit join after interpolated ->@ */ 1042 { $$ = op_convert_list(OP_JOIN, 0, 1043 op_append_elem( 1044 OP_LIST, 1045 newSVREF(scalar( 1046 newSVOP(OP_CONST,0, 1047 newSVpvs("\"")) 1048 )), 1049 $1 1050 )); 1051 } 1052 | PREINC term /* ++$x */ 1053 { $$ = newUNOP(OP_PREINC, 0, 1054 op_lvalue(scalar($2), OP_PREINC)); } 1055 | PREDEC term /* --$x */ 1056 { $$ = newUNOP(OP_PREDEC, 0, 1057 op_lvalue(scalar($2), OP_PREDEC)); } 1058 1059 ; 1060 1061 /* Constructors for anonymous data */ 1062 anonymous: '[' expr ']' 1063 { $$ = newANONLIST($2); } 1064 | '[' ']' 1065 { $$ = newANONLIST(NULL);} 1066 | HASHBRACK expr ';' '}' %prec '(' /* { foo => "Bar" } */ 1067 { $$ = newANONHASH($2); } 1068 | HASHBRACK ';' '}' %prec '(' /* { } (';' by tokener) */ 1069 { $$ = newANONHASH(NULL); } 1070 | ANONSUB startanonsub proto subattrlist subbody %prec '(' 1071 { SvREFCNT_inc_simple_void(PL_compcv); 1072 $$ = newANONATTRSUB($2, $3, $4, $5); } 1073 | ANON_SIGSUB startanonsub subattrlist sigsubbody %prec '(' 1074 { SvREFCNT_inc_simple_void(PL_compcv); 1075 $$ = newANONATTRSUB($2, NULL, $3, $4); } 1076 ; 1077 1078 /* Things called with "do" */ 1079 termdo : DO term %prec UNIOP /* do $filename */ 1080 { $$ = dofile($2, $1);} 1081 | DO block %prec '(' /* do { code */ 1082 { $$ = newUNOP(OP_NULL, OPf_SPECIAL, op_scope($2));} 1083 ; 1084 1085 term : termbinop 1086 | termunop 1087 | anonymous 1088 | termdo 1089 | term '?' term ':' term 1090 { $$ = newCONDOP(0, $1, $3, $5); } 1091 | REFGEN term /* \$x, \@y, \%z */ 1092 { $$ = newUNOP(OP_REFGEN, 0, $2); } 1093 | MY REFGEN term 1094 { $$ = newUNOP(OP_REFGEN, 0, localize($3,1)); } 1095 | myattrterm %prec UNIOP 1096 { $$ = $1; } 1097 | LOCAL term %prec UNIOP 1098 { $$ = localize($2,0); } 1099 | '(' expr ')' 1100 { $$ = sawparens($2); } 1101 | QWLIST 1102 { $$ = $1; } 1103 | '(' ')' 1104 { $$ = sawparens(newNULLLIST()); } 1105 | scalar %prec '(' 1106 { $$ = $1; } 1107 | star %prec '(' 1108 { $$ = $1; } 1109 | hsh %prec '(' 1110 { $$ = $1; } 1111 | ary %prec '(' 1112 { $$ = $1; } 1113 | arylen %prec '(' /* $#x, $#{ something } */ 1114 { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));} 1115 | subscripted 1116 { $$ = $1; } 1117 | sliceme '[' expr ']' /* array slice */ 1118 { $$ = op_prepend_elem(OP_ASLICE, 1119 newOP(OP_PUSHMARK, 0), 1120 newLISTOP(OP_ASLICE, 0, 1121 list($3), 1122 ref($1, OP_ASLICE))); 1123 if ($$ && $1) 1124 $$->op_private |= 1125 $1->op_private & OPpSLICEWARNING; 1126 } 1127 | kvslice '[' expr ']' /* array key/value slice */ 1128 { $$ = op_prepend_elem(OP_KVASLICE, 1129 newOP(OP_PUSHMARK, 0), 1130 newLISTOP(OP_KVASLICE, 0, 1131 list($3), 1132 ref(oopsAV($1), OP_KVASLICE))); 1133 if ($$ && $1) 1134 $$->op_private |= 1135 $1->op_private & OPpSLICEWARNING; 1136 } 1137 | sliceme '{' expr ';' '}' /* @hash{@keys} */ 1138 { $$ = op_prepend_elem(OP_HSLICE, 1139 newOP(OP_PUSHMARK, 0), 1140 newLISTOP(OP_HSLICE, 0, 1141 list($3), 1142 ref(oopsHV($1), OP_HSLICE))); 1143 if ($$ && $1) 1144 $$->op_private |= 1145 $1->op_private & OPpSLICEWARNING; 1146 } 1147 | kvslice '{' expr ';' '}' /* %hash{@keys} */ 1148 { $$ = op_prepend_elem(OP_KVHSLICE, 1149 newOP(OP_PUSHMARK, 0), 1150 newLISTOP(OP_KVHSLICE, 0, 1151 list($3), 1152 ref($1, OP_KVHSLICE))); 1153 if ($$ && $1) 1154 $$->op_private |= 1155 $1->op_private & OPpSLICEWARNING; 1156 } 1157 | THING %prec '(' 1158 { $$ = $1; } 1159 | amper /* &foo; */ 1160 { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); } 1161 | amper '(' ')' /* &foo() or foo() */ 1162 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); 1163 } 1164 | amper '(' expr ')' /* &foo(@args) or foo(@args) */ 1165 { 1166 $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 1167 op_append_elem(OP_LIST, $3, scalar($1))); 1168 } 1169 | NOAMP subname optlistexpr /* foo @args (no parens) */ 1170 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 1171 op_append_elem(OP_LIST, $3, scalar($2))); 1172 } 1173 | term ARROW '$' '*' 1174 { $$ = newSVREF($1); } 1175 | term ARROW '@' '*' 1176 { $$ = newAVREF($1); } 1177 | term ARROW '%' '*' 1178 { $$ = newHVREF($1); } 1179 | term ARROW '&' '*' 1180 { $$ = newUNOP(OP_ENTERSUB, 0, 1181 scalar(newCVREF($3,$1))); } 1182 | term ARROW '*' '*' %prec '(' 1183 { $$ = newGVREF(0,$1); } 1184 | LOOPEX /* loop exiting command (goto, last, dump, etc) */ 1185 { $$ = newOP($1, OPf_SPECIAL); 1186 PL_hints |= HINT_BLOCK_SCOPE; } 1187 | LOOPEX term 1188 { $$ = newLOOPEX($1,$2); } 1189 | NOTOP listexpr /* not $foo */ 1190 { $$ = newUNOP(OP_NOT, 0, scalar($2)); } 1191 | UNIOP /* Unary op, $_ implied */ 1192 { $$ = newOP($1, 0); } 1193 | UNIOP block /* eval { foo }* */ 1194 { $$ = newUNOP($1, 0, $2); } 1195 | UNIOP term /* Unary op */ 1196 { $$ = newUNOP($1, 0, $2); } 1197 | REQUIRE /* require, $_ implied */ 1198 { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0); } 1199 | REQUIRE term /* require Foo */ 1200 { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2); } 1201 | UNIOPSUB 1202 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); } 1203 | UNIOPSUB term /* Sub treated as unop */ 1204 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 1205 op_append_elem(OP_LIST, $2, scalar($1))); } 1206 | FUNC0 /* Nullary operator */ 1207 { $$ = newOP($1, 0); } 1208 | FUNC0 '(' ')' 1209 { $$ = newOP($1, 0);} 1210 | FUNC0OP /* Same as above, but op created in toke.c */ 1211 { $$ = $1; } 1212 | FUNC0OP '(' ')' 1213 { $$ = $1; } 1214 | FUNC0SUB /* Sub treated as nullop */ 1215 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); } 1216 | FUNC1 '(' ')' /* not () */ 1217 { $$ = ($1 == OP_NOT) 1218 ? newUNOP($1, 0, newSVOP(OP_CONST, 0, newSViv(0))) 1219 : newOP($1, OPf_SPECIAL); } 1220 | FUNC1 '(' expr ')' /* not($foo) */ 1221 { $$ = newUNOP($1, 0, $3); } 1222 | PMFUNC /* m//, s///, qr//, tr/// */ 1223 { 1224 if ( $1->op_type != OP_TRANS 1225 && $1->op_type != OP_TRANSR 1226 && (((PMOP*)$1)->op_pmflags & PMf_HAS_CV)) 1227 { 1228 $<ival>$ = start_subparse(FALSE, CVf_ANON); 1229 SAVEFREESV(PL_compcv); 1230 } else 1231 $<ival>$ = 0; 1232 } 1233 '(' listexpr optrepl ')' 1234 { $$ = pmruntime($1, $4, $5, 1, $<ival>2); } 1235 | BAREWORD 1236 | listop 1237 | PLUGEXPR 1238 ; 1239 1240 /* "my" declarations, with optional attributes */ 1241 myattrterm: MY myterm myattrlist 1242 { $$ = my_attrs($2,$3); } 1243 | MY myterm 1244 { $$ = localize($2,1); } 1245 | MY REFGEN myterm myattrlist 1246 { $$ = newUNOP(OP_REFGEN, 0, my_attrs($3,$4)); } 1247 ; 1248 1249 /* Things that can be "my"'d */ 1250 myterm : '(' expr ')' 1251 { $$ = sawparens($2); } 1252 | '(' ')' 1253 { $$ = sawparens(newNULLLIST()); } 1254 1255 | scalar %prec '(' 1256 { $$ = $1; } 1257 | hsh %prec '(' 1258 { $$ = $1; } 1259 | ary %prec '(' 1260 { $$ = $1; } 1261 ; 1262 1263 /* Basic list expressions */ 1264 optlistexpr: /* NULL */ %prec PREC_LOW 1265 { $$ = NULL; } 1266 | listexpr %prec PREC_LOW 1267 { $$ = $1; } 1268 ; 1269 1270 optexpr: /* NULL */ 1271 { $$ = NULL; } 1272 | expr 1273 { $$ = $1; } 1274 ; 1275 1276 optrepl: /* NULL */ 1277 { $$ = NULL; } 1278 | '/' expr 1279 { $$ = $2; } 1280 ; 1281 1282 /* A little bit of trickery to make "for my $foo (@bar)" actually be 1283 lexical */ 1284 my_scalar: scalar 1285 { parser->in_my = 0; $$ = my($1); } 1286 ; 1287 1288 my_var : scalar 1289 | ary 1290 | hsh 1291 ; 1292 1293 refgen_topic: my_var 1294 | amper 1295 ; 1296 1297 my_refgen: MY REFGEN 1298 | REFGEN MY 1299 ; 1300 1301 amper : '&' indirob 1302 { $$ = newCVREF($1,$2); } 1303 ; 1304 1305 scalar : '$' indirob 1306 { $$ = newSVREF($2); } 1307 ; 1308 1309 ary : '@' indirob 1310 { $$ = newAVREF($2); 1311 if ($$) $$->op_private |= $1; 1312 } 1313 ; 1314 1315 hsh : '%' indirob 1316 { $$ = newHVREF($2); 1317 if ($$) $$->op_private |= $1; 1318 } 1319 ; 1320 1321 arylen : DOLSHARP indirob 1322 { $$ = newAVREF($2); } 1323 | term ARROW DOLSHARP '*' 1324 { $$ = newAVREF($1); } 1325 ; 1326 1327 star : '*' indirob 1328 { $$ = newGVREF(0,$2); } 1329 ; 1330 1331 sliceme : ary 1332 | term ARROW '@' 1333 { $$ = newAVREF($1); } 1334 ; 1335 1336 kvslice : hsh 1337 | term ARROW '%' 1338 { $$ = newHVREF($1); } 1339 ; 1340 1341 gelem : star 1342 | term ARROW '*' 1343 { $$ = newGVREF(0,$1); } 1344 ; 1345 1346 /* Indirect objects */ 1347 indirob : BAREWORD 1348 { $$ = scalar($1); } 1349 | scalar %prec PREC_LOW 1350 { $$ = scalar($1); } 1351 | block 1352 { $$ = op_scope($1); } 1353 1354 | PRIVATEREF 1355 { $$ = $1; } 1356 ; 1357