/* perly.y * * Copyright (c) 1991-2002, 2003, 2004 Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * */ /* * 'I see,' laughed Strider. 'I look foul and feel fair. Is that it? * All that is gold does not glitter, not all those who wander are lost.' */ /* This file holds the grammar for the Perl language. If edited, you need * to run regen_perly.pl, which re-creates the files perly.h, perly.tab * and perly.act which are derived from this. * * The main job of of this grammar is to call the various newFOO() * functions in op.c to build a syntax tree of OP structs. * It relies on the lexer in toke.c to do the tokenizing. */ /* Make the parser re-entrant. */ %pure_parser %start prog %union { I32 ival; char *pval; OP *opval; GV *gvval; } %token '{' %token WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF %token FUNC0SUB UNIOPSUB LSTOPSUB %token LABEL %token FORMAT SUB ANONSUB PACKAGE USE %token WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR %token LOOPEX DOTDOT %token FUNC0 FUNC1 FUNC UNIOP LSTOP %token RELOP EQOP MULOP ADDOP %token DOLSHARP DO HASHBRACK NOAMP %token LOCAL MY MYSUB %token COLONATTR %type prog decl format startsub startanonsub startformsub mintro %type progstart remember mremember '&' savescope %type block mblock lineseq line loop cond else %type expr term subscripted scalar ary hsh arylen star amper sideff %type argexpr nexpr texpr iexpr mexpr mnexpr miexpr %type listexpr listexprcom indirob listop method %type formname subname proto subbody cont my_scalar %type subattrlist myattrlist mysubrout myattrterm myterm %type termbinop termunop anonymous termdo %type label %nonassoc PREC_LOW %nonassoc LOOPEX %left OROP DOROP %left ANDOP %right NOTOP %nonassoc LSTOP LSTOPSUB %left ',' %right ASSIGNOP %right '?' ':' %nonassoc DOTDOT %left OROR DORDOR %left ANDAND %left BITOROP %left BITANDOP %nonassoc EQOP %nonassoc RELOP %nonassoc UNIOP UNIOPSUB %left SHIFTOP %left ADDOP %left MULOP %left MATCHOP %right '!' '~' UMINUS REFGEN %right POWOP %nonassoc PREINC PREDEC POSTINC POSTDEC %left ARROW %nonassoc ')' %left '(' %left '[' '{' %% /* RULES */ /* The whole program */ prog : progstart /*CONTINUED*/ lineseq 105468 { $$ = $1; newPROG(block_end($1,$2)); } 105460 ; /* An ordinary block */ block : '{' remember lineseq '}' 441450 { if (PL_copline > (line_t)$1) 441450 PL_copline = (line_t)$1; 441450 $$ = block_end($2, $3); } 441450 ; remember: /* NULL */ /* start a full lexical scope */ 812903 { $$ = block_start(TRUE); } 812903 ; progstart: { 106267 PL_expect = XSTATE; $$ = block_start(TRUE); } 106267 ; mblock : '{' mremember lineseq '}' 536999 { if (PL_copline > (line_t)$1) 536999 PL_copline = (line_t)$1; 536999 $$ = block_end($2, $3); } 536999 ; mremember: /* NULL */ /* start a partial lexical scope */ 537000 { $$ = block_start(FALSE); } 537000 ; savescope: /* NULL */ /* remember stack pos in case of error */ 3802372 { $$ = PL_savestack_ix; } 3802372 /* A collection of "lines" in the program */ lineseq : /* NULL */ 1084729 { $$ = Nullop; } 1084729 | lineseq decl 407095 { $$ = $1; } 407095 | lineseq savescope line 3801789 { LEAVE_SCOPE($2); 3801789 $$ = append_list(OP_LINESEQ, (LISTOP*)$1, (LISTOP*)$3); 3801789 PL_pad_reset_pending = TRUE; 3801789 if ($1 && $3) PL_hints |= HINT_BLOCK_SCOPE; } 1894313 ; /* A "line" in the program */ line : label cond 285993 { $$ = newSTATEOP(0, $1, $2); } 285993 | loop /* loops add their own labels */ | label ';' 832256 { if ($1 != Nullch) { 312 $$ = newSTATEOP(0, $1, newOP(OP_NULL, 0)); } else { 831944 $$ = Nullop; 831944 PL_copline = NOLINE; } 832256 PL_expect = XSTATE; } 832256 | label sideff ';' 2583029 { $$ = newSTATEOP(0, $1, $2); 2583029 PL_expect = XSTATE; } 2583029 ; /* An expression which may have a side-effect */ sideff : error 248 { $$ = Nullop; } 248 | expr 2240259 { $$ = $1; } 2240259 | expr IF expr 197140 { $$ = newLOGOP(OP_AND, 0, $3, $1); } 197140 | expr UNLESS expr 127406 { $$ = newLOGOP(OP_OR, 0, $3, $1); } 127406 | expr WHILE expr 14400 { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); } 14400 | expr UNTIL iexpr 60 { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);} 60 | expr FOR expr 10830 { $$ = newFOROP(0, Nullch, (line_t)$2, Nullop, $3, $1, Nullop); } 10830 ; /* else and elsif blocks */ else : /* NULL */ 188142 { $$ = Nullop; } 188142 | ELSE mblock 97851 { ($2)->op_flags |= OPf_PARENS; $$ = scope($2); } 97851 | ELSIF '(' mexpr ')' mblock else 67708 { PL_copline = (line_t)$1; 67708 $$ = newCONDOP(0, $3, scope($5), $6); 67708 PL_hints |= HINT_BLOCK_SCOPE; } 67708 ; /* Real conditional expressions */ cond : IF '(' remember mexpr ')' mblock else 251914 { PL_copline = (line_t)$1; 251914 $$ = block_end($3, newCONDOP(0, $4, scope($6), $7)); } 251914 | UNLESS '(' remember miexpr ')' mblock else 34079 { PL_copline = (line_t)$1; 34079 $$ = block_end($3, newCONDOP(0, $4, scope($6), $7)); } 34079 ; /* Continue blocks */ cont : /* NULL */ 93956 { $$ = Nullop; } 93956 | CONTINUE block 756 { $$ = scope($2); } 756 ; /* Loops: while, until, for, and a bare block */ loop : label WHILE '(' remember texpr ')' mintro mblock cont 19228 { PL_copline = (line_t)$2; 19228 $$ = block_end($4, newSTATEOP(0, $1, newWHILEOP(0, 1, (LOOP*)Nullop, $2, $5, $8, $9, $7))); } 19227 | label UNTIL '(' remember iexpr ')' mintro mblock cont 144 { PL_copline = (line_t)$2; 144 $$ = block_end($4, newSTATEOP(0, $1, newWHILEOP(0, 1, (LOOP*)Nullop, $2, $5, $8, $9, $7))); } 144 | label FOR MY remember my_scalar '(' mexpr ')' mblock cont 33297 { $$ = block_end($4, newFOROP(0, $1, (line_t)$2, $5, $7, $9, $10)); } 33297 | label FOR scalar '(' remember mexpr ')' mblock cont 14418 { $$ = block_end($5, newFOROP(0, $1, (line_t)$2, mod($3, OP_ENTERLOOP), $6, $8, $9)); } 14418 | label FOR '(' remember mexpr ')' mblock cont 12560 { $$ = block_end($4, newFOROP(0, $1, (line_t)$2, Nullop, $5, $7, $8)); } 12560 | label FOR '(' remember mnexpr ';' texpr ';' mintro mnexpr ')' mblock /* basically fake up an initialize-while lineseq */ 5800 { OP *forop; 5800 PL_copline = (line_t)$2; 5800 forop = newSTATEOP(0, $1, newWHILEOP(0, 1, (LOOP*)Nullop, $2, scalar($7), $12, $10, $9)); 5800 if ($5) { 3190 forop = append_elem(OP_LINESEQ, newSTATEOP(0, ($1?savepv($1):Nullch), $5), forop); } 5800 $$ = block_end($4, forop); } 5800 | label block cont /* a block is a loop that happens once */ 15065 { $$ = newSTATEOP(0, $1, newWHILEOP(0, 1, (LOOP*)Nullop, NOLINE, Nullop, $2, $3, 0)); } 15065 ; /* determine whether there are any new my declarations */ mintro : /* NULL */ 25173 { $$ = (PL_min_intro_pending && PL_max_intro_pending >= PL_min_intro_pending); 25173 intro_my(); } 25173 /* Normal expression */ nexpr : /* NULL */ 4485 { $$ = Nullop; } 4485 | sideff ; /* Boolean expression */ texpr : /* NULL means true */ 1855 { (void)scan_num("1", &yylval); $$ = yylval.opval; } 1855 | expr ; /* Inverted boolean expression */ iexpr : expr 34283 { $$ = invert(scalar($1)); } 34283 ; /* Expression with its own lexical scope */ mexpr : expr 379897 { $$ = $1; intro_my(); } 379897 ; mnexpr : nexpr 11600 { $$ = $1; intro_my(); } 11600 ; miexpr : iexpr 34079 { $$ = $1; intro_my(); } 34079 ; /* Optional "MAIN:"-style loop labels */ label : /* empty */ 3795286 { $$ = Nullch; } 3795286 | LABEL ; /* Some kind of declaration - does not take part in the parse tree */ decl : format 88 { $$ = 0; } 88 | subrout 295968 { $$ = 0; } 295968 | mysubrout ###### { $$ = 0; } ###### | package 39129 { $$ = 0; } 39129 | use 71910 { $$ = 0; } 71910 ; format : FORMAT startformsub formname block 88 { newFORM($2, $3, $4); } 88 ; 86 formname: WORD { $$ = $1; } 86 | /* NULL */ { $$ = Nullop; } 3 ; /* Unimplemented "my sub foo { }" */ mysubrout: MYSUB startsub subname proto subattrlist subbody ###### { newMYSUB($2, $3, $4, $5, $6); } 296028 ; /* Subroutine definition */ subrout : SUB startsub subname proto subattrlist subbody 296028 { newATTRSUB($2, $3, $4, $5, $6); } 295968 ; startsub: /* NULL */ /* start a regular subroutine scope */ 368073 { $$ = start_subparse(FALSE, 0); } 368073 ; startanonsub: /* NULL */ /* start an anonymous subroutine scope */ 18882 { $$ = start_subparse(FALSE, CVf_ANON); } 18882 ; startformsub: /* NULL */ /* start a format subroutine scope */ 89 { $$ = start_subparse(TRUE, 0); } 89 ; /* Name of a subroutine - must be a bareword, could be special */ 296034 subname : WORD { STRLEN n_a; const char *name = SvPV_const(((SVOP*)$1)->op_sv,n_a); 296034 if (strEQ(name, "BEGIN") || strEQ(name, "END") || strEQ(name, "INIT") || strEQ(name, "CHECK")) 6607 CvSPECIAL_on(PL_compcv); 296034 $$ = $1; } 296034 ; /* Subroutine prototype */ proto : /* NULL */ 285508 { $$ = Nullop; } 285508 | THING ; /* Optional list of subroutine attributes */ subattrlist: /* NULL */ 314260 { $$ = Nullop; } 314260 | COLONATTR THING 31 { $$ = $2; } 31 | COLONATTR 78 { $$ = Nullop; } 78 ; /* List of attributes for a "my" variable declaration */ myattrlist: COLONATTR THING 46 { $$ = $2; } 46 | COLONATTR 1092 { $$ = Nullop; } 1092 ; /* Subroutine body - either null or a block */ 265309 subbody : block { $$ = $1; } 265309 | ';' { $$ = Nullop; PL_expect = XSTATE; } 30719 ; package : PACKAGE WORD ';' 39129 { package($2); } 39129 ; use : USE startsub 72039 { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ } 72039 WORD WORD listexpr ';' 72038 { utilize($1, $2, $4, $5, $6); } 71910 ; /* Ordinary expressions; logical combinations */ expr : expr ANDOP expr 45342 { $$ = newLOGOP(OP_AND, 0, $1, $3); } 45342 | expr OROP expr 55624 { $$ = newLOGOP($2, 0, $1, $3); } 55623 | expr DOROP expr 10 { $$ = newLOGOP(OP_DOR, 0, $1, $3); } 10 | argexpr %prec PREC_LOW ; /* Expressions are a list of terms joined by commas */ argexpr : argexpr ',' 21684 { $$ = $1; } 21684 | argexpr ',' term 2094485 { $$ = append_elem(OP_LIST, $1, $3); } 2094484 | term %prec PREC_LOW ; /* List operators */ listop : LSTOP indirob argexpr /* map {...} @args or print $fh @args */ 46226 { $$ = convert($1, OPf_STACKED, prepend_elem(OP_LIST, newGVREF($1,$2), $3) ); } 46225 | FUNC '(' indirob expr ')' /* print ($fh @args */ 28 { $$ = convert($1, OPf_STACKED, prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); } 28 | term ARROW method '(' listexprcom ')' /* $foo->bar(list) */ 193680 { $$ = convert(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, prepend_elem(OP_LIST, scalar($1), $5), newUNOP(OP_METHOD, 0, $3))); } 193678 | term ARROW method /* $foo->bar */ 46943 { $$ = convert(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, scalar($1), newUNOP(OP_METHOD, 0, $3))); } 46943 | METHOD indirob listexpr /* new Class @args */ 4422 { $$ = convert(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, prepend_elem(OP_LIST, $2, $3), newUNOP(OP_METHOD, 0, $1))); } 4422 | FUNCMETH indirob '(' listexprcom ')' /* method $object (@args) */ 1024 { $$ = convert(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, prepend_elem(OP_LIST, $2, $4), newUNOP(OP_METHOD, 0, $1))); } 1024 | LSTOP listexpr /* print @args */ 374068 { $$ = convert($1, 0, $2); } 373981 | FUNC '(' listexprcom ')' /* print (@args) */ 737737 { $$ = convert($1, 0, $3); } 737733 | LSTOPSUB startanonsub block /* sub f(&@); f { foo } ... */ 547 { $3 = newANONATTRSUB($2, 0, Nullop, $3); } 547 listexpr %prec LSTOP /* ... @bar */ 547 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, prepend_elem(OP_LIST, $3, $5), $1)); } 547 ; /* Names of methods. May use $object->$methodname */ method : METHOD | scalar ; /* Some kind of subscripted expression */ subscripted: star '{' expr ';' '}' /* *main::{something} */ /* In this and all the hash accessors, ';' is * provided by the tokeniser */ 2189 { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3)); 2188 PL_expect = XOPERATOR; } 2188 | scalar '[' expr ']' /* $array[$element] */ 131064 { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); } 131063 | term ARROW '[' expr ']' /* somearef->[$element] */ 30971 { $$ = newBINOP(OP_AELEM, 0, ref(newAVREF($1),OP_RV2AV), scalar($4));} 30970 | subscripted '[' expr ']' /* $foo->[$bar]->[$baz] */ 6012 { $$ = newBINOP(OP_AELEM, 0, ref(newAVREF($1),OP_RV2AV), scalar($3));} 6012 | scalar '{' expr ';' '}' /* $foo->{bar();} */ 241713 { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3)); 241712 PL_expect = XOPERATOR; } 241712 | term ARROW '{' expr ';' '}' /* somehref->{bar();} */ 220404 { $$ = newBINOP(OP_HELEM, 0, ref(newHVREF($1),OP_RV2HV), jmaybe($4)); 220402 PL_expect = XOPERATOR; } 220402 | subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */ 10058 { $$ = newBINOP(OP_HELEM, 0, ref(newHVREF($1),OP_RV2HV), jmaybe($3)); 10058 PL_expect = XOPERATOR; } 10058 | term ARROW '(' ')' /* $subref->() */ 1805 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, newCVREF(0, scalar($1))); } 1805 | term ARROW '(' expr ')' /* $subref->(@args) */ 1429 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, $4, newCVREF(0, scalar($1)))); } 1429 | subscripted '(' expr ')' /* $foo->{bar}->(@args) */ 12 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, $3, newCVREF(0, scalar($1)))); } 12 | subscripted '(' ')' /* $foo->{bar}->() */ ###### { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, newCVREF(0, scalar($1))); } ###### ; /* Binary operators between terms */ termbinop : term ASSIGNOP term /* $x = $y */ 1289935 { $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); } 1289927 | term POWOP term /* $x ** $y */ 1635 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 1634 | term MULOP term /* $x * $y, $x x $y */ 24608 { if ($2 != OP_REPEAT) 15643 scalar($1); 24608 $$ = newBINOP($2, 0, $1, scalar($3)); } 24604 | term ADDOP term /* $x + $y */ 749949 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 749944 | term SHIFTOP term /* $x >> $y, $x << $y */ 730 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 728 | term RELOP term /* $x > $y, etc. */ 67370 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 67362 | term EQOP term /* $x == $y, $x eq $y */ 270095 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 270089 | term BITANDOP term /* $x & $y */ 6487 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 6486 | term BITOROP term /* $x | $y */ 14027 { $$ = newBINOP($2, 0, scalar($1), scalar($3)); } 14025 | term DOTDOT term /* $x..$y, $x...$y */ 7553 { $$ = newRANGE($2, scalar($1), scalar($3));} 7551 | term ANDAND term /* $x && $y */ 84422 { $$ = newLOGOP(OP_AND, 0, $1, $3); } 84421 | term OROR term /* $x || $y */ 90416 { $$ = newLOGOP(OP_OR, 0, $1, $3); } 90415 | term DORDOR term /* $x // $y */ 25 { $$ = newLOGOP(OP_DOR, 0, $1, $3); } 24 | term MATCHOP term /* $x =~ /$y/ */ 178802 { $$ = bind_match($2, $1, $3); } 178802 ; /* Unary operators and terms */ termunop : '-' term %prec UMINUS /* -$x */ 29506 { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); } 29505 | '+' term %prec UMINUS /* +$x */ 1706 { $$ = $2; } 1706 | '!' term /* !$x */ 75934 { $$ = newUNOP(OP_NOT, 0, scalar($2)); } 75933 | '~' term /* ~$x */ 11980 { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));} 11979 | term POSTINC /* $x++ */ 30749 { $$ = newUNOP(OP_POSTINC, 0, mod(scalar($1), OP_POSTINC)); } 30748 | term POSTDEC /* $x-- */ 12250 { $$ = newUNOP(OP_POSTDEC, 0, mod(scalar($1), OP_POSTDEC)); } 12249 | PREINC term /* ++$x */ 7119 { $$ = newUNOP(OP_PREINC, 0, mod(scalar($2), OP_PREINC)); } 7118 | PREDEC term /* --$x */ 1897 { $$ = newUNOP(OP_PREDEC, 0, mod(scalar($2), OP_PREDEC)); } 1896 ; /* Constructors for anonymous data */ anonymous: '[' expr ']' 28195 { $$ = newANONLIST($2); } 28194 | '[' ']' 4069 { $$ = newANONLIST(Nullop); } 4069 | HASHBRACK expr ';' '}' %prec '(' /* { foo => "Bar" } */ 16670 { $$ = newANONHASH($2); } 16669 | HASHBRACK ';' '}' %prec '(' /* { } (';' by tokener) */ 8307 { $$ = newANONHASH(Nullop); } 8307 | ANONSUB startanonsub proto subattrlist block %prec '(' 18331 { $$ = newANONATTRSUB($2, $3, $4, $5); } 18330 ; /* Things called with "do" */ termdo : DO term %prec UNIOP /* do $filename */ 1083 { $$ = dofile($2); } 1082 | DO block %prec '(' /* do { code */ 16032 { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); } 16032 | DO WORD '(' ')' /* do somesub() */ 7 { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED, prepend_elem(OP_LIST, scalar(newCVREF( (OPpENTERSUB_AMPER<<8), scalar($2) 7 )),Nullop)); dep();} 7 | DO WORD '(' expr ')' /* do somesub(@args) */ 24 { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED, append_elem(OP_LIST, $4, scalar(newCVREF( (OPpENTERSUB_AMPER<<8), scalar($2) 24 )))); dep();} 24 | DO scalar '(' ')' /* do $subref () */ 2 { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED, prepend_elem(OP_LIST, 2 scalar(newCVREF(0,scalar($2))), Nullop)); dep();} 2 | DO scalar '(' expr ')' /* do $subref (@args) */ 2 { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED, prepend_elem(OP_LIST, $4, 2 scalar(newCVREF(0,scalar($2))))); dep();} 2 ; term : termbinop | termunop | anonymous | termdo | term '?' term ':' term 92869 { $$ = newCONDOP(0, $1, $3, $5); } 92868 | REFGEN term /* \$x, \@y, \%z */ 89292 { $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN)); } 89291 | myattrterm %prec UNIOP 607168 { $$ = $1; } 607168 | LOCAL term %prec UNIOP 51078 { $$ = localize($2,$1); } 51077 | '(' expr ')' 343626 { $$ = sawparens($2); } 343626 | '(' ')' 25052 { $$ = sawparens(newNULLLIST()); } 25052 | scalar %prec '(' 3619767 { $$ = $1; } 3619767 | star %prec '(' 57782 { $$ = $1; } 57782 | hsh %prec '(' 60940 { $$ = $1; } 60940 | ary %prec '(' 585022 { $$ = $1; } 585022 | arylen %prec '(' /* $#x, $#{ something } */ 9035 { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));} 9034 | subscripted 629569 { $$ = $1; } 629569 | '(' expr ')' '[' expr ']' /* list slice */ 23660 { $$ = newSLICEOP(0, $5, $2); } 23660 | '(' ')' '[' expr ']' /* empty list slice! */ ###### { $$ = newSLICEOP(0, $4, Nullop); } ###### | ary '[' expr ']' /* array slice */ 1702 { $$ = prepend_elem(OP_ASLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_ASLICE, 0, list($3), ref($1, OP_ASLICE))); } 1701 | ary '{' expr ';' '}' /* @hash{@keys} */ 10886 { $$ = prepend_elem(OP_HSLICE, newOP(OP_PUSHMARK, 0), newLISTOP(OP_HSLICE, 0, list($3), ref(oopsHV($1), OP_HSLICE))); 10885 PL_expect = XOPERATOR; } 10885 | THING %prec '(' 3226633 { $$ = $1; } 3226633 | amper /* &foo; */ 80258 { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); } 80258 | amper '(' ')' /* &foo() */ 47765 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); } 47764 | amper '(' expr ')' /* &foo(@args) */ 279715 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, $3, scalar($1))); } 279715 | NOAMP WORD listexpr /* foo(@args) */ 44754 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, $3, scalar($2))); } 44754 | LOOPEX /* loop exiting command (goto, last, dump, etc) */ 52339 { $$ = newOP($1, OPf_SPECIAL); 52336 PL_hints |= HINT_BLOCK_SCOPE; } 52336 | LOOPEX term 41465 { $$ = newLOOPEX($1,$2); } 41463 | NOTOP argexpr /* not $foo */ 9193 { $$ = newUNOP(OP_NOT, 0, scalar($2)); } 9193 | UNIOP /* Unary op, $_ implied */ 138797 { $$ = newOP($1, 0); } 138729 | UNIOP block /* eval { foo } */ 11531 { $$ = newUNOP($1, 0, $2); } 11531 | UNIOP term /* Unary op */ 352054 { $$ = newUNOP($1, 0, $2); } 352011 | UNIOPSUB term /* Sub treated as unop */ 581 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, append_elem(OP_LIST, $2, scalar($1))); } 581 | FUNC0 /* Nullary operator */ 6072 { $$ = newOP($1, 0); } 6051 | FUNC0 '(' ')' 548 { $$ = newOP($1, 0); } 548 | FUNC0SUB /* Sub treated as nullop */ 1276 { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); } 1276 | FUNC1 '(' ')' /* not () */ 4616 { $$ = $1 == OP_NOT ? newUNOP($1, 0, newSVOP(OP_CONST, 0, newSViv(0))) : newOP($1, OPf_SPECIAL); } 4616 | FUNC1 '(' expr ')' /* not($foo) */ 160012 { $$ = newUNOP($1, 0, $3); } 160012 | PMFUNC '(' argexpr ')' /* m//, s///, tr/// */ 227073 { $$ = pmruntime($1, $3, 1); } 226842 | WORD | listop ; /* "my" declarations, with optional attributes */ myattrterm: MY myterm myattrlist 1138 { $$ = my_attrs($2,$3); } 1138 | MY myterm 606030 { $$ = localize($2,$1); } 606030 ; /* Things that can be "my"'d */ myterm : '(' expr ')' 149329 { $$ = sawparens($2); } 149329 | '(' ')' ###### { $$ = sawparens(newNULLLIST()); } ###### | scalar %prec '(' 384614 { $$ = $1; } 384614 | hsh %prec '(' 29868 { $$ = $1; } 29868 | ary %prec '(' 43358 { $$ = $1; } 43358 ; /* Basic list expressions */ listexpr: /* NULL */ %prec PREC_LOW 70895 { $$ = Nullop; } 70895 | argexpr %prec PREC_LOW 424934 { $$ = $1; } 424934 ; listexprcom: /* NULL */ 32271 { $$ = Nullop; } 32271 | expr 900171 { $$ = $1; } 900171 | expr ',' ###### { $$ = $1; } ###### ; /* A little bit of trickery to make "for my $foo (@bar)" actually be lexical */ my_scalar: scalar 33297 { PL_in_my = 0; $$ = my($1); } 33297 ; amper : '&' indirob 407740 { $$ = newCVREF($1,$2); } 407739 ; scalar : '$' indirob 4547962 { $$ = newSVREF($2); } 4547961 ; ary : '@' indirob 640969 { $$ = newAVREF($2); } 640968 ; hsh : '%' indirob 90809 { $$ = newHVREF($2); } 90808 ; arylen : DOLSHARP indirob 9035 { $$ = newAVREF($2); } 9035 ; star : '*' indirob 59972 { $$ = newGVREF(0,$2); } 59971 ; /* Indirect objects */ indirob : WORD 1762690 { $$ = scalar($1); } 1762690 | scalar %prec PREC_LOW 121681 { $$ = scalar($1); } 121681 | block 113791 { $$ = scope($1); } 113791 | PRIVATEREF 3810026 { $$ = $1; } ;