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