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> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF QWLIST 51 %token <opval> FUNC0OP FUNC0SUB UNIOPSUB LSTOPSUB 52 %token <opval> PLUGEXPR PLUGSTMT 53 %token <pval> LABEL 54 %token <ival> FORMAT SUB ANONSUB 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 optsubbody cont my_scalar my_var 75 %type <opval> refgen_topic formblock 76 %type <opval> subattrlist myattrlist myattrterm myterm 77 %type <opval> subsignature termbinop termunop anonymous termdo 78 %type <opval> formstmtseq formline formarg 79 80 %nonassoc <ival> PREC_LOW 81 %nonassoc LOOPEX 82 83 %left <ival> OROP DOROP 84 %left <ival> ANDOP 85 %right <ival> NOTOP 86 %nonassoc LSTOP LSTOPSUB 87 %left <ival> ',' 88 %right <ival> ASSIGNOP 89 %right <ival> '?' ':' 90 %nonassoc DOTDOT YADAYADA 91 %left <ival> OROR DORDOR 92 %left <ival> ANDAND 93 %left <ival> BITOROP 94 %left <ival> BITANDOP 95 %nonassoc EQOP 96 %nonassoc RELOP 97 %nonassoc UNIOP UNIOPSUB 98 %nonassoc REQUIRE 99 %left <ival> SHIFTOP 100 %left ADDOP 101 %left MULOP 102 %left <ival> MATCHOP 103 %right <ival> '!' '~' UMINUS REFGEN 104 %right <ival> POWOP 105 %nonassoc <ival> PREINC PREDEC POSTINC POSTDEC POSTJOIN 106 %left <ival> ARROW 107 %nonassoc <ival> ')' 108 %left <ival> '(' 109 %left '[' '{' 110 111 %% /* RULES */ 112 113 /* Top-level choice of what kind of thing yyparse was called to parse */ 114 grammar : GRAMPROG 115 { 116 parser->expect = XSTATE; 117 } 118 remember stmtseq 119 { 120 newPROG(block_end($3,$4)); 121 PL_compiling.cop_seq = 0; 122 $$ = 0; 123 } 124 | GRAMEXPR 125 { 126 parser->expect = XTERM; 127 } 128 optexpr 129 { 130 PL_eval_root = $3; 131 $$ = 0; 132 } 133 | GRAMBLOCK 134 { 135 parser->expect = XBLOCK; 136 } 137 block 138 { 139 PL_pad_reset_pending = TRUE; 140 PL_eval_root = $3; 141 $$ = 0; 142 yyunlex(); 143 parser->yychar = YYEOF; 144 } 145 | GRAMBARESTMT 146 { 147 parser->expect = XSTATE; 148 } 149 barestmt 150 { 151 PL_pad_reset_pending = TRUE; 152 PL_eval_root = $3; 153 $$ = 0; 154 yyunlex(); 155 parser->yychar = YYEOF; 156 } 157 | GRAMFULLSTMT 158 { 159 parser->expect = XSTATE; 160 } 161 fullstmt 162 { 163 PL_pad_reset_pending = TRUE; 164 PL_eval_root = $3; 165 $$ = 0; 166 yyunlex(); 167 parser->yychar = YYEOF; 168 } 169 | GRAMSTMTSEQ 170 { 171 parser->expect = XSTATE; 172 } 173 stmtseq 174 { 175 PL_eval_root = $3; 176 $$ = 0; 177 } 178 ; 179 180 /* An ordinary block */ 181 block : '{' remember stmtseq '}' 182 { if (parser->copline > (line_t)$1) 183 parser->copline = (line_t)$1; 184 $$ = block_end($2, $3); 185 } 186 ; 187 188 /* format body */ 189 formblock: '=' remember ';' FORMRBRACK formstmtseq ';' '.' 190 { if (parser->copline > (line_t)$1) 191 parser->copline = (line_t)$1; 192 $$ = block_end($2, $5); 193 } 194 ; 195 196 remember: /* NULL */ /* start a full lexical scope */ 197 { $$ = block_start(TRUE); 198 parser->parsed_sub = 0; } 199 ; 200 201 mblock : '{' mremember stmtseq '}' 202 { if (parser->copline > (line_t)$1) 203 parser->copline = (line_t)$1; 204 $$ = block_end($2, $3); 205 } 206 ; 207 208 mremember: /* NULL */ /* start a partial lexical scope */ 209 { $$ = block_start(FALSE); 210 parser->parsed_sub = 0; } 211 ; 212 213 /* A sequence of statements in the program */ 214 stmtseq : /* NULL */ 215 { $$ = (OP*)NULL; } 216 | stmtseq fullstmt 217 { $$ = op_append_list(OP_LINESEQ, $1, $2); 218 PL_pad_reset_pending = TRUE; 219 if ($1 && $2) 220 PL_hints |= HINT_BLOCK_SCOPE; 221 } 222 ; 223 224 /* A sequence of format lines */ 225 formstmtseq: /* NULL */ 226 { $$ = (OP*)NULL; } 227 | formstmtseq formline 228 { $$ = op_append_list(OP_LINESEQ, $1, $2); 229 PL_pad_reset_pending = TRUE; 230 if ($1 && $2) 231 PL_hints |= HINT_BLOCK_SCOPE; 232 } 233 ; 234 235 /* A statement in the program, including optional labels */ 236 fullstmt: barestmt 237 { 238 $$ = $1 ? newSTATEOP(0, NULL, $1) : NULL; 239 } 240 | labfullstmt 241 { $$ = $1; } 242 ; 243 244 labfullstmt: LABEL barestmt 245 { 246 $$ = newSTATEOP(SVf_UTF8 * $1[strlen($1)+1], $1, $2); 247 } 248 | LABEL labfullstmt 249 { 250 $$ = newSTATEOP(SVf_UTF8 * $1[strlen($1)+1], $1, $2); 251 } 252 ; 253 254 /* A bare statement, lacking label and other aspects of state op */ 255 barestmt: PLUGSTMT 256 { $$ = $1; } 257 | FORMAT startformsub formname formblock 258 { 259 CV *fmtcv = PL_compcv; 260 newFORM($2, $3, $4); 261 $$ = (OP*)NULL; 262 if (CvOUTSIDE(fmtcv) && !CvEVAL(CvOUTSIDE(fmtcv))) { 263 pad_add_weakref(fmtcv); 264 } 265 parser->parsed_sub = 1; 266 } 267 | SUB subname startsub 268 { 269 if ($2->op_type == OP_CONST) { 270 const char *const name = 271 SvPV_nolen_const(((SVOP*)$2)->op_sv); 272 if (strEQ(name, "BEGIN") || strEQ(name, "END") 273 || strEQ(name, "INIT") || strEQ(name, "CHECK") 274 || strEQ(name, "UNITCHECK")) 275 CvSPECIAL_on(PL_compcv); 276 } 277 else 278 /* State subs inside anonymous subs need to be 279 clonable themselves. */ 280 if (CvANON(CvOUTSIDE(PL_compcv)) 281 || CvCLONE(CvOUTSIDE(PL_compcv)) 282 || !PadnameIsSTATE(PadlistNAMESARRAY(CvPADLIST( 283 CvOUTSIDE(PL_compcv) 284 ))[$2->op_targ])) 285 CvCLONE_on(PL_compcv); 286 parser->in_my = 0; 287 parser->in_my_stash = NULL; 288 } 289 proto subattrlist optsubbody 290 { 291 SvREFCNT_inc_simple_void(PL_compcv); 292 $2->op_type == OP_CONST 293 ? newATTRSUB($3, $2, $5, $6, $7) 294 : newMYSUB($3, $2, $5, $6, $7) 295 ; 296 $$ = (OP*)NULL; 297 intro_my(); 298 parser->parsed_sub = 1; 299 } 300 | SUB subname startsub 301 { 302 if ($2->op_type == OP_CONST) { 303 const char *const name = 304 SvPV_nolen_const(((SVOP*)$2)->op_sv); 305 if (strEQ(name, "BEGIN") || strEQ(name, "END") 306 || strEQ(name, "INIT") || strEQ(name, "CHECK") 307 || strEQ(name, "UNITCHECK")) 308 CvSPECIAL_on(PL_compcv); 309 } 310 else 311 /* State subs inside anonymous subs need to be 312 clonable themselves. */ 313 if (CvANON(CvOUTSIDE(PL_compcv)) 314 || CvCLONE(CvOUTSIDE(PL_compcv)) 315 || !PadnameIsSTATE(PadlistNAMESARRAY(CvPADLIST( 316 CvOUTSIDE(PL_compcv) 317 ))[$2->op_targ])) 318 CvCLONE_on(PL_compcv); 319 parser->in_my = 0; 320 parser->in_my_stash = NULL; 321 } 322 remember subsignature subattrlist '{' stmtseq '}' 323 { 324 OP *body; 325 if (parser->copline > (line_t)$8) 326 parser->copline = (line_t)$8; 327 body = block_end($5, 328 op_append_list(OP_LINESEQ, $6, $9)); 329 330 SvREFCNT_inc_simple_void(PL_compcv); 331 $2->op_type == OP_CONST 332 ? newATTRSUB($3, $2, NULL, $7, body) 333 : newMYSUB($3, $2, NULL, $7, body) 334 ; 335 $$ = (OP*)NULL; 336 intro_my(); 337 parser->parsed_sub = 1; 338 } 339 | PACKAGE WORD WORD ';' 340 { 341 package($3); 342 if ($2) 343 package_version($2); 344 $$ = (OP*)NULL; 345 } 346 | USE startsub 347 { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ } 348 WORD WORD optlistexpr ';' 349 { 350 SvREFCNT_inc_simple_void(PL_compcv); 351 utilize($1, $2, $4, $5, $6); 352 parser->parsed_sub = 1; 353 $$ = (OP*)NULL; 354 } 355 | IF '(' remember mexpr ')' mblock else 356 { 357 $$ = block_end($3, 358 newCONDOP(0, $4, op_scope($6), $7)); 359 parser->copline = (line_t)$1; 360 } 361 | UNLESS '(' remember mexpr ')' mblock else 362 { 363 $$ = block_end($3, 364 newCONDOP(0, $4, $7, op_scope($6))); 365 parser->copline = (line_t)$1; 366 } 367 | GIVEN '(' remember mexpr ')' mblock 368 { 369 $$ = block_end($3, newGIVENOP($4, op_scope($6), 0)); 370 parser->copline = (line_t)$1; 371 } 372 | WHEN '(' remember mexpr ')' mblock 373 { $$ = block_end($3, newWHENOP($4, op_scope($6))); } 374 | DEFAULT block 375 { $$ = newWHENOP(0, op_scope($2)); } 376 | WHILE '(' remember texpr ')' mintro mblock cont 377 { 378 $$ = block_end($3, 379 newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 380 $4, $7, $8, $6)); 381 parser->copline = (line_t)$1; 382 } 383 | UNTIL '(' remember iexpr ')' mintro mblock cont 384 { 385 $$ = block_end($3, 386 newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 387 $4, $7, $8, $6)); 388 parser->copline = (line_t)$1; 389 } 390 | FOR '(' remember mnexpr ';' 391 { parser->expect = XTERM; } 392 texpr ';' 393 { parser->expect = XTERM; } 394 mintro mnexpr ')' 395 mblock 396 { 397 OP *initop = $4; 398 OP *forop = newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 399 scalar($7), $13, $11, $10); 400 if (initop) { 401 forop = op_prepend_elem(OP_LINESEQ, initop, 402 op_append_elem(OP_LINESEQ, 403 newOP(OP_UNSTACK, OPf_SPECIAL), 404 forop)); 405 } 406 PL_hints |= HINT_BLOCK_SCOPE; 407 $$ = block_end($3, forop); 408 parser->copline = (line_t)$1; 409 } 410 | FOR MY remember my_scalar '(' mexpr ')' mblock cont 411 { 412 $$ = block_end($3, newFOROP(0, $4, $6, $8, $9)); 413 parser->copline = (line_t)$1; 414 } 415 | FOR scalar '(' remember mexpr ')' mblock cont 416 { 417 $$ = block_end($4, newFOROP(0, 418 op_lvalue($2, OP_ENTERLOOP), $5, $7, $8)); 419 parser->copline = (line_t)$1; 420 } 421 | FOR REFGEN MY remember my_var 422 { parser->in_my = 0; $<opval>$ = my($5); } 423 '(' mexpr ')' mblock cont 424 { 425 $$ = block_end( 426 $4, 427 newFOROP(0, 428 op_lvalue( 429 newUNOP(OP_REFGEN, 0, 430 $<opval>6), 431 OP_ENTERLOOP), 432 $8, $10, $11) 433 ); 434 parser->copline = (line_t)$1; 435 } 436 | FOR REFGEN refgen_topic '(' remember mexpr ')' mblock cont 437 { 438 $$ = block_end($5, newFOROP( 439 0, op_lvalue(newUNOP(OP_REFGEN, 0, 440 $3), 441 OP_ENTERLOOP), $6, $8, $9)); 442 parser->copline = (line_t)$1; 443 } 444 | FOR '(' remember mexpr ')' mblock cont 445 { 446 $$ = block_end($3, 447 newFOROP(0, (OP*)NULL, $4, $6, $7)); 448 parser->copline = (line_t)$1; 449 } 450 | block cont 451 { 452 /* a block is a loop that happens once */ 453 $$ = newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 454 (OP*)NULL, $1, $2, 0); 455 } 456 | PACKAGE WORD WORD '{' remember 457 { 458 package($3); 459 if ($2) { 460 package_version($2); 461 } 462 } 463 stmtseq '}' 464 { 465 /* a block is a loop that happens once */ 466 $$ = newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 467 (OP*)NULL, block_end($5, $7), (OP*)NULL, 0); 468 if (parser->copline > (line_t)$4) 469 parser->copline = (line_t)$4; 470 } 471 | sideff ';' 472 { 473 $$ = $1; 474 } 475 | ';' 476 { 477 $$ = (OP*)NULL; 478 parser->copline = NOLINE; 479 } 480 ; 481 482 /* Format line */ 483 formline: THING formarg 484 { OP *list; 485 if ($2) { 486 OP *term = $2; 487 list = op_append_elem(OP_LIST, $1, term); 488 } 489 else { 490 list = $1; 491 } 492 if (parser->copline == NOLINE) 493 parser->copline = CopLINE(PL_curcop)-1; 494 else parser->copline--; 495 $$ = newSTATEOP(0, NULL, 496 op_convert_list(OP_FORMLINE, 0, list)); 497 } 498 ; 499 500 formarg : /* NULL */ 501 { $$ = NULL; } 502 | FORMLBRACK stmtseq FORMRBRACK 503 { $$ = op_unscope($2); } 504 ; 505 506 /* An expression which may have a side-effect */ 507 sideff : error 508 { $$ = (OP*)NULL; } 509 | expr 510 { $$ = $1; } 511 | expr IF expr 512 { $$ = newLOGOP(OP_AND, 0, $3, $1); } 513 | expr UNLESS expr 514 { $$ = newLOGOP(OP_OR, 0, $3, $1); } 515 | expr WHILE expr 516 { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); } 517 | expr UNTIL iexpr 518 { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1); } 519 | expr FOR expr 520 { $$ = newFOROP(0, (OP*)NULL, $3, $1, (OP*)NULL); 521 parser->copline = (line_t)$2; } 522 | expr WHEN expr 523 { $$ = newWHENOP($3, op_scope($1)); } 524 ; 525 526 /* else and elsif blocks */ 527 else : /* NULL */ 528 { $$ = (OP*)NULL; } 529 | ELSE mblock 530 { 531 ($2)->op_flags |= OPf_PARENS; 532 $$ = op_scope($2); 533 } 534 | ELSIF '(' mexpr ')' mblock else 535 { parser->copline = (line_t)$1; 536 $$ = newCONDOP(0, 537 newSTATEOP(OPf_SPECIAL,NULL,$3), 538 op_scope($5), $6); 539 PL_hints |= HINT_BLOCK_SCOPE; 540 } 541 ; 542 543 /* Continue blocks */ 544 cont : /* NULL */ 545 { $$ = (OP*)NULL; } 546 | CONTINUE block 547 { $$ = op_scope($2); } 548 ; 549 550 /* determine whether there are any new my declarations */ 551 mintro : /* NULL */ 552 { $$ = (PL_min_intro_pending && 553 PL_max_intro_pending >= PL_min_intro_pending); 554 intro_my(); } 555 556 /* Normal expression */ 557 nexpr : /* NULL */ 558 { $$ = (OP*)NULL; } 559 | sideff 560 ; 561 562 /* Boolean expression */ 563 texpr : /* NULL means true */ 564 { YYSTYPE tmplval; 565 (void)scan_num("1", &tmplval); 566 $$ = tmplval.opval; } 567 | expr 568 ; 569 570 /* Inverted boolean expression */ 571 iexpr : expr 572 { $$ = invert(scalar($1)); } 573 ; 574 575 /* Expression with its own lexical scope */ 576 mexpr : expr 577 { $$ = $1; intro_my(); } 578 ; 579 580 mnexpr : nexpr 581 { $$ = $1; intro_my(); } 582 ; 583 584 formname: WORD { $$ = $1; } 585 | /* NULL */ { $$ = (OP*)NULL; } 586 ; 587 588 startsub: /* NULL */ /* start a regular subroutine scope */ 589 { $$ = start_subparse(FALSE, 0); 590 SAVEFREESV(PL_compcv); } 591 592 ; 593 594 startanonsub: /* NULL */ /* start an anonymous subroutine scope */ 595 { $$ = start_subparse(FALSE, CVf_ANON); 596 SAVEFREESV(PL_compcv); } 597 ; 598 599 startformsub: /* NULL */ /* start a format subroutine scope */ 600 { $$ = start_subparse(TRUE, 0); 601 SAVEFREESV(PL_compcv); } 602 ; 603 604 /* Name of a subroutine - must be a bareword, could be special */ 605 subname : WORD 606 | PRIVATEREF 607 ; 608 609 /* Subroutine prototype */ 610 proto : /* NULL */ 611 { $$ = (OP*)NULL; } 612 | THING 613 ; 614 615 /* Optional list of subroutine attributes */ 616 subattrlist: /* NULL */ 617 { $$ = (OP*)NULL; } 618 | COLONATTR THING 619 { $$ = $2; } 620 | COLONATTR 621 { $$ = (OP*)NULL; } 622 ; 623 624 /* List of attributes for a "my" variable declaration */ 625 myattrlist: COLONATTR THING 626 { $$ = $2; } 627 | COLONATTR 628 { $$ = (OP*)NULL; } 629 ; 630 631 /* Subroutine signature */ 632 subsignature: '(' 633 { 634 /* We shouldn't get here otherwise */ 635 assert(FEATURE_SIGNATURES_IS_ENABLED); 636 637 Perl_ck_warner_d(aTHX_ 638 packWARN(WARN_EXPERIMENTAL__SIGNATURES), 639 "The signatures feature is experimental"); 640 $<opval>$ = parse_subsignature(); 641 } 642 ')' 643 { 644 $$ = op_append_list(OP_LINESEQ, $<opval>2, 645 newSTATEOP(0, NULL, sawparens(newNULLLIST()))); 646 parser->expect = XATTRBLOCK; 647 } 648 ; 649 650 /* Optional subroutine body, for named subroutine declaration */ 651 optsubbody: block 652 | ';' { $$ = (OP*)NULL; } 653 ; 654 655 /* Ordinary expressions; logical combinations */ 656 expr : expr ANDOP expr 657 { $$ = newLOGOP(OP_AND, 0, $1, $3); } 658 | expr OROP expr 659 { $$ = newLOGOP($2, 0, $1, $3); } 660 | expr DOROP expr 661 { $$ = newLOGOP(OP_DOR, 0, $1, $3); } 662 | listexpr %prec PREC_LOW 663 ; 664 665 /* Expressions are a list of terms joined by commas */ 666 listexpr: listexpr ',' 667 { $$ = $1; } 668 | listexpr ',' term 669 { 670 OP* term = $3; 671 $$ = op_append_elem(OP_LIST, $1, term); 672 } 673 | term %prec PREC_LOW 674 ; 675 676 /* List operators */ 677 listop : LSTOP indirob listexpr /* map {...} @args or print $fh @args */ 678 { $$ = op_convert_list($1, OPf_STACKED, 679 op_prepend_elem(OP_LIST, newGVREF($1,$2), $3) ); 680 } 681 | FUNC '(' indirob expr ')' /* print ($fh @args */ 682 { $$ = op_convert_list($1, OPf_STACKED, 683 op_prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); 684 } 685 | term ARROW method '(' optexpr ')' /* $foo->bar(list) */ 686 { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, 687 op_append_elem(OP_LIST, 688 op_prepend_elem(OP_LIST, scalar($1), $5), 689 newMETHOP(OP_METHOD, 0, $3))); 690 } 691 | term ARROW method /* $foo->bar */ 692 { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, 693 op_append_elem(OP_LIST, scalar($1), 694 newMETHOP(OP_METHOD, 0, $3))); 695 } 696 | METHOD indirob optlistexpr /* new Class @args */ 697 { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, 698 op_append_elem(OP_LIST, 699 op_prepend_elem(OP_LIST, $2, $3), 700 newMETHOP(OP_METHOD, 0, $1))); 701 } 702 | FUNCMETH indirob '(' optexpr ')' /* method $object (@args) */ 703 { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED, 704 op_append_elem(OP_LIST, 705 op_prepend_elem(OP_LIST, $2, $4), 706 newMETHOP(OP_METHOD, 0, $1))); 707 } 708 | LSTOP optlistexpr /* print @args */ 709 { $$ = op_convert_list($1, 0, $2); } 710 | FUNC '(' optexpr ')' /* print (@args) */ 711 { $$ = op_convert_list($1, 0, $3); } 712 | LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */ 713 { SvREFCNT_inc_simple_void(PL_compcv); 714 $<opval>$ = newANONATTRSUB($2, 0, (OP*)NULL, $3); } 715 optlistexpr %prec LSTOP /* ... @bar */ 716 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 717 op_append_elem(OP_LIST, 718 op_prepend_elem(OP_LIST, $<opval>4, $5), $1)); 719 } 720 ; 721 722 /* Names of methods. May use $object->$methodname */ 723 method : METHOD 724 | scalar 725 ; 726 727 /* Some kind of subscripted expression */ 728 subscripted: gelem '{' expr ';' '}' /* *main::{something} */ 729 /* In this and all the hash accessors, ';' is 730 * provided by the tokeniser */ 731 { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3)); } 732 | scalar '[' expr ']' /* $array[$element] */ 733 { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); 734 } 735 | term ARROW '[' expr ']' /* somearef->[$element] */ 736 { $$ = newBINOP(OP_AELEM, 0, 737 ref(newAVREF($1),OP_RV2AV), 738 scalar($4)); 739 } 740 | subscripted '[' expr ']' /* $foo->[$bar]->[$baz] */ 741 { $$ = newBINOP(OP_AELEM, 0, 742 ref(newAVREF($1),OP_RV2AV), 743 scalar($3)); 744 } 745 | scalar '{' expr ';' '}' /* $foo{bar();} */ 746 { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3)); 747 } 748 | term ARROW '{' expr ';' '}' /* somehref->{bar();} */ 749 { $$ = newBINOP(OP_HELEM, 0, 750 ref(newHVREF($1),OP_RV2HV), 751 jmaybe($4)); } 752 | subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */ 753 { $$ = newBINOP(OP_HELEM, 0, 754 ref(newHVREF($1),OP_RV2HV), 755 jmaybe($3)); } 756 | term ARROW '(' ')' /* $subref->() */ 757 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 758 newCVREF(0, scalar($1))); } 759 | term ARROW '(' expr ')' /* $subref->(@args) */ 760 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 761 op_append_elem(OP_LIST, $4, 762 newCVREF(0, scalar($1)))); } 763 764 | subscripted '(' expr ')' /* $foo->{bar}->(@args) */ 765 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 766 op_append_elem(OP_LIST, $3, 767 newCVREF(0, scalar($1)))); } 768 | subscripted '(' ')' /* $foo->{bar}->() */ 769 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 770 newCVREF(0, scalar($1))); } 771 | '(' expr ')' '[' expr ']' /* list slice */ 772 { $$ = newSLICEOP(0, $5, $2); } 773 | QWLIST '[' expr ']' /* list literal slice */ 774 { $$ = newSLICEOP(0, $3, $1); } 775 | '(' ')' '[' expr ']' /* empty list slice! */ 776 { $$ = newSLICEOP(0, $4, (OP*)NULL); } 777 ; 778 779 /* Binary operators between terms */ 780 termbinop: term ASSIGNOP term /* $x = $y */ 781 { $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); } 782 | term POWOP term /* $x ** $y */ 783 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 784 | term MULOP term /* $x * $y, $x x $y */ 785 { if ($2 != OP_REPEAT) 786 scalar($1); 787 $$ = newBINOP($2, 0, $1, scalar($3)); 788 } 789 | term ADDOP term /* $x + $y */ 790 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 791 | term SHIFTOP term /* $x >> $y, $x << $y */ 792 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 793 | term RELOP term /* $x > $y, etc. */ 794 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 795 | term EQOP term /* $x == $y, $x eq $y */ 796 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 797 | term BITANDOP term /* $x & $y */ 798 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 799 | term BITOROP term /* $x | $y */ 800 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 801 | term DOTDOT term /* $x..$y, $x...$y */ 802 { $$ = newRANGE($2, scalar($1), scalar($3)); } 803 | term ANDAND term /* $x && $y */ 804 { $$ = newLOGOP(OP_AND, 0, $1, $3); } 805 | term OROR term /* $x || $y */ 806 { $$ = newLOGOP(OP_OR, 0, $1, $3); } 807 | term DORDOR term /* $x // $y */ 808 { $$ = newLOGOP(OP_DOR, 0, $1, $3); } 809 | term MATCHOP term /* $x =~ /$y/ */ 810 { $$ = bind_match($2, $1, $3); } 811 ; 812 813 /* Unary operators and terms */ 814 termunop : '-' term %prec UMINUS /* -$x */ 815 { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); } 816 | '+' term %prec UMINUS /* +$x */ 817 { $$ = $2; } 818 819 | '!' term /* !$x */ 820 { $$ = newUNOP(OP_NOT, 0, scalar($2)); } 821 | '~' term /* ~$x */ 822 { $$ = newUNOP($1, 0, scalar($2)); } 823 | term POSTINC /* $x++ */ 824 { $$ = newUNOP(OP_POSTINC, 0, 825 op_lvalue(scalar($1), OP_POSTINC)); } 826 | term POSTDEC /* $x-- */ 827 { $$ = newUNOP(OP_POSTDEC, 0, 828 op_lvalue(scalar($1), OP_POSTDEC));} 829 | term POSTJOIN /* implicit join after interpolated ->@ */ 830 { $$ = op_convert_list(OP_JOIN, 0, 831 op_append_elem( 832 OP_LIST, 833 newSVREF(scalar( 834 newSVOP(OP_CONST,0, 835 newSVpvs("\"")) 836 )), 837 $1 838 )); 839 } 840 | PREINC term /* ++$x */ 841 { $$ = newUNOP(OP_PREINC, 0, 842 op_lvalue(scalar($2), OP_PREINC)); } 843 | PREDEC term /* --$x */ 844 { $$ = newUNOP(OP_PREDEC, 0, 845 op_lvalue(scalar($2), OP_PREDEC)); } 846 847 ; 848 849 /* Constructors for anonymous data */ 850 anonymous: '[' expr ']' 851 { $$ = newANONLIST($2); } 852 | '[' ']' 853 { $$ = newANONLIST((OP*)NULL);} 854 | HASHBRACK expr ';' '}' %prec '(' /* { foo => "Bar" } */ 855 { $$ = newANONHASH($2); } 856 | HASHBRACK ';' '}' %prec '(' /* { } (';' by tokener) */ 857 { $$ = newANONHASH((OP*)NULL); } 858 | ANONSUB startanonsub proto subattrlist block %prec '(' 859 { SvREFCNT_inc_simple_void(PL_compcv); 860 $$ = newANONATTRSUB($2, $3, $4, $5); } 861 | ANONSUB startanonsub remember subsignature subattrlist '{' stmtseq '}' %prec '(' 862 { 863 OP *body; 864 if (parser->copline > (line_t)$6) 865 parser->copline = (line_t)$6; 866 body = block_end($3, 867 op_append_list(OP_LINESEQ, $4, $7)); 868 SvREFCNT_inc_simple_void(PL_compcv); 869 $$ = newANONATTRSUB($2, NULL, $5, body); 870 } 871 872 ; 873 874 /* Things called with "do" */ 875 termdo : DO term %prec UNIOP /* do $filename */ 876 { $$ = dofile($2, $1);} 877 | DO block %prec '(' /* do { code */ 878 { $$ = newUNOP(OP_NULL, OPf_SPECIAL, op_scope($2));} 879 ; 880 881 term : termbinop 882 | termunop 883 | anonymous 884 | termdo 885 | term '?' term ':' term 886 { $$ = newCONDOP(0, $1, $3, $5); } 887 | REFGEN term /* \$x, \@y, \%z */ 888 { $$ = newUNOP(OP_REFGEN, 0, $2); } 889 | myattrterm %prec UNIOP 890 { $$ = $1; } 891 | LOCAL term %prec UNIOP 892 { $$ = localize($2,$1); } 893 | '(' expr ')' 894 { $$ = sawparens($2); } 895 | QWLIST 896 { $$ = $1; } 897 | '(' ')' 898 { $$ = sawparens(newNULLLIST()); } 899 | scalar %prec '(' 900 { $$ = $1; } 901 | star %prec '(' 902 { $$ = $1; } 903 | hsh %prec '(' 904 { $$ = $1; } 905 | ary %prec '(' 906 { $$ = $1; } 907 | arylen %prec '(' /* $#x, $#{ something } */ 908 { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));} 909 | subscripted 910 { $$ = $1; } 911 | sliceme '[' expr ']' /* array slice */ 912 { $$ = op_prepend_elem(OP_ASLICE, 913 newOP(OP_PUSHMARK, 0), 914 newLISTOP(OP_ASLICE, 0, 915 list($3), 916 ref($1, OP_ASLICE))); 917 if ($$ && $1) 918 $$->op_private |= 919 $1->op_private & OPpSLICEWARNING; 920 } 921 | kvslice '[' expr ']' /* array key/value slice */ 922 { $$ = op_prepend_elem(OP_KVASLICE, 923 newOP(OP_PUSHMARK, 0), 924 newLISTOP(OP_KVASLICE, 0, 925 list($3), 926 ref(oopsAV($1), OP_KVASLICE))); 927 if ($$ && $1) 928 $$->op_private |= 929 $1->op_private & OPpSLICEWARNING; 930 } 931 | sliceme '{' expr ';' '}' /* @hash{@keys} */ 932 { $$ = op_prepend_elem(OP_HSLICE, 933 newOP(OP_PUSHMARK, 0), 934 newLISTOP(OP_HSLICE, 0, 935 list($3), 936 ref(oopsHV($1), OP_HSLICE))); 937 if ($$ && $1) 938 $$->op_private |= 939 $1->op_private & OPpSLICEWARNING; 940 } 941 | kvslice '{' expr ';' '}' /* %hash{@keys} */ 942 { $$ = op_prepend_elem(OP_KVHSLICE, 943 newOP(OP_PUSHMARK, 0), 944 newLISTOP(OP_KVHSLICE, 0, 945 list($3), 946 ref($1, OP_KVHSLICE))); 947 if ($$ && $1) 948 $$->op_private |= 949 $1->op_private & OPpSLICEWARNING; 950 } 951 | THING %prec '(' 952 { $$ = $1; } 953 | amper /* &foo; */ 954 { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); } 955 | amper '(' ')' /* &foo() or foo() */ 956 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); 957 } 958 | amper '(' expr ')' /* &foo(@args) or foo(@args) */ 959 { 960 $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 961 op_append_elem(OP_LIST, $3, scalar($1))); 962 } 963 | NOAMP subname optlistexpr /* foo @args (no parens) */ 964 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 965 op_append_elem(OP_LIST, $3, scalar($2))); 966 } 967 | term ARROW '$' '*' 968 { $$ = newSVREF($1); } 969 | term ARROW '@' '*' 970 { $$ = newAVREF($1); } 971 | term ARROW '%' '*' 972 { $$ = newHVREF($1); } 973 | term ARROW '&' '*' 974 { $$ = newUNOP(OP_ENTERSUB, 0, 975 scalar(newCVREF($3,$1))); } 976 | term ARROW '*' '*' %prec '(' 977 { $$ = newGVREF(0,$1); } 978 | LOOPEX /* loop exiting command (goto, last, dump, etc) */ 979 { $$ = newOP($1, OPf_SPECIAL); 980 PL_hints |= HINT_BLOCK_SCOPE; } 981 | LOOPEX term 982 { $$ = newLOOPEX($1,$2); } 983 | NOTOP listexpr /* not $foo */ 984 { $$ = newUNOP(OP_NOT, 0, scalar($2)); } 985 | UNIOP /* Unary op, $_ implied */ 986 { $$ = newOP($1, 0); } 987 | UNIOP block /* eval { foo }* */ 988 { $$ = newUNOP($1, 0, $2); } 989 | UNIOP term /* Unary op */ 990 { $$ = newUNOP($1, 0, $2); } 991 | REQUIRE /* require, $_ implied */ 992 { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0); } 993 | REQUIRE term /* require Foo */ 994 { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2); } 995 | UNIOPSUB 996 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); } 997 | UNIOPSUB term /* Sub treated as unop */ 998 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 999 op_append_elem(OP_LIST, $2, scalar($1))); } 1000 | FUNC0 /* Nullary operator */ 1001 { $$ = newOP($1, 0); } 1002 | FUNC0 '(' ')' 1003 { $$ = newOP($1, 0);} 1004 | FUNC0OP /* Same as above, but op created in toke.c */ 1005 { $$ = $1; } 1006 | FUNC0OP '(' ')' 1007 { $$ = $1; } 1008 | FUNC0SUB /* Sub treated as nullop */ 1009 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); } 1010 | FUNC1 '(' ')' /* not () */ 1011 { $$ = ($1 == OP_NOT) 1012 ? newUNOP($1, 0, newSVOP(OP_CONST, 0, newSViv(0))) 1013 : newOP($1, OPf_SPECIAL); } 1014 | FUNC1 '(' expr ')' /* not($foo) */ 1015 { $$ = newUNOP($1, 0, $3); } 1016 | PMFUNC /* m//, s///, qr//, tr/// */ 1017 { 1018 if ( $1->op_type != OP_TRANS 1019 && $1->op_type != OP_TRANSR 1020 && (((PMOP*)$1)->op_pmflags & PMf_HAS_CV)) 1021 { 1022 $<ival>$ = start_subparse(FALSE, CVf_ANON); 1023 SAVEFREESV(PL_compcv); 1024 } else 1025 $<ival>$ = 0; 1026 } 1027 '(' listexpr optrepl ')' 1028 { $$ = pmruntime($1, $4, $5, 1, $<ival>2); } 1029 | WORD 1030 | listop 1031 | YADAYADA 1032 { 1033 $$ = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0), 1034 newSVOP(OP_CONST, 0, newSVpvs("Unimplemented"))); 1035 } 1036 | PLUGEXPR 1037 ; 1038 1039 /* "my" declarations, with optional attributes */ 1040 myattrterm: MY myterm myattrlist 1041 { $$ = my_attrs($2,$3); } 1042 | MY myterm 1043 { $$ = localize($2,$1); } 1044 ; 1045 1046 /* Things that can be "my"'d */ 1047 myterm : '(' expr ')' 1048 { $$ = sawparens($2); } 1049 | '(' ')' 1050 { $$ = sawparens(newNULLLIST()); } 1051 1052 | scalar %prec '(' 1053 { $$ = $1; } 1054 | hsh %prec '(' 1055 { $$ = $1; } 1056 | ary %prec '(' 1057 { $$ = $1; } 1058 ; 1059 1060 /* Basic list expressions */ 1061 optlistexpr: /* NULL */ %prec PREC_LOW 1062 { $$ = (OP*)NULL; } 1063 | listexpr %prec PREC_LOW 1064 { $$ = $1; } 1065 ; 1066 1067 optexpr: /* NULL */ 1068 { $$ = (OP*)NULL; } 1069 | expr 1070 { $$ = $1; } 1071 ; 1072 1073 optrepl: /* NULL */ 1074 { $$ = (OP*)NULL; } 1075 | '/' expr 1076 { $$ = $2; } 1077 ; 1078 1079 /* A little bit of trickery to make "for my $foo (@bar)" actually be 1080 lexical */ 1081 my_scalar: scalar 1082 { parser->in_my = 0; $$ = my($1); } 1083 ; 1084 1085 my_var : scalar 1086 | ary 1087 | hsh 1088 ; 1089 1090 refgen_topic: my_var 1091 | amper 1092 ; 1093 1094 amper : '&' indirob 1095 { $$ = newCVREF($1,$2); } 1096 ; 1097 1098 scalar : '$' indirob 1099 { $$ = newSVREF($2); } 1100 ; 1101 1102 ary : '@' indirob 1103 { $$ = newAVREF($2); 1104 if ($$) $$->op_private |= $1; 1105 } 1106 ; 1107 1108 hsh : '%' indirob 1109 { $$ = newHVREF($2); 1110 if ($$) $$->op_private |= $1; 1111 } 1112 ; 1113 1114 arylen : DOLSHARP indirob 1115 { $$ = newAVREF($2); } 1116 | term ARROW DOLSHARP '*' 1117 { $$ = newAVREF($1); } 1118 ; 1119 1120 star : '*' indirob 1121 { $$ = newGVREF(0,$2); } 1122 ; 1123 1124 sliceme : ary 1125 | term ARROW '@' 1126 { $$ = newAVREF($1); } 1127 ; 1128 1129 kvslice : hsh 1130 | term ARROW '%' 1131 { $$ = newHVREF($1); } 1132 ; 1133 1134 gelem : star 1135 | term ARROW '*' 1136 { $$ = newGVREF(0,$1); } 1137 ; 1138 1139 /* Indirect objects */ 1140 indirob : WORD 1141 { $$ = scalar($1); } 1142 | scalar %prec PREC_LOW 1143 { $$ = scalar($1); } 1144 | block 1145 { $$ = op_scope($1); } 1146 1147 | PRIVATEREF 1148 { $$ = $1; } 1149 ; 1150