With Damian's approval synchronize damian's modules'
[p5sagit/p5-mst-13.2.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;
252                           PL_copline = $2;
253                           forop = newSTATEOP(0, $1,
254                                             newWHILEOP(0, 1, (LOOP*)Nullop,
255                                                 $2, scalar($7),
256                                                 $11, $9));
257                           if ($5) {
258                                 forop = append_elem(OP_LINESEQ,
259                                         newSTATEOP(0, ($1?savepv($1):Nullch),
260                                                    $5),
261                                         forop);
262                           }
263
264                           $$ = block_end($4, forop); }
265         |       label block cont  /* a block is a loop that happens once */
266                         { $$ = newSTATEOP(0, $1,
267                                  newWHILEOP(0, 1, (LOOP*)Nullop,
268                                             NOLINE, Nullop, $2, $3)); }
269         ;
270
271 nexpr   :       /* NULL */
272                         { $$ = Nullop; }
273         |       sideff
274         ;
275
276 texpr   :       /* NULL means true */
277                         { (void)scan_num("1", &yylval); $$ = yylval.opval; }
278         |       expr
279         ;
280
281 iexpr   :       expr
282                         { $$ = invert(scalar($1)); }
283         ;
284
285 mexpr   :       expr
286                         { $$ = $1; intro_my(); }
287         ;
288
289 mnexpr  :       nexpr
290                         { $$ = $1; intro_my(); }
291         ;
292
293 mtexpr  :       texpr
294                         { $$ = $1; intro_my(); }
295         ;
296
297 miexpr  :       iexpr
298                         { $$ = $1; intro_my(); }
299         ;
300
301 label   :       /* empty */
302                         { $$ = Nullch; }
303         |       LABEL
304         ;
305
306 decl    :       format
307                         { $$ = 0; }
308         |       subrout
309                         { $$ = 0; }
310         |       mysubrout
311                         { $$ = 0; }
312         |       package
313                         { $$ = 0; }
314         |       use
315                         { $$ = 0; }
316         ;
317
318 format  :       FORMAT startformsub formname block
319                         { newFORM($2, $3, $4); }
320         ;
321
322 formname:       WORD            { $$ = $1; }
323         |       /* NULL */      { $$ = Nullop; }
324         ;
325
326 mysubrout:      MYSUB startsub subname proto subattrlist subbody
327                         { newMYSUB($2, $3, $4, $5, $6); }
328         ;
329
330 subrout :       SUB startsub subname proto subattrlist subbody
331                         { newATTRSUB($2, $3, $4, $5, $6); }
332         ;
333
334 startsub:       /* NULL */      /* start a regular subroutine scope */
335                         { $$ = start_subparse(FALSE, 0); }
336         ;
337
338 startanonsub:   /* NULL */      /* start an anonymous subroutine scope */
339                         { $$ = start_subparse(FALSE, CVf_ANON); }
340         ;
341
342 startformsub:   /* NULL */      /* start a format subroutine scope */
343                         { $$ = start_subparse(TRUE, 0); }
344         ;
345
346 subname :       WORD    { STRLEN n_a; char *name = SvPV(((SVOP*)$1)->op_sv,n_a);
347                           if (strEQ(name, "BEGIN") || strEQ(name, "END")
348                               || strEQ(name, "INIT") || strEQ(name, "CHECK"))
349                               CvSPECIAL_on(PL_compcv);
350                           $$ = $1; }
351         ;
352
353 proto   :       /* NULL */
354                         { $$ = Nullop; }
355         |       THING
356         ;
357
358 subattrlist:    /* NULL */
359                         { $$ = Nullop; }
360         |       COLONATTR THING
361                         { $$ = $2; }
362         |       COLONATTR
363                         { $$ = Nullop; }
364         ;
365
366 myattrlist:     COLONATTR THING
367                         { $$ = $2; }
368         |       COLONATTR
369                         { $$ = Nullop; }
370         ;
371
372 subbody :       block   { $$ = $1; }
373         |       ';'     { $$ = Nullop; PL_expect = XSTATE; }
374         ;
375
376 package :       PACKAGE WORD ';'
377                         { package($2); }
378         |       PACKAGE ';'
379                         { package(Nullop); }
380         ;
381
382 use     :       USE startsub
383                         { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
384                     WORD WORD listexpr ';'
385                         { utilize($1, $2, $4, $5, $6); }
386         ;
387
388 expr    :       expr ANDOP expr
389                         { $$ = newLOGOP(OP_AND, 0, $1, $3); }
390         |       expr OROP expr
391                         { $$ = newLOGOP($2, 0, $1, $3); }
392         |       argexpr %prec PREC_LOW
393         ;
394
395 argexpr :       argexpr ','
396                         { $$ = $1; }
397         |       argexpr ',' term
398                         { $$ = append_elem(OP_LIST, $1, $3); }
399         |       term %prec PREC_LOW
400         ;
401
402 listop  :       LSTOP indirob argexpr
403                         { $$ = convert($1, OPf_STACKED,
404                                 prepend_elem(OP_LIST, newGVREF($1,$2), $3) ); }
405         |       FUNC '(' indirob expr ')'
406                         { $$ = convert($1, OPf_STACKED,
407                                 prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); }
408         |       term ARROW method '(' listexprcom ')'
409                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
410                                 append_elem(OP_LIST,
411                                     prepend_elem(OP_LIST, scalar($1), $5),
412                                     newUNOP(OP_METHOD, 0, $3))); }
413         |       term ARROW method
414                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
415                                 append_elem(OP_LIST, scalar($1),
416                                     newUNOP(OP_METHOD, 0, $3))); }
417         |       METHOD indirob listexpr
418                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
419                                 append_elem(OP_LIST,
420                                     prepend_elem(OP_LIST, $2, $3),
421                                     newUNOP(OP_METHOD, 0, $1))); }
422         |       FUNCMETH indirob '(' listexprcom ')'
423                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
424                                 append_elem(OP_LIST,
425                                     prepend_elem(OP_LIST, $2, $4),
426                                     newUNOP(OP_METHOD, 0, $1))); }
427         |       LSTOP listexpr
428                         { $$ = convert($1, 0, $2); }
429         |       FUNC '(' listexprcom ')'
430                         { $$ = convert($1, 0, $3); }
431         |       LSTOPSUB startanonsub block
432                         { $3 = newANONATTRSUB($2, 0, Nullop, $3); }
433                     listexpr            %prec LSTOP
434                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
435                                  append_elem(OP_LIST,
436                                    prepend_elem(OP_LIST, $3, $5), $1)); }
437         ;
438
439 method  :       METHOD
440         |       scalar
441         ;
442
443 subscripted:    star '{' expr ';' '}'
444                         { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3)); }
445         |       scalar '[' expr ']'
446                         { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); }
447         |       term ARROW '[' expr ']'
448                         { $$ = newBINOP(OP_AELEM, 0,
449                                         ref(newAVREF($1),OP_RV2AV),
450                                         scalar($4));}
451         |       subscripted '[' expr ']'
452                         { $$ = newBINOP(OP_AELEM, 0,
453                                         ref(newAVREF($1),OP_RV2AV),
454                                         scalar($3));}
455         |       scalar '{' expr ';' '}'
456                         { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
457                             PL_expect = XOPERATOR; }
458         |       term ARROW '{' expr ';' '}'
459                         { $$ = newBINOP(OP_HELEM, 0,
460                                         ref(newHVREF($1),OP_RV2HV),
461                                         jmaybe($4));
462                             PL_expect = XOPERATOR; }
463         |       subscripted '{' expr ';' '}'
464                         { $$ = newBINOP(OP_HELEM, 0,
465                                         ref(newHVREF($1),OP_RV2HV),
466                                         jmaybe($3));
467                             PL_expect = XOPERATOR; }
468         |       term ARROW '(' ')'
469                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
470                                    newCVREF(0, scalar($1))); }
471         |       term ARROW '(' expr ')'
472                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
473                                    append_elem(OP_LIST, $4,
474                                        newCVREF(0, scalar($1)))); }
475
476         |       subscripted '(' expr ')'
477                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
478                                    append_elem(OP_LIST, $3,
479                                                newCVREF(0, scalar($1)))); }
480         |       subscripted '(' ')'
481                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
482                                    newCVREF(0, scalar($1))); }
483
484
485
486 term    :       term ASSIGNOP term
487                         { $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); }
488         |       term POWOP term
489                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
490         |       term MULOP term
491                         {   if ($2 != OP_REPEAT)
492                                 scalar($1);
493                             $$ = newBINOP($2, 0, $1, scalar($3)); }
494         |       term ADDOP term
495                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
496         |       term SHIFTOP term
497                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
498         |       term RELOP term
499                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
500         |       term EQOP term
501                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
502         |       term BITANDOP term
503                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
504         |       term BITOROP term
505                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
506         |       term DOTDOT term
507                         { $$ = newRANGE($2, scalar($1), scalar($3));}
508         |       term ANDAND term
509                         { $$ = newLOGOP(OP_AND, 0, $1, $3); }
510         |       term OROR term
511                         { $$ = newLOGOP(OP_OR, 0, $1, $3); }
512         |       term '?' term ':' term
513                         { $$ = newCONDOP(0, $1, $3, $5); }
514         |       term MATCHOP term
515                         { $$ = bind_match($2, $1, $3); }
516
517         |       '-' term %prec UMINUS
518                         { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); }
519         |       '+' term %prec UMINUS
520                         { $$ = $2; }
521         |       '!' term
522                         { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
523         |       '~' term
524                         { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));}
525         |       REFGEN term
526                         { $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN)); }
527         |       term POSTINC
528                         { $$ = newUNOP(OP_POSTINC, 0,
529                                         mod(scalar($1), OP_POSTINC)); }
530         |       term POSTDEC
531                         { $$ = newUNOP(OP_POSTDEC, 0,
532                                         mod(scalar($1), OP_POSTDEC)); }
533         |       PREINC term
534                         { $$ = newUNOP(OP_PREINC, 0,
535                                         mod(scalar($2), OP_PREINC)); }
536         |       PREDEC term
537                         { $$ = newUNOP(OP_PREDEC, 0,
538                                         mod(scalar($2), OP_PREDEC)); }
539         |       myattrterm      %prec UNIOP
540                         { $$ = $1; }
541         |       LOCAL term      %prec UNIOP
542                         { $$ = localize($2,$1); }
543         |       '(' expr ')'
544                         { $$ = sawparens($2); }
545         |       '(' ')'
546                         { $$ = sawparens(newNULLLIST()); }
547         |       '[' expr ']'
548                         { $$ = newANONLIST($2); }
549         |       '[' ']'
550                         { $$ = newANONLIST(Nullop); }
551         |       HASHBRACK expr ';' '}'                  %prec '('
552                         { $$ = newANONHASH($2); }
553         |       HASHBRACK ';' '}'                               %prec '('
554                         { $$ = newANONHASH(Nullop); }
555         |       ANONSUB startanonsub proto subattrlist block    %prec '('
556                         { $$ = newANONATTRSUB($2, $3, $4, $5); }
557         |       scalar  %prec '('
558                         { $$ = $1; }
559         |       star    %prec '('
560                         { $$ = $1; }
561         |       hsh     %prec '('
562                         { $$ = $1; }
563         |       ary     %prec '('
564                         { $$ = $1; }
565         |       arylen  %prec '('
566                         { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
567         |       subscripted
568                         { $$ = $1; }
569         |       '(' expr ')' '[' expr ']'
570                         { $$ = newSLICEOP(0, $5, $2); }
571         |       '(' ')' '[' expr ']'
572                         { $$ = newSLICEOP(0, $4, Nullop); }
573         |       ary '[' expr ']'
574                         { $$ = prepend_elem(OP_ASLICE,
575                                 newOP(OP_PUSHMARK, 0),
576                                     newLISTOP(OP_ASLICE, 0,
577                                         list($3),
578                                         ref($1, OP_ASLICE))); }
579         |       ary '{' expr ';' '}'
580                         { $$ = prepend_elem(OP_HSLICE,
581                                 newOP(OP_PUSHMARK, 0),
582                                     newLISTOP(OP_HSLICE, 0,
583                                         list($3),
584                                         ref(oopsHV($1), OP_HSLICE)));
585                             PL_expect = XOPERATOR; }
586         |       THING   %prec '('
587                         { $$ = $1; }
588         |       amper
589                         { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
590         |       amper '(' ')'
591                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
592         |       amper '(' expr ')'
593                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
594                             append_elem(OP_LIST, $3, scalar($1))); }
595         |       NOAMP WORD listexpr
596                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
597                             append_elem(OP_LIST, $3, scalar($2))); }
598         |       DO term %prec UNIOP
599                         { $$ = dofile($2); }
600         |       DO block        %prec '('
601                         { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); }
602         |       DO WORD '(' ')'
603                         { $$ = newUNOP(OP_ENTERSUB,
604                             OPf_SPECIAL|OPf_STACKED,
605                             prepend_elem(OP_LIST,
606                                 scalar(newCVREF(
607                                     (OPpENTERSUB_AMPER<<8),
608                                     scalar($2)
609                                 )),Nullop)); dep();}
610         |       DO WORD '(' expr ')'
611                         { $$ = newUNOP(OP_ENTERSUB,
612                             OPf_SPECIAL|OPf_STACKED,
613                             append_elem(OP_LIST,
614                                 $4,
615                                 scalar(newCVREF(
616                                     (OPpENTERSUB_AMPER<<8),
617                                     scalar($2)
618                                 )))); dep();}
619         |       DO scalar '(' ')'
620                         { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
621                             prepend_elem(OP_LIST,
622                                 scalar(newCVREF(0,scalar($2))), Nullop)); dep();}
623         |       DO scalar '(' expr ')'
624                         { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
625                             prepend_elem(OP_LIST,
626                                 $4,
627                                 scalar(newCVREF(0,scalar($2))))); dep();}
628         |       LOOPEX
629                         { $$ = newOP($1, OPf_SPECIAL);
630                             PL_hints |= HINT_BLOCK_SCOPE; }
631         |       LOOPEX term
632                         { $$ = newLOOPEX($1,$2); }
633         |       NOTOP argexpr
634                         { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
635         |       UNIOP
636                         { $$ = newOP($1, 0); }
637         |       UNIOP block
638                         { $$ = newUNOP($1, 0, $2); }
639         |       UNIOP term
640                         { $$ = newUNOP($1, 0, $2); }
641         |       UNIOPSUB term
642                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
643                             append_elem(OP_LIST, $2, scalar($1))); }
644         |       FUNC0
645                         { $$ = newOP($1, 0); }
646         |       FUNC0 '(' ')'
647                         { $$ = newOP($1, 0); }
648         |       FUNC0SUB
649                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
650                                 scalar($1)); }
651         |       FUNC1 '(' ')'
652                         { $$ = newOP($1, OPf_SPECIAL); }
653         |       FUNC1 '(' expr ')'
654                         { $$ = newUNOP($1, 0, $3); }
655         |       PMFUNC '(' term ')'
656                         { $$ = pmruntime($1, $3, Nullop); }
657         |       PMFUNC '(' term ',' term ')'
658                         { $$ = pmruntime($1, $3, $5); }
659         |       WORD
660         |       listop
661         ;
662
663 myattrterm:     MY myterm myattrlist
664                         { $$ = my_attrs($2,$3); }
665         |       MY myterm
666                         { $$ = localize($2,$1); }
667         ;
668
669 myterm  :       '(' expr ')'
670                         { $$ = sawparens($2); }
671         |       '(' ')'
672                         { $$ = sawparens(newNULLLIST()); }
673         |       scalar  %prec '('
674                         { $$ = $1; }
675         |       hsh     %prec '('
676                         { $$ = $1; }
677         |       ary     %prec '('
678                         { $$ = $1; }
679         ;
680
681 listexpr:       /* NULL */ %prec PREC_LOW
682                         { $$ = Nullop; }
683         |       argexpr    %prec PREC_LOW
684                         { $$ = $1; }
685         ;
686
687 listexprcom:    /* NULL */
688                         { $$ = Nullop; }
689         |       expr
690                         { $$ = $1; }
691         |       expr ','
692                         { $$ = $1; }
693         ;
694
695 my_scalar:      scalar
696                         { PL_in_my = 0; $$ = my($1); }
697         ;
698
699 amper   :       '&' indirob
700                         { $$ = newCVREF($1,$2); }
701         ;
702
703 scalar  :       '$' indirob
704                         { $$ = newSVREF($2); }
705         ;
706
707 ary     :       '@' indirob
708                         { $$ = newAVREF($2); }
709         ;
710
711 hsh     :       '%' indirob
712                         { $$ = newHVREF($2); }
713         ;
714
715 arylen  :       DOLSHARP indirob
716                         { $$ = newAVREF($2); }
717         ;
718
719 star    :       '*' indirob
720                         { $$ = newGVREF(0,$2); }
721         ;
722
723 indirob :       WORD
724                         { $$ = scalar($1); }
725         |       scalar %prec PREC_LOW
726                         { $$ = scalar($1);  }
727         |       block
728                         { $$ = scope($1); }
729
730         |       PRIVATEREF
731                         { $$ = $1; }
732         ;
733
734 %% /* PROGRAM */
735
736 /* more stuff added to make perly_c.diff easier to apply */
737
738 #ifdef yyparse
739 #undef yyparse
740 #endif
741 #define yyparse() Perl_yyparse(pTHX)
742