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