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 * Note that these derived files are included and compiled twice; once 24 * from perly.c, and once from madly.c. The second time, a number of MAD 25 * macros are defined, which compile in extra code that allows the parse 26 * tree to be accurately dumped. In particular: 27 * 28 * MAD defined if compiling madly.c 29 * DO_MAD(A) expands to A under madly.c, to null otherwise 30 * IF_MAD(a,b) expands to A under madly.c, to B otherwise 31 * TOKEN_GETMAD() expands to token_getmad() under madly.c, to null otherwise 32 * TOKEN_FREE() similarly 33 * OP_GETMAD() similarly 34 * IVAL(i) expands to (i)->tk_lval.ival or (i) 35 * PVAL(p) expands to (p)->tk_lval.pval or (p) 36 * 37 * The main job of of this grammar is to call the various newFOO() 38 * functions in op.c to build a syntax tree of OP structs. 39 * It relies on the lexer in toke.c to do the tokenizing. 40 * 41 * Note: due to the way that the cleanup code works WRT to freeing ops on 42 * the parse stack, it is dangerous to assign to the $n variables within 43 * an action. 44 */ 45 46 /* Make the parser re-entrant. */ 47 48 %pure_parser 49 50 /* FIXME for MAD - is the new mintro on while and until important? */ 51 52 %start grammar 53 54 %union { 55 I32 ival; /* __DEFAULT__ (marker for regen_perly.pl; 56 must always be 1st union member) */ 57 char *pval; 58 OP *opval; 59 GV *gvval; 60 #ifdef PERL_IN_MADLY_C 61 TOKEN* p_tkval; 62 TOKEN* i_tkval; 63 #else 64 char *p_tkval; 65 I32 i_tkval; 66 #endif 67 #ifdef PERL_MAD 68 TOKEN* tkval; 69 #endif 70 } 71 72 %token <ival> GRAMPROG GRAMEXPR GRAMBLOCK GRAMBARESTMT GRAMFULLSTMT GRAMSTMTSEQ 73 74 %token <i_tkval> '{' '}' '[' ']' '-' '+' '$' '@' '%' '*' '&' ';' '=' '.' 75 76 %token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF QWLIST 77 %token <opval> FUNC0OP FUNC0SUB UNIOPSUB LSTOPSUB 78 %token <opval> PLUGEXPR PLUGSTMT 79 %token <p_tkval> LABEL 80 %token <i_tkval> FORMAT SUB ANONSUB PACKAGE USE 81 %token <i_tkval> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR 82 %token <i_tkval> GIVEN WHEN DEFAULT 83 %token <i_tkval> LOOPEX DOTDOT YADAYADA 84 %token <i_tkval> FUNC0 FUNC1 FUNC UNIOP LSTOP 85 %token <i_tkval> RELOP EQOP MULOP ADDOP 86 %token <i_tkval> DOLSHARP DO HASHBRACK NOAMP 87 %token <i_tkval> LOCAL MY REQUIRE 88 %token <i_tkval> COLONATTR FORMLBRACK FORMRBRACK 89 90 %type <ival> grammar remember mremember 91 %type <ival> startsub startanonsub startformsub 92 /* FIXME for MAD - are these two ival? */ 93 %type <ival> mintro 94 95 %type <opval> stmtseq fullstmt labfullstmt barestmt block mblock else 96 %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff 97 %type <opval> sliceme kvslice gelem 98 %type <opval> listexpr nexpr texpr iexpr mexpr mnexpr miexpr 99 %type <opval> optlistexpr optexpr indirob listop method 100 %type <opval> formname subname proto optsubbody cont my_scalar formblock 101 %type <opval> subattrlist myattrlist myattrterm myterm 102 %type <opval> realsubbody subsignature termbinop termunop anonymous termdo 103 %type <opval> formstmtseq formline formarg 104 105 %nonassoc <i_tkval> PREC_LOW 106 %nonassoc LOOPEX 107 108 %left <i_tkval> OROP DOROP 109 %left <i_tkval> ANDOP 110 %right <i_tkval> NOTOP 111 %nonassoc LSTOP LSTOPSUB 112 %left <i_tkval> ',' 113 %right <i_tkval> ASSIGNOP 114 %right <i_tkval> '?' ':' 115 %nonassoc DOTDOT YADAYADA 116 %left <i_tkval> OROR DORDOR 117 %left <i_tkval> ANDAND 118 %left <i_tkval> BITOROP 119 %left <i_tkval> BITANDOP 120 %nonassoc EQOP 121 %nonassoc RELOP 122 %nonassoc UNIOP UNIOPSUB 123 %nonassoc REQUIRE 124 %left <i_tkval> SHIFTOP 125 %left ADDOP 126 %left MULOP 127 %left <i_tkval> MATCHOP 128 %right <i_tkval> '!' '~' UMINUS REFGEN 129 %right <i_tkval> POWOP 130 %nonassoc <i_tkval> PREINC PREDEC POSTINC POSTDEC POSTJOIN 131 %left <i_tkval> ARROW 132 %nonassoc <i_tkval> ')' 133 %left <i_tkval> '(' 134 %left '[' '{' 135 136 %token <i_tkval> PEG 137 138 %% /* RULES */ 139 140 /* Top-level choice of what kind of thing yyparse was called to parse */ 141 grammar : GRAMPROG 142 { 143 PL_parser->expect = XSTATE; 144 } 145 remember stmtseq 146 { 147 newPROG(block_end($3,$4)); 148 $$ = 0; 149 } 150 | GRAMEXPR 151 { 152 parser->expect = XTERM; 153 } 154 optexpr 155 { 156 PL_eval_root = $3; 157 $$ = 0; 158 } 159 | GRAMBLOCK 160 { 161 parser->expect = XBLOCK; 162 } 163 block 164 { 165 PL_pad_reset_pending = TRUE; 166 PL_eval_root = $3; 167 $$ = 0; 168 yyunlex(); 169 parser->yychar = YYEOF; 170 } 171 | GRAMBARESTMT 172 { 173 parser->expect = XSTATE; 174 } 175 barestmt 176 { 177 PL_pad_reset_pending = TRUE; 178 PL_eval_root = $3; 179 $$ = 0; 180 yyunlex(); 181 parser->yychar = YYEOF; 182 } 183 | GRAMFULLSTMT 184 { 185 parser->expect = XSTATE; 186 } 187 fullstmt 188 { 189 PL_pad_reset_pending = TRUE; 190 PL_eval_root = $3; 191 $$ = 0; 192 yyunlex(); 193 parser->yychar = YYEOF; 194 } 195 | GRAMSTMTSEQ 196 { 197 parser->expect = XSTATE; 198 } 199 stmtseq 200 { 201 PL_eval_root = $3; 202 $$ = 0; 203 } 204 ; 205 206 /* An ordinary block */ 207 block : '{' remember stmtseq '}' 208 { if (PL_parser->copline > (line_t)IVAL($1)) 209 PL_parser->copline = (line_t)IVAL($1); 210 $$ = block_end($2, $3); 211 TOKEN_GETMAD($1,$$,'{'); 212 TOKEN_GETMAD($4,$$,'}'); 213 } 214 ; 215 216 /* format body */ 217 formblock: '=' remember ';' FORMRBRACK formstmtseq ';' '.' 218 { if (PL_parser->copline > (line_t)IVAL($1)) 219 PL_parser->copline = (line_t)IVAL($1); 220 $$ = block_end($2, $5); 221 TOKEN_GETMAD($1,$$,'{'); 222 TOKEN_GETMAD($7,$$,'}'); 223 } 224 ; 225 226 remember: /* NULL */ /* start a full lexical scope */ 227 { $$ = block_start(TRUE); } 228 ; 229 230 mblock : '{' mremember stmtseq '}' 231 { if (PL_parser->copline > (line_t)IVAL($1)) 232 PL_parser->copline = (line_t)IVAL($1); 233 $$ = block_end($2, $3); 234 TOKEN_GETMAD($1,$$,'{'); 235 TOKEN_GETMAD($4,$$,'}'); 236 } 237 ; 238 239 mremember: /* NULL */ /* start a partial lexical scope */ 240 { $$ = block_start(FALSE); } 241 ; 242 243 /* A sequence of statements in the program */ 244 stmtseq : /* NULL */ 245 { $$ = (OP*)NULL; } 246 | stmtseq fullstmt 247 { $$ = op_append_list(OP_LINESEQ, $1, $2); 248 PL_pad_reset_pending = TRUE; 249 if ($1 && $2) 250 PL_hints |= HINT_BLOCK_SCOPE; 251 } 252 ; 253 254 /* A sequence of format lines */ 255 formstmtseq: /* NULL */ 256 { $$ = (OP*)NULL; } 257 | formstmtseq formline 258 { $$ = op_append_list(OP_LINESEQ, $1, $2); 259 PL_pad_reset_pending = TRUE; 260 if ($1 && $2) 261 PL_hints |= HINT_BLOCK_SCOPE; 262 } 263 ; 264 265 /* A statement in the program, including optional labels */ 266 fullstmt: barestmt 267 { 268 if($1) { 269 $$ = newSTATEOP(0, NULL, $1); 270 } else { 271 $$ = IF_MAD(newOP(OP_NULL, 0), NULL); 272 } 273 } 274 | labfullstmt 275 { $$ = $1; } 276 ; 277 278 labfullstmt: LABEL barestmt 279 { 280 $$ = newSTATEOP(SVf_UTF8 281 * PVAL($1)[strlen(PVAL($1))+1], 282 PVAL($1), $2); 283 TOKEN_GETMAD($1, 284 $2 ? cLISTOPx($$)->op_first : $$, 'L'); 285 } 286 | LABEL labfullstmt 287 { 288 $$ = newSTATEOP(SVf_UTF8 289 * PVAL($1)[strlen(PVAL($1))+1], 290 PVAL($1), $2); 291 TOKEN_GETMAD($1, cLISTOPx($$)->op_first, 'L'); 292 } 293 ; 294 295 /* A bare statement, lacking label and other aspects of state op */ 296 barestmt: PLUGSTMT 297 { $$ = $1; } 298 | PEG 299 { 300 $$ = newOP(OP_NULL,0); 301 TOKEN_GETMAD($1,$$,'p'); 302 } 303 | FORMAT startformsub formname formblock 304 { 305 CV *fmtcv = PL_compcv; 306 #ifdef MAD 307 $$ = newFORM($2, $3, $4); 308 prepend_madprops($1->tk_mad, $$, 'F'); 309 $1->tk_mad = 0; 310 token_free($1); 311 #else 312 newFORM($2, $3, $4); 313 $$ = (OP*)NULL; 314 #endif 315 if (CvOUTSIDE(fmtcv) && !CvEVAL(CvOUTSIDE(fmtcv))) { 316 SvREFCNT_inc_simple_void(fmtcv); 317 pad_add_anon(fmtcv, OP_NULL); 318 } 319 } 320 | SUB subname startsub 321 { 322 if ($2->op_type == OP_CONST) { 323 const char *const name = 324 SvPV_nolen_const(((SVOP*)$2)->op_sv); 325 if (strEQ(name, "BEGIN") || strEQ(name, "END") 326 || strEQ(name, "INIT") || strEQ(name, "CHECK") 327 || strEQ(name, "UNITCHECK")) 328 CvSPECIAL_on(PL_compcv); 329 } 330 else 331 /* State subs inside anonymous subs need to be 332 clonable themselves. */ 333 if (CvANON(CvOUTSIDE(PL_compcv)) 334 || CvCLONE(CvOUTSIDE(PL_compcv)) 335 || !PadnameIsSTATE(PadlistNAMESARRAY(CvPADLIST( 336 CvOUTSIDE(PL_compcv) 337 ))[$2->op_targ])) 338 CvCLONE_on(PL_compcv); 339 PL_parser->in_my = 0; 340 PL_parser->in_my_stash = NULL; 341 } 342 proto subattrlist optsubbody 343 { 344 SvREFCNT_inc_simple_void(PL_compcv); 345 #ifdef MAD 346 { 347 OP* o = newSVOP(OP_ANONCODE, 0, 348 (SV*)( 349 #endif 350 $2->op_type == OP_CONST 351 ? newATTRSUB($3, $2, $5, $6, $7) 352 : newMYSUB($3, $2, $5, $6, $7) 353 #ifdef MAD 354 )); 355 $$ = newOP(OP_NULL,0); 356 op_getmad(o,$$,'&'); 357 op_getmad($2,$$,'n'); 358 op_getmad($5,$$,'s'); 359 op_getmad($6,$$,'a'); 360 token_getmad($1,$$,'d'); 361 append_madprops($7->op_madprop, $$, 0); 362 $7->op_madprop = 0; 363 } 364 #else 365 ; 366 $$ = (OP*)NULL; 367 #endif 368 intro_my(); 369 } 370 | PACKAGE WORD WORD ';' 371 { 372 #ifdef MAD 373 $$ = package($3); 374 token_getmad($1,$$,'o'); 375 if ($2) 376 package_version($2); 377 token_getmad($4,$$,';'); 378 #else 379 package($3); 380 if ($2) 381 package_version($2); 382 $$ = (OP*)NULL; 383 #endif 384 } 385 | USE startsub 386 { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ } 387 WORD WORD optlistexpr ';' 388 { 389 SvREFCNT_inc_simple_void(PL_compcv); 390 #ifdef MAD 391 $$ = utilize(IVAL($1), $2, $4, $5, $6); 392 token_getmad($1,$$,'o'); 393 token_getmad($7,$$,';'); 394 if (PL_parser->rsfp_filters && 395 AvFILLp(PL_parser->rsfp_filters) >= 0) 396 append_madprops(newMADPROP('!', MAD_NULL, NULL, 0), $$, 0); 397 #else 398 utilize(IVAL($1), $2, $4, $5, $6); 399 $$ = (OP*)NULL; 400 #endif 401 } 402 | IF '(' remember mexpr ')' mblock else 403 { 404 $$ = block_end($3, 405 newCONDOP(0, $4, op_scope($6), $7)); 406 TOKEN_GETMAD($1,$$,'I'); 407 TOKEN_GETMAD($2,$$,'('); 408 TOKEN_GETMAD($5,$$,')'); 409 PL_parser->copline = (line_t)IVAL($1); 410 } 411 | UNLESS '(' remember miexpr ')' mblock else 412 { 413 $$ = block_end($3, 414 newCONDOP(0, $4, op_scope($6), $7)); 415 TOKEN_GETMAD($1,$$,'I'); 416 TOKEN_GETMAD($2,$$,'('); 417 TOKEN_GETMAD($5,$$,')'); 418 PL_parser->copline = (line_t)IVAL($1); 419 } 420 | GIVEN '(' remember mexpr ')' mblock 421 { 422 const PADOFFSET offset = pad_findmy_pvs("$_", 0); 423 $$ = block_end($3, 424 newGIVENOP($4, op_scope($6), 425 offset == NOT_IN_PAD 426 || PAD_COMPNAME_FLAGS_isOUR(offset) 427 ? 0 428 : offset)); 429 PL_parser->copline = (line_t)IVAL($1); 430 } 431 | WHEN '(' remember mexpr ')' mblock 432 { $$ = block_end($3, newWHENOP($4, op_scope($6))); } 433 | DEFAULT block 434 { $$ = newWHENOP(0, op_scope($2)); } 435 | WHILE '(' remember texpr ')' mintro mblock cont 436 { 437 $$ = block_end($3, 438 newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 439 $4, $7, $8, $6)); 440 TOKEN_GETMAD($1,$$,'W'); 441 TOKEN_GETMAD($2,$$,'('); 442 TOKEN_GETMAD($5,$$,')'); 443 PL_parser->copline = (line_t)IVAL($1); 444 } 445 | UNTIL '(' remember iexpr ')' mintro mblock cont 446 { 447 $$ = block_end($3, 448 newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 449 $4, $7, $8, $6)); 450 TOKEN_GETMAD($1,$$,'W'); 451 TOKEN_GETMAD($2,$$,'('); 452 TOKEN_GETMAD($5,$$,')'); 453 PL_parser->copline = (line_t)IVAL($1); 454 } 455 | FOR '(' remember mnexpr ';' texpr ';' mintro mnexpr ')' 456 mblock 457 { 458 OP *initop = IF_MAD($4 ? $4 : newOP(OP_NULL, 0), $4); 459 OP *forop = newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 460 scalar($6), $11, $9, $8); 461 if (initop) { 462 forop = op_prepend_elem(OP_LINESEQ, initop, 463 op_append_elem(OP_LINESEQ, 464 newOP(OP_UNSTACK, OPf_SPECIAL), 465 forop)); 466 } 467 DO_MAD({ forop = newUNOP(OP_NULL, 0, forop); }) 468 $$ = block_end($3, forop); 469 TOKEN_GETMAD($1,$$,'3'); 470 TOKEN_GETMAD($2,$$,'('); 471 TOKEN_GETMAD($5,$$,'1'); 472 TOKEN_GETMAD($7,$$,'2'); 473 TOKEN_GETMAD($10,$$,')'); 474 PL_parser->copline = (line_t)IVAL($1); 475 } 476 | FOR MY remember my_scalar '(' mexpr ')' mblock cont 477 { 478 $$ = block_end($3, newFOROP(0, $4, $6, $8, $9)); 479 TOKEN_GETMAD($1,$$,'W'); 480 TOKEN_GETMAD($2,$$,'d'); 481 TOKEN_GETMAD($5,$$,'('); 482 TOKEN_GETMAD($7,$$,')'); 483 PL_parser->copline = (line_t)IVAL($1); 484 } 485 | FOR scalar '(' remember mexpr ')' mblock cont 486 { 487 $$ = block_end($4, newFOROP(0, 488 op_lvalue($2, OP_ENTERLOOP), $5, $7, $8)); 489 TOKEN_GETMAD($1,$$,'W'); 490 TOKEN_GETMAD($3,$$,'('); 491 TOKEN_GETMAD($6,$$,')'); 492 PL_parser->copline = (line_t)IVAL($1); 493 } 494 | FOR '(' remember mexpr ')' mblock cont 495 { 496 $$ = block_end($3, 497 newFOROP(0, (OP*)NULL, $4, $6, $7)); 498 TOKEN_GETMAD($1,$$,'W'); 499 TOKEN_GETMAD($2,$$,'('); 500 TOKEN_GETMAD($5,$$,')'); 501 PL_parser->copline = (line_t)IVAL($1); 502 } 503 | block cont 504 { 505 /* a block is a loop that happens once */ 506 $$ = newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 507 (OP*)NULL, $1, $2, 0); 508 } 509 | PACKAGE WORD WORD '{' remember 510 { 511 package($3); 512 if ($2) { 513 package_version($2); 514 } 515 } 516 stmtseq '}' 517 { 518 /* a block is a loop that happens once */ 519 $$ = newWHILEOP(0, 1, (LOOP*)(OP*)NULL, 520 (OP*)NULL, block_end($5, $7), (OP*)NULL, 0); 521 TOKEN_GETMAD($4,$$,'{'); 522 TOKEN_GETMAD($8,$$,'}'); 523 if (PL_parser->copline > (line_t)IVAL($4)) 524 PL_parser->copline = (line_t)IVAL($4); 525 } 526 | sideff ';' 527 { 528 PL_parser->expect = XSTATE; 529 $$ = $1; 530 TOKEN_GETMAD($2,$$,';'); 531 } 532 | ';' 533 { 534 PL_parser->expect = XSTATE; 535 $$ = IF_MAD(newOP(OP_NULL, 0), (OP*)NULL); 536 TOKEN_GETMAD($1,$$,';'); 537 PL_parser->copline = NOLINE; 538 } 539 ; 540 541 /* Format line */ 542 formline: THING formarg 543 { OP *list; 544 if ($2) { 545 OP *term = $2; 546 DO_MAD(term = newUNOP(OP_NULL, 0, term)); 547 list = op_append_elem(OP_LIST, $1, term); 548 } 549 else { 550 #ifdef MAD 551 OP *op = newNULLLIST(); 552 list = op_append_elem(OP_LIST, $1, op); 553 #else 554 list = $1; 555 #endif 556 } 557 if (PL_parser->copline == NOLINE) 558 PL_parser->copline = CopLINE(PL_curcop)-1; 559 else PL_parser->copline--; 560 $$ = newSTATEOP(0, NULL, 561 convert(OP_FORMLINE, 0, list)); 562 } 563 ; 564 565 formarg : /* NULL */ 566 { $$ = NULL; } 567 | FORMLBRACK stmtseq FORMRBRACK 568 { $$ = op_unscope($2); } 569 ; 570 571 /* An expression which may have a side-effect */ 572 sideff : error 573 { $$ = (OP*)NULL; } 574 | expr 575 { $$ = $1; } 576 | expr IF expr 577 { $$ = newLOGOP(OP_AND, 0, $3, $1); 578 TOKEN_GETMAD($2,$$,'i'); 579 } 580 | expr UNLESS expr 581 { $$ = newLOGOP(OP_OR, 0, $3, $1); 582 TOKEN_GETMAD($2,$$,'i'); 583 } 584 | expr WHILE expr 585 { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); 586 TOKEN_GETMAD($2,$$,'w'); 587 } 588 | expr UNTIL iexpr 589 { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1); 590 TOKEN_GETMAD($2,$$,'w'); 591 } 592 | expr FOR expr 593 { $$ = newFOROP(0, (OP*)NULL, $3, $1, (OP*)NULL); 594 TOKEN_GETMAD($2,$$,'w'); 595 PL_parser->copline = (line_t)IVAL($2); 596 } 597 | expr WHEN expr 598 { $$ = newWHENOP($3, op_scope($1)); } 599 ; 600 601 /* else and elsif blocks */ 602 else : /* NULL */ 603 { $$ = (OP*)NULL; } 604 | ELSE mblock 605 { 606 ($2)->op_flags |= OPf_PARENS; 607 $$ = op_scope($2); 608 TOKEN_GETMAD($1,$$,'o'); 609 } 610 | ELSIF '(' mexpr ')' mblock else 611 { PL_parser->copline = (line_t)IVAL($1); 612 $$ = newCONDOP(0, 613 newSTATEOP(OPf_SPECIAL,NULL,$3), 614 op_scope($5), $6); 615 PL_hints |= HINT_BLOCK_SCOPE; 616 TOKEN_GETMAD($1,$$,'I'); 617 TOKEN_GETMAD($2,$$,'('); 618 TOKEN_GETMAD($4,$$,')'); 619 } 620 ; 621 622 /* Continue blocks */ 623 cont : /* NULL */ 624 { $$ = (OP*)NULL; } 625 | CONTINUE block 626 { 627 $$ = op_scope($2); 628 TOKEN_GETMAD($1,$$,'o'); 629 } 630 ; 631 632 /* determine whether there are any new my declarations */ 633 mintro : /* NULL */ 634 { $$ = (PL_min_intro_pending && 635 PL_max_intro_pending >= PL_min_intro_pending); 636 intro_my(); } 637 638 /* Normal expression */ 639 nexpr : /* NULL */ 640 { $$ = (OP*)NULL; } 641 | sideff 642 ; 643 644 /* Boolean expression */ 645 texpr : /* NULL means true */ 646 { YYSTYPE tmplval; 647 (void)scan_num("1", &tmplval); 648 $$ = tmplval.opval; } 649 | expr 650 ; 651 652 /* Inverted boolean expression */ 653 iexpr : expr 654 { $$ = invert(scalar($1)); } 655 ; 656 657 /* Expression with its own lexical scope */ 658 mexpr : expr 659 { $$ = $1; intro_my(); } 660 ; 661 662 mnexpr : nexpr 663 { $$ = $1; intro_my(); } 664 ; 665 666 miexpr : iexpr 667 { $$ = $1; intro_my(); } 668 ; 669 670 formname: WORD { $$ = $1; } 671 | /* NULL */ { $$ = (OP*)NULL; } 672 ; 673 674 startsub: /* NULL */ /* start a regular subroutine scope */ 675 { $$ = start_subparse(FALSE, 0); 676 SAVEFREESV(PL_compcv); } 677 678 ; 679 680 startanonsub: /* NULL */ /* start an anonymous subroutine scope */ 681 { $$ = start_subparse(FALSE, CVf_ANON); 682 SAVEFREESV(PL_compcv); } 683 ; 684 685 startformsub: /* NULL */ /* start a format subroutine scope */ 686 { $$ = start_subparse(TRUE, 0); 687 SAVEFREESV(PL_compcv); } 688 ; 689 690 /* Name of a subroutine - must be a bareword, could be special */ 691 subname : WORD 692 | PRIVATEREF 693 ; 694 695 /* Subroutine prototype */ 696 proto : /* NULL */ 697 { $$ = (OP*)NULL; } 698 | THING 699 ; 700 701 /* Optional list of subroutine attributes */ 702 subattrlist: /* NULL */ 703 { $$ = (OP*)NULL; } 704 | COLONATTR THING 705 { $$ = $2; 706 TOKEN_GETMAD($1,$$,':'); 707 } 708 | COLONATTR 709 { $$ = IF_MAD( 710 newOP(OP_NULL, 0), 711 (OP*)NULL 712 ); 713 TOKEN_GETMAD($1,$$,':'); 714 } 715 ; 716 717 /* List of attributes for a "my" variable declaration */ 718 myattrlist: COLONATTR THING 719 { $$ = $2; 720 TOKEN_GETMAD($1,$$,':'); 721 } 722 | COLONATTR 723 { $$ = IF_MAD( 724 newOP(OP_NULL, 0), 725 (OP*)NULL 726 ); 727 TOKEN_GETMAD($1,$$,':'); 728 } 729 ; 730 731 /* Optional subroutine signature */ 732 subsignature: /* NULL */ { $$ = (OP*)NULL; } 733 | '(' 734 { 735 if (!FEATURE_SIGNATURES_IS_ENABLED) 736 Perl_croak(aTHX_ "Experimental " 737 "subroutine signatures not enabled"); 738 Perl_ck_warner_d(aTHX_ 739 packWARN(WARN_EXPERIMENTAL__SIGNATURES), 740 "The signatures feature is experimental"); 741 $<opval>$ = parse_subsignature(); 742 } 743 ')' 744 { 745 $$ = op_append_list(OP_LINESEQ, $<opval>2, 746 newSTATEOP(0, NULL, sawparens(newNULLLIST()))); 747 PL_parser->expect = XBLOCK; 748 } 749 ; 750 751 /* Subroutine body - block with optional signature */ 752 realsubbody: remember subsignature '{' stmtseq '}' 753 { 754 if (PL_parser->copline > (line_t)IVAL($3)) 755 PL_parser->copline = (line_t)IVAL($3); 756 $$ = block_end($1, 757 op_append_list(OP_LINESEQ, $2, $4)); 758 TOKEN_GETMAD($3,$$,'{'); 759 TOKEN_GETMAD($5,$$,'}'); 760 } 761 ; 762 763 /* Optional subroutine body, for named subroutine declaration */ 764 optsubbody: realsubbody { $$ = $1; } 765 | ';' { $$ = IF_MAD( 766 newOP(OP_NULL,0), 767 (OP*)NULL 768 ); 769 PL_parser->expect = XSTATE; 770 TOKEN_GETMAD($1,$$,';'); 771 } 772 ; 773 774 /* Ordinary expressions; logical combinations */ 775 expr : expr ANDOP expr 776 { $$ = newLOGOP(OP_AND, 0, $1, $3); 777 TOKEN_GETMAD($2,$$,'o'); 778 } 779 | expr OROP expr 780 { $$ = newLOGOP(IVAL($2), 0, $1, $3); 781 TOKEN_GETMAD($2,$$,'o'); 782 } 783 | expr DOROP expr 784 { $$ = newLOGOP(OP_DOR, 0, $1, $3); 785 TOKEN_GETMAD($2,$$,'o'); 786 } 787 | listexpr %prec PREC_LOW 788 ; 789 790 /* Expressions are a list of terms joined by commas */ 791 listexpr: listexpr ',' 792 { 793 #ifdef MAD 794 OP* op = newNULLLIST(); 795 token_getmad($2,op,','); 796 $$ = op_append_elem(OP_LIST, $1, op); 797 #else 798 $$ = $1; 799 #endif 800 } 801 | listexpr ',' term 802 { 803 OP* term = $3; 804 DO_MAD( 805 term = newUNOP(OP_NULL, 0, term); 806 token_getmad($2,term,','); 807 ) 808 $$ = op_append_elem(OP_LIST, $1, term); 809 } 810 | term %prec PREC_LOW 811 ; 812 813 /* List operators */ 814 listop : LSTOP indirob listexpr /* map {...} @args or print $fh @args */ 815 { $$ = convert(IVAL($1), OPf_STACKED, 816 op_prepend_elem(OP_LIST, newGVREF(IVAL($1),$2), $3) ); 817 TOKEN_GETMAD($1,$$,'o'); 818 } 819 | FUNC '(' indirob expr ')' /* print ($fh @args */ 820 { $$ = convert(IVAL($1), OPf_STACKED, 821 op_prepend_elem(OP_LIST, newGVREF(IVAL($1),$3), $4) ); 822 TOKEN_GETMAD($1,$$,'o'); 823 TOKEN_GETMAD($2,$$,'('); 824 TOKEN_GETMAD($5,$$,')'); 825 } 826 | term ARROW method '(' optexpr ')' /* $foo->bar(list) */ 827 { $$ = convert(OP_ENTERSUB, OPf_STACKED, 828 op_append_elem(OP_LIST, 829 op_prepend_elem(OP_LIST, scalar($1), $5), 830 newUNOP(OP_METHOD, 0, $3))); 831 TOKEN_GETMAD($2,$$,'A'); 832 TOKEN_GETMAD($4,$$,'('); 833 TOKEN_GETMAD($6,$$,')'); 834 } 835 | term ARROW method /* $foo->bar */ 836 { $$ = convert(OP_ENTERSUB, OPf_STACKED, 837 op_append_elem(OP_LIST, scalar($1), 838 newUNOP(OP_METHOD, 0, $3))); 839 TOKEN_GETMAD($2,$$,'A'); 840 } 841 | METHOD indirob optlistexpr /* new Class @args */ 842 { $$ = convert(OP_ENTERSUB, OPf_STACKED, 843 op_append_elem(OP_LIST, 844 op_prepend_elem(OP_LIST, $2, $3), 845 newUNOP(OP_METHOD, 0, $1))); 846 } 847 | FUNCMETH indirob '(' optexpr ')' /* method $object (@args) */ 848 { $$ = convert(OP_ENTERSUB, OPf_STACKED, 849 op_append_elem(OP_LIST, 850 op_prepend_elem(OP_LIST, $2, $4), 851 newUNOP(OP_METHOD, 0, $1))); 852 TOKEN_GETMAD($3,$$,'('); 853 TOKEN_GETMAD($5,$$,')'); 854 } 855 | LSTOP optlistexpr /* print @args */ 856 { $$ = convert(IVAL($1), 0, $2); 857 TOKEN_GETMAD($1,$$,'o'); 858 } 859 | FUNC '(' optexpr ')' /* print (@args) */ 860 { $$ = convert(IVAL($1), 0, $3); 861 TOKEN_GETMAD($1,$$,'o'); 862 TOKEN_GETMAD($2,$$,'('); 863 TOKEN_GETMAD($4,$$,')'); 864 } 865 | LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */ 866 { SvREFCNT_inc_simple_void(PL_compcv); 867 $<opval>$ = newANONATTRSUB($2, 0, (OP*)NULL, $3); } 868 optlistexpr %prec LSTOP /* ... @bar */ 869 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 870 op_append_elem(OP_LIST, 871 op_prepend_elem(OP_LIST, $<opval>4, $5), $1)); 872 } 873 ; 874 875 /* Names of methods. May use $object->$methodname */ 876 method : METHOD 877 | scalar 878 ; 879 880 /* Some kind of subscripted expression */ 881 subscripted: gelem '{' expr ';' '}' /* *main::{something} */ 882 /* In this and all the hash accessors, ';' is 883 * provided by the tokeniser */ 884 { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3)); 885 PL_parser->expect = XOPERATOR; 886 TOKEN_GETMAD($2,$$,'{'); 887 TOKEN_GETMAD($4,$$,';'); 888 TOKEN_GETMAD($5,$$,'}'); 889 } 890 | scalar '[' expr ']' /* $array[$element] */ 891 { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); 892 TOKEN_GETMAD($2,$$,'['); 893 TOKEN_GETMAD($4,$$,']'); 894 } 895 | term ARROW '[' expr ']' /* somearef->[$element] */ 896 { $$ = newBINOP(OP_AELEM, 0, 897 ref(newAVREF($1),OP_RV2AV), 898 scalar($4)); 899 TOKEN_GETMAD($2,$$,'a'); 900 TOKEN_GETMAD($3,$$,'['); 901 TOKEN_GETMAD($5,$$,']'); 902 } 903 | subscripted '[' expr ']' /* $foo->[$bar]->[$baz] */ 904 { $$ = newBINOP(OP_AELEM, 0, 905 ref(newAVREF($1),OP_RV2AV), 906 scalar($3)); 907 TOKEN_GETMAD($2,$$,'['); 908 TOKEN_GETMAD($4,$$,']'); 909 } 910 | scalar '{' expr ';' '}' /* $foo{bar();} */ 911 { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3)); 912 PL_parser->expect = XOPERATOR; 913 TOKEN_GETMAD($2,$$,'{'); 914 TOKEN_GETMAD($4,$$,';'); 915 TOKEN_GETMAD($5,$$,'}'); 916 } 917 | term ARROW '{' expr ';' '}' /* somehref->{bar();} */ 918 { $$ = newBINOP(OP_HELEM, 0, 919 ref(newHVREF($1),OP_RV2HV), 920 jmaybe($4)); 921 PL_parser->expect = XOPERATOR; 922 TOKEN_GETMAD($2,$$,'a'); 923 TOKEN_GETMAD($3,$$,'{'); 924 TOKEN_GETMAD($5,$$,';'); 925 TOKEN_GETMAD($6,$$,'}'); 926 } 927 | subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */ 928 { $$ = newBINOP(OP_HELEM, 0, 929 ref(newHVREF($1),OP_RV2HV), 930 jmaybe($3)); 931 PL_parser->expect = XOPERATOR; 932 TOKEN_GETMAD($2,$$,'{'); 933 TOKEN_GETMAD($4,$$,';'); 934 TOKEN_GETMAD($5,$$,'}'); 935 } 936 | term ARROW '(' ')' /* $subref->() */ 937 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 938 newCVREF(0, scalar($1))); 939 TOKEN_GETMAD($2,$$,'a'); 940 TOKEN_GETMAD($3,$$,'('); 941 TOKEN_GETMAD($4,$$,')'); 942 } 943 | term ARROW '(' expr ')' /* $subref->(@args) */ 944 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 945 op_append_elem(OP_LIST, $4, 946 newCVREF(0, scalar($1)))); 947 TOKEN_GETMAD($2,$$,'a'); 948 TOKEN_GETMAD($3,$$,'('); 949 TOKEN_GETMAD($5,$$,')'); 950 } 951 952 | subscripted '(' expr ')' /* $foo->{bar}->(@args) */ 953 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 954 op_append_elem(OP_LIST, $3, 955 newCVREF(0, scalar($1)))); 956 TOKEN_GETMAD($2,$$,'('); 957 TOKEN_GETMAD($4,$$,')'); 958 } 959 | subscripted '(' ')' /* $foo->{bar}->() */ 960 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 961 newCVREF(0, scalar($1))); 962 TOKEN_GETMAD($2,$$,'('); 963 TOKEN_GETMAD($3,$$,')'); 964 } 965 | '(' expr ')' '[' expr ']' /* list slice */ 966 { $$ = newSLICEOP(0, $5, $2); 967 TOKEN_GETMAD($1,$$,'('); 968 TOKEN_GETMAD($3,$$,')'); 969 TOKEN_GETMAD($4,$$,'['); 970 TOKEN_GETMAD($6,$$,']'); 971 } 972 | QWLIST '[' expr ']' /* list literal slice */ 973 { $$ = newSLICEOP(0, $3, $1); 974 TOKEN_GETMAD($2,$$,'['); 975 TOKEN_GETMAD($4,$$,']'); 976 } 977 | '(' ')' '[' expr ']' /* empty list slice! */ 978 { $$ = newSLICEOP(0, $4, (OP*)NULL); 979 TOKEN_GETMAD($1,$$,'('); 980 TOKEN_GETMAD($2,$$,')'); 981 TOKEN_GETMAD($3,$$,'['); 982 TOKEN_GETMAD($5,$$,']'); 983 } 984 ; 985 986 /* Binary operators between terms */ 987 termbinop: term ASSIGNOP term /* $x = $y */ 988 { $$ = newASSIGNOP(OPf_STACKED, $1, IVAL($2), $3); 989 TOKEN_GETMAD($2,$$,'o'); 990 } 991 | term POWOP term /* $x ** $y */ 992 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3)); 993 TOKEN_GETMAD($2,$$,'o'); 994 } 995 | term MULOP term /* $x * $y, $x x $y */ 996 { if (IVAL($2) != OP_REPEAT) 997 scalar($1); 998 $$ = newBINOP(IVAL($2), 0, $1, scalar($3)); 999 TOKEN_GETMAD($2,$$,'o'); 1000 } 1001 | term ADDOP term /* $x + $y */ 1002 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3)); 1003 TOKEN_GETMAD($2,$$,'o'); 1004 } 1005 | term SHIFTOP term /* $x >> $y, $x << $y */ 1006 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3)); 1007 TOKEN_GETMAD($2,$$,'o'); 1008 } 1009 | term RELOP term /* $x > $y, etc. */ 1010 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3)); 1011 TOKEN_GETMAD($2,$$,'o'); 1012 } 1013 | term EQOP term /* $x == $y, $x eq $y */ 1014 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3)); 1015 TOKEN_GETMAD($2,$$,'o'); 1016 } 1017 | term BITANDOP term /* $x & $y */ 1018 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3)); 1019 TOKEN_GETMAD($2,$$,'o'); 1020 } 1021 | term BITOROP term /* $x | $y */ 1022 { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3)); 1023 TOKEN_GETMAD($2,$$,'o'); 1024 } 1025 | term DOTDOT term /* $x..$y, $x...$y */ 1026 { 1027 $$ = newRANGE(IVAL($2), scalar($1), scalar($3)); 1028 DO_MAD({ 1029 UNOP *op; 1030 op = (UNOP*)$$; 1031 op = (UNOP*)op->op_first; /* get to flop */ 1032 op = (UNOP*)op->op_first; /* get to flip */ 1033 op = (UNOP*)op->op_first; /* get to range */ 1034 token_getmad($2,(OP*)op,'o'); 1035 }); 1036 } 1037 | term ANDAND term /* $x && $y */ 1038 { $$ = newLOGOP(OP_AND, 0, $1, $3); 1039 TOKEN_GETMAD($2,$$,'o'); 1040 } 1041 | term OROR term /* $x || $y */ 1042 { $$ = newLOGOP(OP_OR, 0, $1, $3); 1043 TOKEN_GETMAD($2,$$,'o'); 1044 } 1045 | term DORDOR term /* $x // $y */ 1046 { $$ = newLOGOP(OP_DOR, 0, $1, $3); 1047 TOKEN_GETMAD($2,$$,'o'); 1048 } 1049 | term MATCHOP term /* $x =~ /$y/ */ 1050 { $$ = bind_match(IVAL($2), $1, $3); 1051 TOKEN_GETMAD($2, 1052 ($$->op_type == OP_NOT 1053 ? ((UNOP*)$$)->op_first : $$), 1054 '~'); 1055 } 1056 ; 1057 1058 /* Unary operators and terms */ 1059 termunop : '-' term %prec UMINUS /* -$x */ 1060 { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); 1061 TOKEN_GETMAD($1,$$,'o'); 1062 } 1063 | '+' term %prec UMINUS /* +$x */ 1064 { $$ = IF_MAD( 1065 newUNOP(OP_NULL, 0, $2), 1066 $2 1067 ); 1068 TOKEN_GETMAD($1,$$,'+'); 1069 } 1070 | '!' term /* !$x */ 1071 { $$ = newUNOP(OP_NOT, 0, scalar($2)); 1072 TOKEN_GETMAD($1,$$,'o'); 1073 } 1074 | '~' term /* ~$x */ 1075 { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2)); 1076 TOKEN_GETMAD($1,$$,'o'); 1077 } 1078 | term POSTINC /* $x++ */ 1079 { $$ = newUNOP(OP_POSTINC, 0, 1080 op_lvalue(scalar($1), OP_POSTINC)); 1081 TOKEN_GETMAD($2,$$,'o'); 1082 } 1083 | term POSTDEC /* $x-- */ 1084 { $$ = newUNOP(OP_POSTDEC, 0, 1085 op_lvalue(scalar($1), OP_POSTDEC)); 1086 TOKEN_GETMAD($2,$$,'o'); 1087 } 1088 | term POSTJOIN /* implicit join after interpolated ->@ */ 1089 { $$ = convert(OP_JOIN, 0, 1090 op_append_elem( 1091 OP_LIST, 1092 newSVREF(scalar( 1093 newSVOP(OP_CONST,0, 1094 newSVpvs("\"")) 1095 )), 1096 $1 1097 )); 1098 TOKEN_GETMAD($2,$$,'o'); 1099 } 1100 | PREINC term /* ++$x */ 1101 { $$ = newUNOP(OP_PREINC, 0, 1102 op_lvalue(scalar($2), OP_PREINC)); 1103 TOKEN_GETMAD($1,$$,'o'); 1104 } 1105 | PREDEC term /* --$x */ 1106 { $$ = newUNOP(OP_PREDEC, 0, 1107 op_lvalue(scalar($2), OP_PREDEC)); 1108 TOKEN_GETMAD($1,$$,'o'); 1109 } 1110 1111 ; 1112 1113 /* Constructors for anonymous data */ 1114 anonymous: '[' expr ']' 1115 { $$ = newANONLIST($2); 1116 TOKEN_GETMAD($1,$$,'['); 1117 TOKEN_GETMAD($3,$$,']'); 1118 } 1119 | '[' ']' 1120 { $$ = newANONLIST((OP*)NULL); 1121 TOKEN_GETMAD($1,$$,'['); 1122 TOKEN_GETMAD($2,$$,']'); 1123 } 1124 | HASHBRACK expr ';' '}' %prec '(' /* { foo => "Bar" } */ 1125 { $$ = newANONHASH($2); 1126 TOKEN_GETMAD($1,$$,'{'); 1127 TOKEN_GETMAD($3,$$,';'); 1128 TOKEN_GETMAD($4,$$,'}'); 1129 } 1130 | HASHBRACK ';' '}' %prec '(' /* { } (';' by tokener) */ 1131 { $$ = newANONHASH((OP*)NULL); 1132 TOKEN_GETMAD($1,$$,'{'); 1133 TOKEN_GETMAD($2,$$,';'); 1134 TOKEN_GETMAD($3,$$,'}'); 1135 } 1136 | ANONSUB startanonsub proto subattrlist realsubbody %prec '(' 1137 { SvREFCNT_inc_simple_void(PL_compcv); 1138 $$ = newANONATTRSUB($2, $3, $4, $5); 1139 TOKEN_GETMAD($1,$$,'o'); 1140 OP_GETMAD($3,$$,'s'); 1141 OP_GETMAD($4,$$,'a'); 1142 } 1143 1144 ; 1145 1146 /* Things called with "do" */ 1147 termdo : DO term %prec UNIOP /* do $filename */ 1148 { $$ = dofile($2, IVAL($1)); 1149 TOKEN_GETMAD($1,$$,'o'); 1150 } 1151 | DO block %prec '(' /* do { code */ 1152 { $$ = newUNOP(OP_NULL, OPf_SPECIAL, op_scope($2)); 1153 TOKEN_GETMAD($1,$$,'D'); 1154 } 1155 ; 1156 1157 term : termbinop 1158 | termunop 1159 | anonymous 1160 | termdo 1161 | term '?' term ':' term 1162 { $$ = newCONDOP(0, $1, $3, $5); 1163 TOKEN_GETMAD($2,$$,'?'); 1164 TOKEN_GETMAD($4,$$,':'); 1165 } 1166 | REFGEN term /* \$x, \@y, \%z */ 1167 { $$ = newUNOP(OP_REFGEN, 0, op_lvalue($2,OP_REFGEN)); 1168 TOKEN_GETMAD($1,$$,'o'); 1169 } 1170 | myattrterm %prec UNIOP 1171 { $$ = $1; } 1172 | LOCAL term %prec UNIOP 1173 { $$ = localize($2,IVAL($1)); 1174 TOKEN_GETMAD($1,$$,'k'); 1175 } 1176 | '(' expr ')' 1177 { $$ = sawparens(IF_MAD(newUNOP(OP_NULL,0,$2), $2)); 1178 TOKEN_GETMAD($1,$$,'('); 1179 TOKEN_GETMAD($3,$$,')'); 1180 } 1181 | QWLIST 1182 { $$ = IF_MAD(newUNOP(OP_NULL,0,$1), $1); } 1183 | '(' ')' 1184 { $$ = sawparens(newNULLLIST()); 1185 TOKEN_GETMAD($1,$$,'('); 1186 TOKEN_GETMAD($2,$$,')'); 1187 } 1188 | scalar %prec '(' 1189 { $$ = $1; } 1190 | star %prec '(' 1191 { $$ = $1; } 1192 | hsh %prec '(' 1193 { $$ = $1; } 1194 | ary %prec '(' 1195 { $$ = $1; } 1196 | arylen %prec '(' /* $#x, $#{ something } */ 1197 { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));} 1198 | subscripted 1199 { $$ = $1; } 1200 | sliceme '[' expr ']' /* array slice */ 1201 { $$ = op_prepend_elem(OP_ASLICE, 1202 newOP(OP_PUSHMARK, 0), 1203 newLISTOP(OP_ASLICE, 0, 1204 list($3), 1205 ref($1, OP_ASLICE))); 1206 if ($$ && $1) 1207 $$->op_private |= 1208 $1->op_private & OPpSLICEWARNING; 1209 TOKEN_GETMAD($2,$$,'['); 1210 TOKEN_GETMAD($4,$$,']'); 1211 } 1212 | kvslice '[' expr ']' /* array key/value slice */ 1213 { $$ = op_prepend_elem(OP_KVASLICE, 1214 newOP(OP_PUSHMARK, 0), 1215 newLISTOP(OP_KVASLICE, 0, 1216 list($3), 1217 ref(oopsAV($1), OP_KVASLICE))); 1218 if ($$ && $1) 1219 $$->op_private |= 1220 $1->op_private & OPpSLICEWARNING; 1221 TOKEN_GETMAD($2,$$,'['); 1222 TOKEN_GETMAD($4,$$,']'); 1223 } 1224 | sliceme '{' expr ';' '}' /* @hash{@keys} */ 1225 { $$ = op_prepend_elem(OP_HSLICE, 1226 newOP(OP_PUSHMARK, 0), 1227 newLISTOP(OP_HSLICE, 0, 1228 list($3), 1229 ref(oopsHV($1), OP_HSLICE))); 1230 if ($$ && $1) 1231 $$->op_private |= 1232 $1->op_private & OPpSLICEWARNING; 1233 PL_parser->expect = XOPERATOR; 1234 TOKEN_GETMAD($2,$$,'{'); 1235 TOKEN_GETMAD($4,$$,';'); 1236 TOKEN_GETMAD($5,$$,'}'); 1237 } 1238 | kvslice '{' expr ';' '}' /* %hash{@keys} */ 1239 { $$ = op_prepend_elem(OP_KVHSLICE, 1240 newOP(OP_PUSHMARK, 0), 1241 newLISTOP(OP_KVHSLICE, 0, 1242 list($3), 1243 ref($1, OP_KVHSLICE))); 1244 if ($$ && $1) 1245 $$->op_private |= 1246 $1->op_private & OPpSLICEWARNING; 1247 PL_parser->expect = XOPERATOR; 1248 TOKEN_GETMAD($2,$$,'{'); 1249 TOKEN_GETMAD($4,$$,';'); 1250 TOKEN_GETMAD($5,$$,'}'); 1251 } 1252 | THING %prec '(' 1253 { $$ = $1; } 1254 | amper /* &foo; */ 1255 { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); } 1256 | amper '(' ')' /* &foo() or foo() */ 1257 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); 1258 TOKEN_GETMAD($2,$$,'('); 1259 TOKEN_GETMAD($3,$$,')'); 1260 } 1261 | amper '(' expr ')' /* &foo(@args) or foo(@args) */ 1262 { 1263 $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 1264 op_append_elem(OP_LIST, $3, scalar($1))); 1265 DO_MAD({ 1266 OP* op = $$; 1267 if (op->op_type == OP_CONST) { /* defeat const fold */ 1268 op = (OP*)op->op_madprop->mad_val; 1269 } 1270 token_getmad($2,op,'('); 1271 token_getmad($4,op,')'); 1272 }); 1273 } 1274 | NOAMP subname optlistexpr /* foo @args (no parens) */ 1275 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 1276 op_append_elem(OP_LIST, $3, scalar($2))); 1277 TOKEN_GETMAD($1,$$,'o'); 1278 } 1279 | term ARROW '$' '*' 1280 { $$ = newSVREF($1); 1281 TOKEN_GETMAD($3,$$,'$'); 1282 } 1283 | term ARROW '@' '*' 1284 { $$ = newAVREF($1); 1285 TOKEN_GETMAD($3,$$,'@'); 1286 } 1287 | term ARROW '%' '*' 1288 { $$ = newHVREF($1); 1289 TOKEN_GETMAD($3,$$,'%'); 1290 } 1291 | term ARROW '&' '*' 1292 { $$ = newUNOP(OP_ENTERSUB, 0, 1293 scalar(newCVREF(IVAL($3),$1))); 1294 TOKEN_GETMAD($3,$$,'&'); 1295 } 1296 | term ARROW '*' '*' %prec '(' 1297 { $$ = newGVREF(0,$1); 1298 TOKEN_GETMAD($3,$$,'*'); 1299 } 1300 | LOOPEX /* loop exiting command (goto, last, dump, etc) */ 1301 { $$ = newOP(IVAL($1), OPf_SPECIAL); 1302 PL_hints |= HINT_BLOCK_SCOPE; 1303 TOKEN_GETMAD($1,$$,'o'); 1304 } 1305 | LOOPEX term 1306 { $$ = newLOOPEX(IVAL($1),$2); 1307 TOKEN_GETMAD($1,$$,'o'); 1308 } 1309 | NOTOP listexpr /* not $foo */ 1310 { $$ = newUNOP(OP_NOT, 0, scalar($2)); 1311 TOKEN_GETMAD($1,$$,'o'); 1312 } 1313 | UNIOP /* Unary op, $_ implied */ 1314 { $$ = newOP(IVAL($1), 0); 1315 TOKEN_GETMAD($1,$$,'o'); 1316 } 1317 | UNIOP block /* eval { foo }* */ 1318 { $$ = newUNOP(IVAL($1), 0, $2); 1319 TOKEN_GETMAD($1,$$,'o'); 1320 } 1321 | UNIOP term /* Unary op */ 1322 { $$ = newUNOP(IVAL($1), 0, $2); 1323 TOKEN_GETMAD($1,$$,'o'); 1324 } 1325 | REQUIRE /* require, $_ implied */ 1326 { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0); 1327 TOKEN_GETMAD($1,$$,'o'); 1328 } 1329 | REQUIRE term /* require Foo */ 1330 { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2); 1331 TOKEN_GETMAD($1,$$,'o'); 1332 } 1333 | UNIOPSUB 1334 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); } 1335 | UNIOPSUB term /* Sub treated as unop */ 1336 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 1337 op_append_elem(OP_LIST, $2, scalar($1))); } 1338 | FUNC0 /* Nullary operator */ 1339 { $$ = newOP(IVAL($1), 0); 1340 TOKEN_GETMAD($1,$$,'o'); 1341 } 1342 | FUNC0 '(' ')' 1343 { $$ = newOP(IVAL($1), 0); 1344 TOKEN_GETMAD($1,$$,'o'); 1345 TOKEN_GETMAD($2,$$,'('); 1346 TOKEN_GETMAD($3,$$,')'); 1347 } 1348 | FUNC0OP /* Same as above, but op created in toke.c */ 1349 { $$ = $1; } 1350 | FUNC0OP '(' ')' 1351 { $$ = $1; 1352 TOKEN_GETMAD($2,$$,'('); 1353 TOKEN_GETMAD($3,$$,')'); 1354 } 1355 | FUNC0SUB /* Sub treated as nullop */ 1356 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, 1357 scalar($1)); } 1358 | FUNC1 '(' ')' /* not () */ 1359 { $$ = (IVAL($1) == OP_NOT) 1360 ? newUNOP(IVAL($1), 0, newSVOP(OP_CONST, 0, newSViv(0))) 1361 : newOP(IVAL($1), OPf_SPECIAL); 1362 1363 TOKEN_GETMAD($1,$$,'o'); 1364 TOKEN_GETMAD($2,$$,'('); 1365 TOKEN_GETMAD($3,$$,')'); 1366 } 1367 | FUNC1 '(' expr ')' /* not($foo) */ 1368 { $$ = newUNOP(IVAL($1), 0, $3); 1369 TOKEN_GETMAD($1,$$,'o'); 1370 TOKEN_GETMAD($2,$$,'('); 1371 TOKEN_GETMAD($4,$$,')'); 1372 } 1373 | PMFUNC /* m//, s///, qr//, tr/// */ 1374 { 1375 if ( $1->op_type != OP_TRANS 1376 && $1->op_type != OP_TRANSR 1377 && (((PMOP*)$1)->op_pmflags & PMf_HAS_CV)) 1378 { 1379 $<ival>$ = start_subparse(FALSE, CVf_ANON); 1380 SAVEFREESV(PL_compcv); 1381 } else 1382 $<ival>$ = 0; 1383 } 1384 '(' listexpr ')' 1385 { $$ = pmruntime($1, $4, 1, $<ival>2); 1386 TOKEN_GETMAD($3,$$,'('); 1387 TOKEN_GETMAD($5,$$,')'); 1388 } 1389 | WORD 1390 | listop 1391 | YADAYADA 1392 { 1393 $$ = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0), 1394 newSVOP(OP_CONST, 0, newSVpvs("Unimplemented"))); 1395 TOKEN_GETMAD($1,$$,'X'); 1396 } 1397 | PLUGEXPR 1398 ; 1399 1400 /* "my" declarations, with optional attributes */ 1401 myattrterm: MY myterm myattrlist 1402 { $$ = my_attrs($2,$3); 1403 DO_MAD( 1404 token_getmad($1,$$,'d'); 1405 append_madprops($3->op_madprop, $$, 'a'); 1406 $3->op_madprop = 0; 1407 ); 1408 } 1409 | MY myterm 1410 { $$ = localize($2,IVAL($1)); 1411 TOKEN_GETMAD($1,$$,'d'); 1412 } 1413 ; 1414 1415 /* Things that can be "my"'d */ 1416 myterm : '(' expr ')' 1417 { $$ = sawparens($2); 1418 TOKEN_GETMAD($1,$$,'('); 1419 TOKEN_GETMAD($3,$$,')'); 1420 } 1421 | '(' ')' 1422 { $$ = sawparens(newNULLLIST()); 1423 TOKEN_GETMAD($1,$$,'('); 1424 TOKEN_GETMAD($2,$$,')'); 1425 } 1426 | scalar %prec '(' 1427 { $$ = $1; } 1428 | hsh %prec '(' 1429 { $$ = $1; } 1430 | ary %prec '(' 1431 { $$ = $1; } 1432 ; 1433 1434 /* Basic list expressions */ 1435 optlistexpr: /* NULL */ %prec PREC_LOW 1436 { $$ = (OP*)NULL; } 1437 | listexpr %prec PREC_LOW 1438 { $$ = $1; } 1439 ; 1440 1441 optexpr: /* NULL */ 1442 { $$ = (OP*)NULL; } 1443 | expr 1444 { $$ = $1; } 1445 ; 1446 1447 /* A little bit of trickery to make "for my $foo (@bar)" actually be 1448 lexical */ 1449 my_scalar: scalar 1450 { PL_parser->in_my = 0; $$ = my($1); } 1451 ; 1452 1453 amper : '&' indirob 1454 { $$ = newCVREF(IVAL($1),$2); 1455 TOKEN_GETMAD($1,$$,'&'); 1456 } 1457 ; 1458 1459 scalar : '$' indirob 1460 { $$ = newSVREF($2); 1461 TOKEN_GETMAD($1,$$,'$'); 1462 } 1463 ; 1464 1465 ary : '@' indirob 1466 { $$ = newAVREF($2); 1467 if ($$) $$->op_private |= IVAL($1); 1468 TOKEN_GETMAD($1,$$,'@'); 1469 } 1470 ; 1471 1472 hsh : '%' indirob 1473 { $$ = newHVREF($2); 1474 if ($$) $$->op_private |= IVAL($1); 1475 TOKEN_GETMAD($1,$$,'%'); 1476 } 1477 ; 1478 1479 arylen : DOLSHARP indirob 1480 { $$ = newAVREF($2); 1481 TOKEN_GETMAD($1,$$,'l'); 1482 } 1483 | term ARROW DOLSHARP '*' 1484 { $$ = newAVREF($1); 1485 TOKEN_GETMAD($3,$$,'l'); 1486 } 1487 ; 1488 1489 star : '*' indirob 1490 { $$ = newGVREF(0,$2); 1491 TOKEN_GETMAD($1,$$,'*'); 1492 } 1493 ; 1494 1495 sliceme : ary 1496 | term ARROW '@' 1497 { $$ = newAVREF($1); 1498 TOKEN_GETMAD($3,$$,'@'); 1499 } 1500 ; 1501 1502 kvslice : hsh 1503 | term ARROW '%' 1504 { $$ = newHVREF($1); 1505 TOKEN_GETMAD($3,$$,'@'); 1506 } 1507 ; 1508 1509 gelem : star 1510 | term ARROW '*' 1511 { $$ = newGVREF(0,$1); 1512 TOKEN_GETMAD($3,$$,'*'); 1513 } 1514 ; 1515 1516 /* Indirect objects */ 1517 indirob : WORD 1518 { $$ = scalar($1); } 1519 | scalar %prec PREC_LOW 1520 { $$ = scalar($1); } 1521 | block 1522 { $$ = op_scope($1); } 1523 1524 | PRIVATEREF 1525 { $$ = $1; } 1526 ; 1527