This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: [ PATCH perl@8956 ] new debug option -DR shows ref counts
[perl5.git] / perly.y
1 /*    perly.y
2  *
3  *    Copyright (c) 1991-2001, Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9
10 /*
11  * 'I see,' laughed Strider.  'I look foul and feel fair.  Is that it?
12  * All that is gold does not glitter, not all those who wander are lost.'
13  */
14
15 %{
16 #include "EXTERN.h"
17 #define PERL_IN_PERLY_C
18 #include "perl.h"
19
20 #define dep() deprecate("\"do\" to call subroutines")
21
22 /* stuff included here to make perly_c.diff apply better */
23
24 #define yydebug     PL_yydebug
25 #define yynerrs     PL_yynerrs
26 #define yyerrflag   PL_yyerrflag
27 #define yychar      PL_yychar
28 #define yyval       PL_yyval
29 #define yylval      PL_yylval
30
31 struct ysv {
32     short* yyss;
33     YYSTYPE* yyvs;
34     int oldyydebug;
35     int oldyynerrs;
36     int oldyyerrflag;
37     int oldyychar;
38     YYSTYPE oldyyval;
39     YYSTYPE oldyylval;
40 };
41
42 static void yydestruct(pTHXo_ void *ptr);
43
44 %}
45
46 %start prog
47
48 %{
49 #if 0 /* get this from perly.h instead */
50 %}
51
52 %union {
53     I32 ival;
54     char *pval;
55     OP *opval;
56     GV *gvval;
57 }
58
59 %{
60 #endif /* 0 */
61
62 #ifdef USE_PURE_BISON
63 #define YYLEX_PARAM (&yychar)
64 #define yylex yylex_r
65 #endif
66
67 %}
68
69 %token <ival> '{'
70
71 %token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF
72 %token <opval> FUNC0SUB UNIOPSUB LSTOPSUB
73 %token <pval> LABEL
74 %token <ival> FORMAT SUB ANONSUB PACKAGE USE
75 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
76 %token <ival> LOOPEX DOTDOT
77 %token <ival> FUNC0 FUNC1 FUNC UNIOP LSTOP
78 %token <ival> RELOP EQOP MULOP ADDOP
79 %token <ival> DOLSHARP DO HASHBRACK NOAMP
80 %token <ival> LOCAL MY MYSUB
81 %token COLONATTR
82
83 %type <ival> prog decl format startsub startanonsub startformsub
84 %type <ival> remember mremember '&'
85 %type <opval> block mblock lineseq line loop cond else
86 %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
87 %type <opval> argexpr nexpr texpr iexpr mexpr mnexpr mtexpr miexpr
88 %type <opval> listexpr listexprcom indirob listop method
89 %type <opval> formname subname proto subbody cont my_scalar
90 %type <opval> subattrlist myattrlist mysubrout myattrterm myterm
91 %type <pval> label
92
93 %nonassoc PREC_LOW
94 %nonassoc LOOPEX
95
96 %left <ival> OROP
97 %left ANDOP
98 %right NOTOP
99 %nonassoc LSTOP LSTOPSUB
100 %left ','
101 %right <ival> ASSIGNOP
102 %right '?' ':'
103 %nonassoc DOTDOT
104 %left OROR
105 %left ANDAND
106 %left <ival> BITOROP
107 %left <ival> BITANDOP
108 %nonassoc EQOP
109 %nonassoc RELOP
110 %nonassoc UNIOP UNIOPSUB
111 %left <ival> SHIFTOP
112 %left ADDOP
113 %left MULOP
114 %left <ival> MATCHOP
115 %right '!' '~' UMINUS REFGEN
116 %right <ival> POWOP
117 %nonassoc PREINC PREDEC POSTINC POSTDEC
118 %left ARROW
119 %nonassoc <ival> ')'
120 %left '('
121 %left '[' '{'
122
123 %% /* RULES */
124
125 prog    :       /* NULL */
126                 {
127 #if defined(YYDEBUG) && defined(DEBUGGING)
128                     yydebug = (DEBUG_p_TEST);
129 #endif
130                     PL_expect = XSTATE;
131                 }
132         /*CONTINUED*/   lineseq
133                         { newPROG($2); }
134         ;
135
136 block   :       '{' remember lineseq '}'
137                         { if (PL_copline > (line_t)$1)
138                               PL_copline = $1;
139                           $$ = block_end($2, $3); }
140         ;
141
142 remember:       /* NULL */      /* start a full lexical scope */
143                         { $$ = block_start(TRUE); }
144         ;
145
146 mblock  :       '{' mremember lineseq '}'
147                         { if (PL_copline > (line_t)$1)
148                               PL_copline = $1;
149                           $$ = block_end($2, $3); }
150         ;
151
152 mremember:      /* NULL */      /* start a partial lexical scope */
153                         { $$ = block_start(FALSE); }
154         ;
155
156 lineseq :       /* NULL */
157                         { $$ = Nullop; }
158         |       lineseq decl
159                         { $$ = $1; }
160         |       lineseq line
161                         {   $$ = append_list(OP_LINESEQ,
162                                 (LISTOP*)$1, (LISTOP*)$2);
163                             PL_pad_reset_pending = TRUE;
164                             if ($1 && $2) PL_hints |= HINT_BLOCK_SCOPE; }
165         ;
166
167 line    :       label cond
168                         { $$ = newSTATEOP(0, $1, $2); }
169         |       loop    /* loops add their own labels */
170         |       label ';'
171                         { if ($1 != Nullch) {
172                               $$ = newSTATEOP(0, $1, newOP(OP_NULL, 0));
173                             }
174                             else {
175                               $$ = Nullop;
176                               PL_copline = NOLINE;
177                             }
178                             PL_expect = XSTATE; }
179         |       label sideff ';'
180                         { $$ = newSTATEOP(0, $1, $2);
181                           PL_expect = XSTATE; }
182         ;
183
184 sideff  :       error
185                         { $$ = Nullop; }
186         |       expr
187                         { $$ = $1; }
188         |       expr IF expr
189                         { $$ = newLOGOP(OP_AND, 0, $3, $1); }
190         |       expr UNLESS expr
191                         { $$ = newLOGOP(OP_OR, 0, $3, $1); }
192         |       expr WHILE expr
193                         { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); }
194         |       expr UNTIL iexpr
195                         { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);}
196         |       expr FOR expr
197                         { $$ = newFOROP(0, Nullch, $2,
198                                         Nullop, $3, $1, Nullop); }
199         ;
200
201 else    :       /* NULL */
202                         { $$ = Nullop; }
203         |       ELSE mblock
204                         { ($2)->op_flags |= OPf_PARENS; $$ = scope($2); }
205         |       ELSIF '(' mexpr ')' mblock else
206                         { PL_copline = $1;
207                             $$ = newCONDOP(0, $3, scope($5), $6);
208                             PL_hints |= HINT_BLOCK_SCOPE; }
209         ;
210
211 cond    :       IF '(' remember mexpr ')' mblock else
212                         { PL_copline = $1;
213                             $$ = block_end($3,
214                                    newCONDOP(0, $4, scope($6), $7)); }
215         |       UNLESS '(' remember miexpr ')' mblock else
216                         { PL_copline = $1;
217                             $$ = block_end($3,
218                                    newCONDOP(0, $4, scope($6), $7)); }
219         ;
220
221 cont    :       /* NULL */
222                         { $$ = Nullop; }
223         |       CONTINUE block
224                         { $$ = scope($2); }
225         ;
226
227 loop    :       label WHILE '(' remember mtexpr ')' mblock cont
228                         { PL_copline = $2;
229                             $$ = block_end($4,
230                                    newSTATEOP(0, $1,
231                                      newWHILEOP(0, 1, (LOOP*)Nullop,
232                                                 $2, $5, $7, $8))); }
233         |       label UNTIL '(' remember miexpr ')' mblock cont
234                         { PL_copline = $2;
235                             $$ = block_end($4,
236                                    newSTATEOP(0, $1,
237                                      newWHILEOP(0, 1, (LOOP*)Nullop,
238                                                 $2, $5, $7, $8))); }
239         |       label FOR MY remember my_scalar '(' mexpr ')' mblock cont
240                         { $$ = block_end($4,
241                                  newFOROP(0, $1, $2, $5, $7, $9, $10)); }
242         |       label FOR scalar '(' remember mexpr ')' mblock cont
243                         { $$ = block_end($5,
244                                  newFOROP(0, $1, $2, mod($3, OP_ENTERLOOP),
245                                           $6, $8, $9)); }
246         |       label FOR '(' remember mexpr ')' mblock cont
247                         { $$ = block_end($4,
248                                  newFOROP(0, $1, $2, Nullop, $5, $7, $8)); }
249         |       label FOR '(' remember mnexpr ';' mtexpr ';' mnexpr ')' mblock
250                         /* basically fake up an initialize-while lineseq */
251                         { OP *forop = append_elem(OP_LINESEQ,
252                                         scalar($5),
253                                         newWHILEOP(0, 1, (LOOP*)Nullop,
254                                                    $2, scalar($7),
255                                                    $11, scalar($9)));
256                           PL_copline = $2;
257                           $$ = block_end($4, newSTATEOP(0, $1, forop)); }
258         |       label block cont  /* a block is a loop that happens once */
259                         { $$ = newSTATEOP(0, $1,
260                                  newWHILEOP(0, 1, (LOOP*)Nullop,
261                                             NOLINE, Nullop, $2, $3)); }
262         ;
263
264 nexpr   :       /* NULL */
265                         { $$ = Nullop; }
266         |       sideff
267         ;
268
269 texpr   :       /* NULL means true */
270                         { (void)scan_num("1", &yylval); $$ = yylval.opval; }
271         |       expr
272         ;
273
274 iexpr   :       expr
275                         { $$ = invert(scalar($1)); }
276         ;
277
278 mexpr   :       expr
279                         { $$ = $1; intro_my(); }
280         ;
281
282 mnexpr  :       nexpr
283                         { $$ = $1; intro_my(); }
284         ;
285
286 mtexpr  :       texpr
287                         { $$ = $1; intro_my(); }
288         ;
289
290 miexpr  :       iexpr
291                         { $$ = $1; intro_my(); }
292         ;
293
294 label   :       /* empty */
295                         { $$ = Nullch; }
296         |       LABEL
297         ;
298
299 decl    :       format
300                         { $$ = 0; }
301         |       subrout
302                         { $$ = 0; }
303         |       mysubrout
304                         { $$ = 0; }
305         |       package
306                         { $$ = 0; }
307         |       use
308                         { $$ = 0; }
309         ;
310
311 format  :       FORMAT startformsub formname block
312                         { newFORM($2, $3, $4); }
313         ;
314
315 formname:       WORD            { $$ = $1; }
316         |       /* NULL */      { $$ = Nullop; }
317         ;
318
319 mysubrout:      MYSUB startsub subname proto subattrlist subbody
320                         { newMYSUB($2, $3, $4, $5, $6); }
321         ;
322
323 subrout :       SUB startsub subname proto subattrlist subbody
324                         { newATTRSUB($2, $3, $4, $5, $6); }
325         ;
326
327 startsub:       /* NULL */      /* start a regular subroutine scope */
328                         { $$ = start_subparse(FALSE, 0); }
329         ;
330
331 startanonsub:   /* NULL */      /* start an anonymous subroutine scope */
332                         { $$ = start_subparse(FALSE, CVf_ANON); }
333         ;
334
335 startformsub:   /* NULL */      /* start a format subroutine scope */
336                         { $$ = start_subparse(TRUE, 0); }
337         ;
338
339 subname :       WORD    { STRLEN n_a; char *name = SvPV(((SVOP*)$1)->op_sv,n_a);
340                           if (strEQ(name, "BEGIN") || strEQ(name, "END")
341                               || strEQ(name, "INIT") || strEQ(name, "CHECK"))
342                               CvSPECIAL_on(PL_compcv);
343                           $$ = $1; }
344         ;
345
346 proto   :       /* NULL */
347                         { $$ = Nullop; }
348         |       THING
349         ;
350
351 subattrlist:    /* NULL */
352                         { $$ = Nullop; }
353         |       COLONATTR THING
354                         { $$ = $2; }
355         |       COLONATTR
356                         { $$ = Nullop; }
357         ;
358
359 myattrlist:     COLONATTR THING
360                         { $$ = $2; }
361         |       COLONATTR
362                         { $$ = Nullop; }
363         ;
364
365 subbody :       block   { $$ = $1; }
366         |       ';'     { $$ = Nullop; PL_expect = XSTATE; }
367         ;
368
369 package :       PACKAGE WORD ';'
370                         { package($2); }
371         |       PACKAGE ';'
372                         { package(Nullop); }
373         ;
374
375 use     :       USE startsub
376                         { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
377                     WORD WORD listexpr ';'
378                         { utilize($1, $2, $4, $5, $6); }
379         ;
380
381 expr    :       expr ANDOP expr
382                         { $$ = newLOGOP(OP_AND, 0, $1, $3); }
383         |       expr OROP expr
384                         { $$ = newLOGOP($2, 0, $1, $3); }
385         |       argexpr %prec PREC_LOW
386         ;
387
388 argexpr :       argexpr ','
389                         { $$ = $1; }
390         |       argexpr ',' term
391                         { $$ = append_elem(OP_LIST, $1, $3); }
392         |       term %prec PREC_LOW
393         ;
394
395 listop  :       LSTOP indirob argexpr
396                         { $$ = convert($1, OPf_STACKED,
397                                 prepend_elem(OP_LIST, newGVREF($1,$2), $3) ); }
398         |       FUNC '(' indirob expr ')'
399                         { $$ = convert($1, OPf_STACKED,
400                                 prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); }
401         |       term ARROW method '(' listexprcom ')'
402                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
403                                 append_elem(OP_LIST,
404                                     prepend_elem(OP_LIST, scalar($1), $5),
405                                     newUNOP(OP_METHOD, 0, $3))); }
406         |       term ARROW method
407                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
408                                 append_elem(OP_LIST, scalar($1),
409                                     newUNOP(OP_METHOD, 0, $3))); }
410         |       METHOD indirob listexpr
411                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
412                                 append_elem(OP_LIST,
413                                     prepend_elem(OP_LIST, $2, $3),
414                                     newUNOP(OP_METHOD, 0, $1))); }
415         |       FUNCMETH indirob '(' listexprcom ')'
416                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
417                                 append_elem(OP_LIST,
418                                     prepend_elem(OP_LIST, $2, $4),
419                                     newUNOP(OP_METHOD, 0, $1))); }
420         |       LSTOP listexpr
421                         { $$ = convert($1, 0, $2); }
422         |       FUNC '(' listexprcom ')'
423                         { $$ = convert($1, 0, $3); }
424         |       LSTOPSUB startanonsub block
425                         { $3 = newANONATTRSUB($2, 0, Nullop, $3); }
426                     listexpr            %prec LSTOP
427                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
428                                  append_elem(OP_LIST,
429                                    prepend_elem(OP_LIST, $3, $5), $1)); }
430         ;
431
432 method  :       METHOD
433         |       scalar
434         ;
435
436 subscripted:    star '{' expr ';' '}'
437                         { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3)); }
438         |       scalar '[' expr ']'
439                         { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); }
440         |       term ARROW '[' expr ']'
441                         { $$ = newBINOP(OP_AELEM, 0,
442                                         ref(newAVREF($1),OP_RV2AV),
443                                         scalar($4));}
444         |       subscripted '[' expr ']'
445                         { $$ = newBINOP(OP_AELEM, 0,
446                                         ref(newAVREF($1),OP_RV2AV),
447                                         scalar($3));}
448         |       scalar '{' expr ';' '}'
449                         { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
450                             PL_expect = XOPERATOR; }
451         |       term ARROW '{' expr ';' '}'
452                         { $$ = newBINOP(OP_HELEM, 0,
453                                         ref(newHVREF($1),OP_RV2HV),
454                                         jmaybe($4));
455                             PL_expect = XOPERATOR; }
456         |       subscripted '{' expr ';' '}'
457                         { $$ = newBINOP(OP_HELEM, 0,
458                                         ref(newHVREF($1),OP_RV2HV),
459                                         jmaybe($3));
460                             PL_expect = XOPERATOR; }
461         |       term ARROW '(' ')'
462                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
463                                    newCVREF(0, scalar($1))); }
464         |       term ARROW '(' expr ')'
465                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
466                                    append_elem(OP_LIST, $4,
467                                        newCVREF(0, scalar($1)))); }
468
469         |       subscripted '(' expr ')'
470                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
471                                    append_elem(OP_LIST, $3,
472                                                newCVREF(0, scalar($1)))); }
473         |       subscripted '(' ')'
474                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
475                                    newCVREF(0, scalar($1))); }
476
477
478
479 term    :       term ASSIGNOP term
480                         { $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); }
481         |       term POWOP term
482                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
483         |       term MULOP term
484                         {   if ($2 != OP_REPEAT)
485                                 scalar($1);
486                             $$ = newBINOP($2, 0, $1, scalar($3)); }
487         |       term ADDOP term
488                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
489         |       term SHIFTOP term
490                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
491         |       term RELOP term
492                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
493         |       term EQOP term
494                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
495         |       term BITANDOP term
496                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
497         |       term BITOROP term
498                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
499         |       term DOTDOT term
500                         { $$ = newRANGE($2, scalar($1), scalar($3));}
501         |       term ANDAND term
502                         { $$ = newLOGOP(OP_AND, 0, $1, $3); }
503         |       term OROR term
504                         { $$ = newLOGOP(OP_OR, 0, $1, $3); }
505         |       term '?' term ':' term
506                         { $$ = newCONDOP(0, $1, $3, $5); }
507         |       term MATCHOP term
508                         { $$ = bind_match($2, $1, $3); }
509
510         |       '-' term %prec UMINUS
511                         { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); }
512         |       '+' term %prec UMINUS
513                         { $$ = $2; }
514         |       '!' term
515                         { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
516         |       '~' term
517                         { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));}
518         |       REFGEN term
519                         { $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN)); }
520         |       term POSTINC
521                         { $$ = newUNOP(OP_POSTINC, 0,
522                                         mod(scalar($1), OP_POSTINC)); }
523         |       term POSTDEC
524                         { $$ = newUNOP(OP_POSTDEC, 0,
525                                         mod(scalar($1), OP_POSTDEC)); }
526         |       PREINC term
527                         { $$ = newUNOP(OP_PREINC, 0,
528                                         mod(scalar($2), OP_PREINC)); }
529         |       PREDEC term
530                         { $$ = newUNOP(OP_PREDEC, 0,
531                                         mod(scalar($2), OP_PREDEC)); }
532         |       myattrterm      %prec UNIOP
533                         { $$ = $1; }
534         |       LOCAL term      %prec UNIOP
535                         { $$ = localize($2,$1); }
536         |       '(' expr ')'
537                         { $$ = sawparens($2); }
538         |       '(' ')'
539                         { $$ = sawparens(newNULLLIST()); }
540         |       '[' expr ']'
541                         { $$ = newANONLIST($2); }
542         |       '[' ']'
543                         { $$ = newANONLIST(Nullop); }
544         |       HASHBRACK expr ';' '}'                  %prec '('
545                         { $$ = newANONHASH($2); }
546         |       HASHBRACK ';' '}'                               %prec '('
547                         { $$ = newANONHASH(Nullop); }
548         |       ANONSUB startanonsub proto subattrlist block    %prec '('
549                         { $$ = newANONATTRSUB($2, $3, $4, $5); }
550         |       scalar  %prec '('
551                         { $$ = $1; }
552         |       star    %prec '('
553                         { $$ = $1; }
554         |       hsh     %prec '('
555                         { $$ = $1; }
556         |       ary     %prec '('
557                         { $$ = $1; }
558         |       arylen  %prec '('
559                         { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
560         |       subscripted
561                         { $$ = $1; }
562         |       '(' expr ')' '[' expr ']'
563                         { $$ = newSLICEOP(0, $5, $2); }
564         |       '(' ')' '[' expr ']'
565                         { $$ = newSLICEOP(0, $4, Nullop); }
566         |       ary '[' expr ']'
567                         { $$ = prepend_elem(OP_ASLICE,
568                                 newOP(OP_PUSHMARK, 0),
569                                     newLISTOP(OP_ASLICE, 0,
570                                         list($3),
571                                         ref($1, OP_ASLICE))); }
572         |       ary '{' expr ';' '}'
573                         { $$ = prepend_elem(OP_HSLICE,
574                                 newOP(OP_PUSHMARK, 0),
575                                     newLISTOP(OP_HSLICE, 0,
576                                         list($3),
577                                         ref(oopsHV($1), OP_HSLICE)));
578                             PL_expect = XOPERATOR; }
579         |       THING   %prec '('
580                         { $$ = $1; }
581         |       amper
582                         { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
583         |       amper '(' ')'
584                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
585         |       amper '(' expr ')'
586                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
587                             append_elem(OP_LIST, $3, scalar($1))); }
588         |       NOAMP WORD listexpr
589                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
590                             append_elem(OP_LIST, $3, scalar($2))); }
591         |       DO term %prec UNIOP
592                         { $$ = dofile($2); }
593         |       DO block        %prec '('
594                         { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); }
595         |       DO WORD '(' ')'
596                         { $$ = newUNOP(OP_ENTERSUB,
597                             OPf_SPECIAL|OPf_STACKED,
598                             prepend_elem(OP_LIST,
599                                 scalar(newCVREF(
600                                     (OPpENTERSUB_AMPER<<8),
601                                     scalar($2)
602                                 )),Nullop)); dep();}
603         |       DO WORD '(' expr ')'
604                         { $$ = newUNOP(OP_ENTERSUB,
605                             OPf_SPECIAL|OPf_STACKED,
606                             append_elem(OP_LIST,
607                                 $4,
608                                 scalar(newCVREF(
609                                     (OPpENTERSUB_AMPER<<8),
610                                     scalar($2)
611                                 )))); dep();}
612         |       DO scalar '(' ')'
613                         { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
614                             prepend_elem(OP_LIST,
615                                 scalar(newCVREF(0,scalar($2))), Nullop)); dep();}
616         |       DO scalar '(' expr ')'
617                         { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
618                             prepend_elem(OP_LIST,
619                                 $4,
620                                 scalar(newCVREF(0,scalar($2))))); dep();}
621         |       LOOPEX
622                         { $$ = newOP($1, OPf_SPECIAL);
623                             PL_hints |= HINT_BLOCK_SCOPE; }
624         |       LOOPEX term
625                         { $$ = newLOOPEX($1,$2); }
626         |       NOTOP argexpr
627                         { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
628         |       UNIOP
629                         { $$ = newOP($1, 0); }
630         |       UNIOP block
631                         { $$ = newUNOP($1, 0, $2); }
632         |       UNIOP term
633                         { $$ = newUNOP($1, 0, $2); }
634         |       UNIOPSUB term
635                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
636                             append_elem(OP_LIST, $2, scalar($1))); }
637         |       FUNC0
638                         { $$ = newOP($1, 0); }
639         |       FUNC0 '(' ')'
640                         { $$ = newOP($1, 0); }
641         |       FUNC0SUB
642                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
643                                 scalar($1)); }
644         |       FUNC1 '(' ')'
645                         { $$ = newOP($1, OPf_SPECIAL); }
646         |       FUNC1 '(' expr ')'
647                         { $$ = newUNOP($1, 0, $3); }
648         |       PMFUNC '(' term ')'
649                         { $$ = pmruntime($1, $3, Nullop); }
650         |       PMFUNC '(' term ',' term ')'
651                         { $$ = pmruntime($1, $3, $5); }
652         |       WORD
653         |       listop
654         ;
655
656 myattrterm:     MY myterm myattrlist
657                         { $$ = my_attrs($2,$3); }
658         |       MY myterm
659                         { $$ = localize($2,$1); }
660         ;
661
662 myterm  :       '(' expr ')'
663                         { $$ = sawparens($2); }
664         |       '(' ')'
665                         { $$ = sawparens(newNULLLIST()); }
666         |       scalar  %prec '('
667                         { $$ = $1; }
668         |       hsh     %prec '('
669                         { $$ = $1; }
670         |       ary     %prec '('
671                         { $$ = $1; }
672         ;
673
674 listexpr:       /* NULL */ %prec PREC_LOW
675                         { $$ = Nullop; }
676         |       argexpr    %prec PREC_LOW
677                         { $$ = $1; }
678         ;
679
680 listexprcom:    /* NULL */
681                         { $$ = Nullop; }
682         |       expr
683                         { $$ = $1; }
684         |       expr ','
685                         { $$ = $1; }
686         ;
687
688 my_scalar:      scalar
689                         { PL_in_my = 0; $$ = my($1); }
690         ;
691
692 amper   :       '&' indirob
693                         { $$ = newCVREF($1,$2); }
694         ;
695
696 scalar  :       '$' indirob
697                         { $$ = newSVREF($2); }
698         ;
699
700 ary     :       '@' indirob
701                         { $$ = newAVREF($2); }
702         ;
703
704 hsh     :       '%' indirob
705                         { $$ = newHVREF($2); }
706         ;
707
708 arylen  :       DOLSHARP indirob
709                         { $$ = newAVREF($2); }
710         ;
711
712 star    :       '*' indirob
713                         { $$ = newGVREF(0,$2); }
714         ;
715
716 indirob :       WORD
717                         { $$ = scalar($1); }
718         |       scalar %prec PREC_LOW
719                         { $$ = scalar($1);  }
720         |       block
721                         { $$ = scope($1); }
722
723         |       PRIVATEREF
724                         { $$ = $1; }
725         ;
726
727 %% /* PROGRAM */
728
729 /* more stuff added to make perly_c.diff easier to apply */
730
731 #ifdef yyparse
732 #undef yyparse
733 #endif
734 #define yyparse() Perl_yyparse(pTHX)
735