This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Applied a patch from David Fifield to fix an error message in perlipc.pod
[perl5.git] / perly.y
1 /*    perly.y
2  *
3  *    Copyright (c) 1991-2002, 2003, 2004, 2005, 2006 Larry Wall
4  *    Copyright (c) 2007, 2008 by Larry Wall and others
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  *
9  */
10
11 /*
12  * 'I see,' laughed Strider.  'I look foul and feel fair.  Is that it?
13  *  All that is gold does not glitter, not all those who wander are lost.'
14  *
15  *     [p.171 of _The Lord of the Rings_, I/x: "Strider"]
16  */
17
18 /*
19  * This file holds the grammar for the Perl language. If edited, you need
20  * to run regen_perly.pl, which re-creates the files perly.h, perly.tab
21  * and perly.act which are derived from this.
22  *
23  * Note that these derived files are included and compiled twice; once
24  * from perly.c, and once from madly.c. The second time, a number of MAD
25  * macros are defined, which compile in extra code that allows the parse
26  * tree to be accurately dumped. In particular:
27  *
28  * MAD            defined if compiling madly.c
29  * DO_MAD(A)      expands to A  under madly.c, to null otherwise
30  * IF_MAD(a,b)    expands to A under madly.c, to B otherwise
31  * TOKEN_GETMAD() expands to token_getmad() under madly.c, to null otherwise
32  * TOKEN_FREE()   similarly
33  * OP_GETMAD()    similarly
34  * IVAL(i)        expands to (i)->tk_lval.ival or (i)
35  * PVAL(p)        expands to (p)->tk_lval.pval or (p)
36  *
37  * The main job of of this grammar is to call the various newFOO()
38  * functions in op.c to build a syntax tree of OP structs.
39  * It relies on the lexer in toke.c to do the tokenizing.
40  *
41  * Note: due to the way that the cleanup code works WRT to freeing ops on
42  * the parse stack, it is dangerous to assign to the $n variables within
43  * an action.
44  */
45
46 /*  Make the parser re-entrant. */
47
48 %pure_parser
49
50 /* FIXME for MAD - is the new mintro on while and until important?  */
51
52 %start prog
53
54 %union {
55     I32 ival; /* __DEFAULT__ (marker for regen_perly.pl;
56                                 must always be 1st union member) */
57     char *pval;
58     OP *opval;
59     GV *gvval;
60 #ifdef PERL_IN_MADLY_C
61     TOKEN* p_tkval;
62     TOKEN* i_tkval;
63 #else
64     char *p_tkval;
65     I32 i_tkval;
66 #endif
67 #ifdef PERL_MAD
68     TOKEN* tkval;
69 #endif
70 }
71
72 %token <i_tkval> '{' '}' '[' ']' '-' '+' '$' '@' '%' '*' '&' ';'
73
74 %token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF
75 %token <opval> FUNC0SUB UNIOPSUB LSTOPSUB
76 %token <p_tkval> LABEL
77 %token <i_tkval> FORMAT SUB ANONSUB PACKAGE USE
78 %token <i_tkval> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
79 %token <i_tkval> GIVEN WHEN DEFAULT
80 %token <i_tkval> LOOPEX DOTDOT YADAYADA
81 %token <i_tkval> FUNC0 FUNC1 FUNC UNIOP LSTOP
82 %token <i_tkval> RELOP EQOP MULOP ADDOP
83 %token <i_tkval> DOLSHARP DO HASHBRACK NOAMP
84 %token <i_tkval> LOCAL MY MYSUB REQUIRE
85 %token <i_tkval> COLONATTR
86
87 %type <ival> prog progstart remember mremember
88 %type <ival>  startsub startanonsub startformsub
89 /* FIXME for MAD - are these two ival? */
90 %type <ival> mydefsv mintro
91
92 %type <opval> decl format subrout mysubrout package use peg
93
94 %type <opval> block mblock lineseq line loop cond else
95 %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
96 %type <opval> argexpr nexpr texpr iexpr mexpr mnexpr miexpr
97 %type <opval> listexpr listexprcom indirob listop method
98 %type <opval> formname subname proto subbody cont my_scalar
99 %type <opval> subattrlist myattrlist myattrterm myterm
100 %type <opval> termbinop termunop anonymous termdo
101 %type <opval> switch case
102 %type <p_tkval> label
103
104 %nonassoc <i_tkval> PREC_LOW
105 %nonassoc LOOPEX
106
107 %left <i_tkval> OROP DOROP
108 %left <i_tkval> ANDOP
109 %right <i_tkval> NOTOP
110 %nonassoc LSTOP LSTOPSUB
111 %left <i_tkval> ','
112 %right <i_tkval> ASSIGNOP
113 %right <i_tkval> '?' ':'
114 %nonassoc DOTDOT YADAYADA
115 %left <i_tkval> OROR DORDOR
116 %left <i_tkval> ANDAND
117 %left <i_tkval> BITOROP
118 %left <i_tkval> BITANDOP
119 %nonassoc EQOP
120 %nonassoc RELOP
121 %nonassoc UNIOP UNIOPSUB
122 %nonassoc REQUIRE
123 %left <i_tkval> SHIFTOP
124 %left ADDOP
125 %left MULOP
126 %left <i_tkval> MATCHOP
127 %right <i_tkval> '!' '~' UMINUS REFGEN
128 %right <i_tkval> POWOP
129 %nonassoc <i_tkval> PREINC PREDEC POSTINC POSTDEC
130 %left <i_tkval> ARROW
131 %nonassoc <i_tkval> ')'
132 %left <i_tkval> '('
133 %left '[' '{'
134
135 %token <i_tkval> PEG
136
137 %% /* RULES */
138
139 /* The whole program */
140 prog    :       progstart
141         /*CONTINUED*/   lineseq
142                         { $$ = $1; newPROG(block_end($1,$2)); }
143         ;
144
145 /* An ordinary block */
146 block   :       '{' remember lineseq '}'
147                         { if (PL_parser->copline > (line_t)IVAL($1))
148                               PL_parser->copline = (line_t)IVAL($1);
149                           $$ = block_end($2, $3);
150                           TOKEN_GETMAD($1,$$,'{');
151                           TOKEN_GETMAD($4,$$,'}');
152                         }
153         ;
154
155 remember:       /* NULL */      /* start a full lexical scope */
156                         { $$ = block_start(TRUE); }
157         ;
158
159 mydefsv:        /* NULL */      /* lexicalize $_ */
160                         { $$ = (I32) allocmy("$_"); }
161         ;
162
163 progstart:
164                 {
165                     PL_parser->expect = XSTATE; $$ = block_start(TRUE);
166                 }
167         ;
168
169
170 mblock  :       '{' mremember lineseq '}'
171                         { if (PL_parser->copline > (line_t)IVAL($1))
172                               PL_parser->copline = (line_t)IVAL($1);
173                           $$ = block_end($2, $3);
174                           TOKEN_GETMAD($1,$$,'{');
175                           TOKEN_GETMAD($4,$$,'}');
176                         }
177         ;
178
179 mremember:      /* NULL */      /* start a partial lexical scope */
180                         { $$ = block_start(FALSE); }
181         ;
182
183 /* A collection of "lines" in the program */
184 lineseq :       /* NULL */
185                         { $$ = (OP*)NULL; }
186         |       lineseq decl
187                         {
188                         $$ = IF_MAD(
189                                 append_list(OP_LINESEQ,
190                                     (LISTOP*)$1, (LISTOP*)$2),
191                                 $1);
192                         }
193         |       lineseq line
194                         {   $$ = append_list(OP_LINESEQ,
195                                 (LISTOP*)$1, (LISTOP*)$2);
196                             PL_pad_reset_pending = TRUE;
197                             if ($1 && $2)
198                                 PL_hints |= HINT_BLOCK_SCOPE;
199                         }
200         ;
201
202 /* A "line" in the program */
203 line    :       label cond
204                         { $$ = newSTATEOP(0, PVAL($1), $2);
205                           TOKEN_GETMAD($1,((LISTOP*)$$)->op_first,'L'); }
206         |       loop    /* loops add their own labels */
207         |       switch  /* ... and so do switches */
208                         { $$ = $1; }
209         |       label case
210                         { $$ = newSTATEOP(0, PVAL($1), $2); }
211         |       label ';'
212                         {
213                           if (PVAL($1)) {
214                               $$ = newSTATEOP(0, PVAL($1), newOP(OP_NULL, 0));
215                               TOKEN_GETMAD($1,$$,'L');
216                               TOKEN_GETMAD($2,((LISTOP*)$$)->op_first,';');
217                           }
218                           else {
219                               $$ = IF_MAD(
220                                         newOP(OP_NULL, 0),
221                                         (OP*)NULL);
222                               PL_parser->copline = NOLINE;
223                               TOKEN_FREE($1);
224                               TOKEN_GETMAD($2,$$,';');
225                           }
226                           PL_parser->expect = XSTATE;
227                         }
228         |       label sideff ';'
229                         {
230                           $$ = newSTATEOP(0, PVAL($1), $2);
231                           PL_parser->expect = XSTATE;
232                           DO_MAD({
233                               /* sideff might already have a nexstate */
234                               OP* op = ((LISTOP*)$$)->op_first;
235                               if (op) {
236                                   while (op->op_sibling &&
237                                      op->op_sibling->op_type == OP_NEXTSTATE)
238                                         op = op->op_sibling;
239                                   token_getmad($1,op,'L');
240                                   token_getmad($3,op,';');
241                               }
242                           })
243                         }
244         ;
245
246 /* An expression which may have a side-effect */
247 sideff  :       error
248                         { $$ = (OP*)NULL; }
249         |       expr
250                         { $$ = $1; }
251         |       expr IF expr
252                         { $$ = newLOGOP(OP_AND, 0, $3, $1);
253                           TOKEN_GETMAD($2,$$,'i');
254                         }
255         |       expr UNLESS expr
256                         { $$ = newLOGOP(OP_OR, 0, $3, $1);
257                           TOKEN_GETMAD($2,$$,'i');
258                         }
259         |       expr WHILE expr
260                         { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1);
261                           TOKEN_GETMAD($2,$$,'w');
262                         }
263         |       expr UNTIL iexpr
264                         { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);
265                           TOKEN_GETMAD($2,$$,'w');
266                         }
267         |       expr FOR expr
268                         { $$ = newFOROP(0, NULL, (line_t)IVAL($2),
269                                         (OP*)NULL, $3, $1, (OP*)NULL);
270                           TOKEN_GETMAD($2,((LISTOP*)$$)->op_first->op_sibling,'w');
271                         }
272         |       expr WHEN expr
273                         { $$ = newWHENOP($3, scope($1)); }
274         ;
275
276 /* else and elsif blocks */
277 else    :       /* NULL */
278                         { $$ = (OP*)NULL; }
279         |       ELSE mblock
280                         { ($2)->op_flags |= OPf_PARENS; $$ = scope($2);
281                           TOKEN_GETMAD($1,$$,'o');
282                         }
283         |       ELSIF '(' mexpr ')' mblock else
284                         { PL_parser->copline = (line_t)IVAL($1);
285                             $$ = newCONDOP(0, newSTATEOP(OPf_SPECIAL,NULL,$3), scope($5), $6);
286                             PL_hints |= HINT_BLOCK_SCOPE;
287                           TOKEN_GETMAD($1,$$,'I');
288                           TOKEN_GETMAD($2,$$,'(');
289                           TOKEN_GETMAD($4,$$,')');
290                         }
291         ;
292
293 /* Real conditional expressions */
294 cond    :       IF '(' remember mexpr ')' mblock else
295                         { PL_parser->copline = (line_t)IVAL($1);
296                             $$ = block_end($3,
297                                    newCONDOP(0, $4, scope($6), $7));
298                           TOKEN_GETMAD($1,$$,'I');
299                           TOKEN_GETMAD($2,$$,'(');
300                           TOKEN_GETMAD($5,$$,')');
301                         }
302         |       UNLESS '(' remember miexpr ')' mblock else
303                         { PL_parser->copline = (line_t)IVAL($1);
304                             $$ = block_end($3,
305                                    newCONDOP(0, $4, scope($6), $7));
306                           TOKEN_GETMAD($1,$$,'I');
307                           TOKEN_GETMAD($2,$$,'(');
308                           TOKEN_GETMAD($5,$$,')');
309                         }
310         ;
311
312 /* Cases for a switch statement */
313 case    :       WHEN '(' remember mexpr ')' mblock
314         { $$ = block_end($3,
315                 newWHENOP($4, scope($6))); }
316         |       DEFAULT block
317         { $$ = newWHENOP(0, scope($2)); }
318         ;
319
320 /* Continue blocks */
321 cont    :       /* NULL */
322                         { $$ = (OP*)NULL; }
323         |       CONTINUE block
324                         { $$ = scope($2);
325                           TOKEN_GETMAD($1,$$,'o');
326                         }
327         ;
328
329 /* Loops: while, until, for, and a bare block */
330 loop    :       label WHILE '(' remember texpr ')' mintro mblock cont
331                         { OP *innerop;
332                           PL_parser->copline = (line_t)$2;
333                             $$ = block_end($4,
334                                    newSTATEOP(0, PVAL($1),
335                                      innerop = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
336                                                 IVAL($2), $5, $8, $9, $7)));
337                           TOKEN_GETMAD($1,innerop,'L');
338                           TOKEN_GETMAD($2,innerop,'W');
339                           TOKEN_GETMAD($3,innerop,'(');
340                           TOKEN_GETMAD($6,innerop,')');
341                         }
342
343         |       label UNTIL '(' remember iexpr ')' mintro mblock cont
344                         { OP *innerop;
345                           PL_parser->copline = (line_t)$2;
346                             $$ = block_end($4,
347                                    newSTATEOP(0, PVAL($1),
348                                      innerop = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
349                                                 IVAL($2), $5, $8, $9, $7)));
350                           TOKEN_GETMAD($1,innerop,'L');
351                           TOKEN_GETMAD($2,innerop,'W');
352                           TOKEN_GETMAD($3,innerop,'(');
353                           TOKEN_GETMAD($6,innerop,')');
354                         }
355         |       label FOR MY remember my_scalar '(' mexpr ')' mblock cont
356                         { OP *innerop;
357                           $$ = block_end($4,
358                              innerop = newFOROP(0, PVAL($1), (line_t)IVAL($2),
359                                             $5, $7, $9, $10));
360                           TOKEN_GETMAD($1,((LISTOP*)innerop)->op_first,'L');
361                           TOKEN_GETMAD($2,((LISTOP*)innerop)->op_first->op_sibling,'W');
362                           TOKEN_GETMAD($3,((LISTOP*)innerop)->op_first->op_sibling,'d');
363                           TOKEN_GETMAD($6,((LISTOP*)innerop)->op_first->op_sibling,'(');
364                           TOKEN_GETMAD($8,((LISTOP*)innerop)->op_first->op_sibling,')');
365                         }
366         |       label FOR scalar '(' remember mexpr ')' mblock cont
367                         { OP *innerop;
368                           $$ = block_end($5,
369                              innerop = newFOROP(0, PVAL($1), (line_t)IVAL($2),
370                                     mod($3, OP_ENTERLOOP), $6, $8, $9));
371                           TOKEN_GETMAD($1,((LISTOP*)innerop)->op_first,'L');
372                           TOKEN_GETMAD($2,((LISTOP*)innerop)->op_first->op_sibling,'W');
373                           TOKEN_GETMAD($4,((LISTOP*)innerop)->op_first->op_sibling,'(');
374                           TOKEN_GETMAD($7,((LISTOP*)innerop)->op_first->op_sibling,')');
375                         }
376         |       label FOR '(' remember mexpr ')' mblock cont
377                         { OP *innerop;
378                           $$ = block_end($4,
379                              innerop = newFOROP(0, PVAL($1), (line_t)IVAL($2),
380                                                     (OP*)NULL, $5, $7, $8));
381                           TOKEN_GETMAD($1,((LISTOP*)innerop)->op_first,'L');
382                           TOKEN_GETMAD($2,((LISTOP*)innerop)->op_first->op_sibling,'W');
383                           TOKEN_GETMAD($3,((LISTOP*)innerop)->op_first->op_sibling,'(');
384                           TOKEN_GETMAD($6,((LISTOP*)innerop)->op_first->op_sibling,')');
385                         }
386         |       label FOR '(' remember mnexpr ';' texpr ';' mintro mnexpr ')'
387                     mblock
388                         /* basically fake up an initialize-while lineseq */
389                         { OP *forop;
390                           PL_parser->copline = (line_t)IVAL($2);
391                           forop = newSTATEOP(0, PVAL($1),
392                                             newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
393                                                 IVAL($2), scalar($7),
394                                                 $12, $10, $9));
395 #ifdef MAD
396                           forop = newUNOP(OP_NULL, 0, append_elem(OP_LINESEQ,
397                                 newSTATEOP(0,
398                                            CopLABEL_alloc(($1)->tk_lval.pval),
399                                            ($5 ? $5 : newOP(OP_NULL, 0)) ),
400                                 forop));
401
402                           token_getmad($2,forop,'3');
403                           token_getmad($3,forop,'(');
404                           token_getmad($6,forop,'1');
405                           token_getmad($8,forop,'2');
406                           token_getmad($11,forop,')');
407                           token_getmad($1,forop,'L');
408 #else
409                           if ($5) {
410                                 forop = append_elem(OP_LINESEQ,
411                                         newSTATEOP(0, CopLABEL_alloc($1), $5),
412                                         forop);
413                           }
414
415
416 #endif
417                           $$ = block_end($4, forop); }
418         |       label block cont  /* a block is a loop that happens once */
419                         { $$ = newSTATEOP(0, PVAL($1),
420                                  newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
421                                             NOLINE, (OP*)NULL, $2, $3, 0));
422                           TOKEN_GETMAD($1,((LISTOP*)$$)->op_first,'L'); }
423         ;
424
425 /* Switch blocks */
426 switch  :       label GIVEN '(' remember mydefsv mexpr ')' mblock
427                         { PL_parser->copline = (line_t) $2;
428                             $$ = block_end($4,
429                                 newSTATEOP(0, PVAL($1),
430                                     newGIVENOP($6, scope($8),
431                                         (PADOFFSET) $5) )); }
432         ;
433
434 /* determine whether there are any new my declarations */
435 mintro  :       /* NULL */
436                         { $$ = (PL_min_intro_pending &&
437                             PL_max_intro_pending >=  PL_min_intro_pending);
438                           intro_my(); }
439
440 /* Normal expression */
441 nexpr   :       /* NULL */
442                         { $$ = (OP*)NULL; }
443         |       sideff
444         ;
445
446 /* Boolean expression */
447 texpr   :       /* NULL means true */
448                         { YYSTYPE tmplval;
449                           (void)scan_num("1", &tmplval);
450                           $$ = tmplval.opval; }
451         |       expr
452         ;
453
454 /* Inverted boolean expression */
455 iexpr   :       expr
456                         { $$ = invert(scalar($1)); }
457         ;
458
459 /* Expression with its own lexical scope */
460 mexpr   :       expr
461                         { $$ = $1; intro_my(); }
462         ;
463
464 mnexpr  :       nexpr
465                         { $$ = $1; intro_my(); }
466         ;
467
468 miexpr  :       iexpr
469                         { $$ = $1; intro_my(); }
470         ;
471
472 /* Optional "MAIN:"-style loop labels */
473 label   :       /* empty */
474                         {
475 #ifdef MAD
476                           YYSTYPE tmplval;
477                           tmplval.pval = NULL;
478                           $$ = newTOKEN(OP_NULL, tmplval, 0);
479 #else
480                           $$ = NULL;
481 #endif
482                         }
483         |       LABEL
484         ;
485
486 /* Some kind of declaration - just hang on peg in the parse tree */
487 decl    :       format
488                         { $$ = $1; }
489         |       subrout
490                         { $$ = $1; }
491         |       mysubrout
492                         { $$ = $1; }
493         |       package
494                         { $$ = $1; }
495         |       use
496                         { $$ = $1; }
497
498     /* these two are only used by MAD */
499
500         |       peg
501                         { $$ = $1; }
502         ;
503
504 peg     :       PEG
505                         { $$ = newOP(OP_NULL,0);
506                           TOKEN_GETMAD($1,$$,'p');
507                         }
508         ;
509
510 format  :       FORMAT startformsub formname block
511                         { SvREFCNT_inc_simple_void(PL_compcv);
512 #ifdef MAD
513                           $$ = newFORM($2, $3, $4);
514                           prepend_madprops($1->tk_mad, $$, 'F');
515                           $1->tk_mad = 0;
516                           token_free($1);
517 #else
518                           newFORM($2, $3, $4);
519                           $$ = (OP*)NULL;
520 #endif
521                         }
522         ;
523
524 formname:       WORD            { $$ = $1; }
525         |       /* NULL */      { $$ = (OP*)NULL; }
526         ;
527
528 /* Unimplemented "my sub foo { }" */
529 mysubrout:      MYSUB startsub subname proto subattrlist subbody
530                         { SvREFCNT_inc_simple_void(PL_compcv);
531 #ifdef MAD
532                           $$ = newMYSUB($2, $3, $4, $5, $6);
533                           token_getmad($1,$$,'d');
534 #else
535                           newMYSUB($2, $3, $4, $5, $6);
536                           $$ = (OP*)NULL;
537 #endif
538                         }
539         ;
540
541 /* Subroutine definition */
542 subrout :       SUB startsub subname proto subattrlist subbody
543                         { SvREFCNT_inc_simple_void(PL_compcv);
544 #ifdef MAD
545                           {
546                               OP* o = newSVOP(OP_ANONCODE, 0,
547                                 (SV*)newATTRSUB($2, $3, $4, $5, $6));
548                               $$ = newOP(OP_NULL,0);
549                               op_getmad(o,$$,'&');
550                               op_getmad($3,$$,'n');
551                               op_getmad($4,$$,'s');
552                               op_getmad($5,$$,'a');
553                               token_getmad($1,$$,'d');
554                               append_madprops($6->op_madprop, $$, 0);
555                               $6->op_madprop = 0;
556                             }
557 #else
558                           newATTRSUB($2, $3, $4, $5, $6);
559                           $$ = (OP*)NULL;
560 #endif
561                         }
562         ;
563
564 startsub:       /* NULL */      /* start a regular subroutine scope */
565                         { $$ = start_subparse(FALSE, 0);
566                             SAVEFREESV(PL_compcv); }
567
568         ;
569
570 startanonsub:   /* NULL */      /* start an anonymous subroutine scope */
571                         { $$ = start_subparse(FALSE, CVf_ANON);
572                             SAVEFREESV(PL_compcv); }
573         ;
574
575 startformsub:   /* NULL */      /* start a format subroutine scope */
576                         { $$ = start_subparse(TRUE, 0);
577                             SAVEFREESV(PL_compcv); }
578         ;
579
580 /* Name of a subroutine - must be a bareword, could be special */
581 subname :       WORD    { const char *const name = SvPV_nolen_const(((SVOP*)$1)->op_sv);
582                           if (strEQ(name, "BEGIN") || strEQ(name, "END")
583                               || strEQ(name, "INIT") || strEQ(name, "CHECK")
584                               || strEQ(name, "UNITCHECK"))
585                               CvSPECIAL_on(PL_compcv);
586                           $$ = $1; }
587         ;
588
589 /* Subroutine prototype */
590 proto   :       /* NULL */
591                         { $$ = (OP*)NULL; }
592         |       THING
593         ;
594
595 /* Optional list of subroutine attributes */
596 subattrlist:    /* NULL */
597                         { $$ = (OP*)NULL; }
598         |       COLONATTR THING
599                         { $$ = $2;
600                           TOKEN_GETMAD($1,$$,':');
601                         }
602         |       COLONATTR
603                         { $$ = IF_MAD(
604                                     newOP(OP_NULL, 0),
605                                     (OP*)NULL
606                                 );
607                           TOKEN_GETMAD($1,$$,':');
608                         }
609         ;
610
611 /* List of attributes for a "my" variable declaration */
612 myattrlist:     COLONATTR THING
613                         { $$ = $2;
614                           TOKEN_GETMAD($1,$$,':');
615                         }
616         |       COLONATTR
617                         { $$ = IF_MAD(
618                                     newOP(OP_NULL, 0),
619                                     (OP*)NULL
620                                 );
621                           TOKEN_GETMAD($1,$$,':');
622                         }
623         ;
624
625 /* Subroutine body - either null or a block */
626 subbody :       block   { $$ = $1; }
627         |       ';'     { $$ = IF_MAD(
628                                     newOP(OP_NULL,0),
629                                     (OP*)NULL
630                                 );
631                           PL_parser->expect = XSTATE;
632                           TOKEN_GETMAD($1,$$,';');
633                         }
634         ;
635
636 package :       PACKAGE WORD WORD ';'
637                         {
638 #ifdef MAD
639                           $$ = package($3);
640                           token_getmad($1,$$,'o');
641                           if ($2)
642                               package_version($2);
643                           token_getmad($4,$$,';');
644 #else
645                           package($3);
646                           if ($2)
647                               package_version($2);
648                           $$ = (OP*)NULL;
649 #endif
650                         }
651         ;
652
653 use     :       USE startsub
654                         { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
655                     WORD WORD listexpr ';'
656                         { SvREFCNT_inc_simple_void(PL_compcv);
657 #ifdef MAD
658                           $$ = utilize(IVAL($1), $2, $4, $5, $6);
659                           token_getmad($1,$$,'o');
660                           token_getmad($7,$$,';');
661                           if (PL_parser->rsfp_filters &&
662                                       AvFILLp(PL_parser->rsfp_filters) >= 0)
663                               append_madprops(newMADPROP('!', MAD_NULL, NULL, 0), $$, 0);
664 #else
665                           utilize(IVAL($1), $2, $4, $5, $6);
666                           $$ = (OP*)NULL;
667 #endif
668                         }
669         ;
670
671 /* Ordinary expressions; logical combinations */
672 expr    :       expr ANDOP expr
673                         { $$ = newLOGOP(OP_AND, 0, $1, $3);
674                           TOKEN_GETMAD($2,$$,'o');
675                         }
676         |       expr OROP expr
677                         { $$ = newLOGOP(IVAL($2), 0, $1, $3);
678                           TOKEN_GETMAD($2,$$,'o');
679                         }
680         |       expr DOROP expr
681                         { $$ = newLOGOP(OP_DOR, 0, $1, $3);
682                           TOKEN_GETMAD($2,$$,'o');
683                         }
684         |       argexpr %prec PREC_LOW
685         ;
686
687 /* Expressions are a list of terms joined by commas */
688 argexpr :       argexpr ','
689                         {
690 #ifdef MAD
691                           OP* op = newNULLLIST();
692                           token_getmad($2,op,',');
693                           $$ = append_elem(OP_LIST, $1, op);
694 #else
695                           $$ = $1;
696 #endif
697                         }
698         |       argexpr ',' term
699                         { 
700                           OP* term = $3;
701                           DO_MAD(
702                               term = newUNOP(OP_NULL, 0, term);
703                               token_getmad($2,term,',');
704                           )
705                           $$ = append_elem(OP_LIST, $1, term);
706                         }
707         |       term %prec PREC_LOW
708         ;
709
710 /* List operators */
711 listop  :       LSTOP indirob argexpr /* map {...} @args or print $fh @args */
712                         { $$ = convert(IVAL($1), OPf_STACKED,
713                                 prepend_elem(OP_LIST, newGVREF(IVAL($1),$2), $3) );
714                           TOKEN_GETMAD($1,$$,'o');
715                         }
716         |       FUNC '(' indirob expr ')'      /* print ($fh @args */
717                         { $$ = convert(IVAL($1), OPf_STACKED,
718                                 prepend_elem(OP_LIST, newGVREF(IVAL($1),$3), $4) );
719                           TOKEN_GETMAD($1,$$,'o');
720                           TOKEN_GETMAD($2,$$,'(');
721                           TOKEN_GETMAD($5,$$,')');
722                         }
723         |       term ARROW method '(' listexprcom ')' /* $foo->bar(list) */
724                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
725                                 append_elem(OP_LIST,
726                                     prepend_elem(OP_LIST, scalar($1), $5),
727                                     newUNOP(OP_METHOD, 0, $3)));
728                           TOKEN_GETMAD($2,$$,'A');
729                           TOKEN_GETMAD($4,$$,'(');
730                           TOKEN_GETMAD($6,$$,')');
731                         }
732         |       term ARROW method                     /* $foo->bar */
733                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
734                                 append_elem(OP_LIST, scalar($1),
735                                     newUNOP(OP_METHOD, 0, $3)));
736                           TOKEN_GETMAD($2,$$,'A');
737                         }
738         |       METHOD indirob listexpr              /* new Class @args */
739                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
740                                 append_elem(OP_LIST,
741                                     prepend_elem(OP_LIST, $2, $3),
742                                     newUNOP(OP_METHOD, 0, $1)));
743                         }
744         |       FUNCMETH indirob '(' listexprcom ')' /* method $object (@args) */
745                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
746                                 append_elem(OP_LIST,
747                                     prepend_elem(OP_LIST, $2, $4),
748                                     newUNOP(OP_METHOD, 0, $1)));
749                           TOKEN_GETMAD($3,$$,'(');
750                           TOKEN_GETMAD($5,$$,')');
751                         }
752         |       LSTOP listexpr                       /* print @args */
753                         { $$ = convert(IVAL($1), 0, $2);
754                           TOKEN_GETMAD($1,$$,'o');
755                         }
756         |       FUNC '(' listexprcom ')'             /* print (@args) */
757                         { $$ = convert(IVAL($1), 0, $3);
758                           TOKEN_GETMAD($1,$$,'o');
759                           TOKEN_GETMAD($2,$$,'(');
760                           TOKEN_GETMAD($4,$$,')');
761                         }
762         |       LSTOPSUB startanonsub block /* sub f(&@);   f { foo } ... */
763                         { SvREFCNT_inc_simple_void(PL_compcv);
764                           $<opval>$ = newANONATTRSUB($2, 0, (OP*)NULL, $3); }
765                     listexpr            %prec LSTOP  /* ... @bar */
766                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
767                                  append_elem(OP_LIST,
768                                    prepend_elem(OP_LIST, $<opval>4, $5), $1));
769                         }
770         ;
771
772 /* Names of methods. May use $object->$methodname */
773 method  :       METHOD
774         |       scalar
775         ;
776
777 /* Some kind of subscripted expression */
778 subscripted:    star '{' expr ';' '}'        /* *main::{something} */
779                         /* In this and all the hash accessors, ';' is
780                          * provided by the tokeniser */
781                         { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3));
782                             PL_parser->expect = XOPERATOR;
783                           TOKEN_GETMAD($2,$$,'{');
784                           TOKEN_GETMAD($4,$$,';');
785                           TOKEN_GETMAD($5,$$,'}');
786                         }
787         |       scalar '[' expr ']'          /* $array[$element] */
788                         { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3));
789                           TOKEN_GETMAD($2,$$,'[');
790                           TOKEN_GETMAD($4,$$,']');
791                         }
792         |       term ARROW '[' expr ']'      /* somearef->[$element] */
793                         { $$ = newBINOP(OP_AELEM, 0,
794                                         ref(newAVREF($1),OP_RV2AV),
795                                         scalar($4));
796                           TOKEN_GETMAD($2,$$,'a');
797                           TOKEN_GETMAD($3,$$,'[');
798                           TOKEN_GETMAD($5,$$,']');
799                         }
800         |       subscripted '[' expr ']'    /* $foo->[$bar]->[$baz] */
801                         { $$ = newBINOP(OP_AELEM, 0,
802                                         ref(newAVREF($1),OP_RV2AV),
803                                         scalar($3));
804                           TOKEN_GETMAD($2,$$,'[');
805                           TOKEN_GETMAD($4,$$,']');
806                         }
807         |       scalar '{' expr ';' '}'    /* $foo->{bar();} */
808                         { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
809                             PL_parser->expect = XOPERATOR;
810                           TOKEN_GETMAD($2,$$,'{');
811                           TOKEN_GETMAD($4,$$,';');
812                           TOKEN_GETMAD($5,$$,'}');
813                         }
814         |       term ARROW '{' expr ';' '}' /* somehref->{bar();} */
815                         { $$ = newBINOP(OP_HELEM, 0,
816                                         ref(newHVREF($1),OP_RV2HV),
817                                         jmaybe($4));
818                             PL_parser->expect = XOPERATOR;
819                           TOKEN_GETMAD($2,$$,'a');
820                           TOKEN_GETMAD($3,$$,'{');
821                           TOKEN_GETMAD($5,$$,';');
822                           TOKEN_GETMAD($6,$$,'}');
823                         }
824         |       subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */
825                         { $$ = newBINOP(OP_HELEM, 0,
826                                         ref(newHVREF($1),OP_RV2HV),
827                                         jmaybe($3));
828                             PL_parser->expect = XOPERATOR;
829                           TOKEN_GETMAD($2,$$,'{');
830                           TOKEN_GETMAD($4,$$,';');
831                           TOKEN_GETMAD($5,$$,'}');
832                         }
833         |       term ARROW '(' ')'          /* $subref->() */
834                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
835                                    newCVREF(0, scalar($1)));
836                           TOKEN_GETMAD($2,$$,'a');
837                           TOKEN_GETMAD($3,$$,'(');
838                           TOKEN_GETMAD($4,$$,')');
839                         }
840         |       term ARROW '(' expr ')'     /* $subref->(@args) */
841                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
842                                    append_elem(OP_LIST, $4,
843                                        newCVREF(0, scalar($1))));
844                           TOKEN_GETMAD($2,$$,'a');
845                           TOKEN_GETMAD($3,$$,'(');
846                           TOKEN_GETMAD($5,$$,')');
847                         }
848
849         |       subscripted '(' expr ')'   /* $foo->{bar}->(@args) */
850                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
851                                    append_elem(OP_LIST, $3,
852                                                newCVREF(0, scalar($1))));
853                           TOKEN_GETMAD($2,$$,'(');
854                           TOKEN_GETMAD($4,$$,')');
855                         }
856         |       subscripted '(' ')'        /* $foo->{bar}->() */
857                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
858                                    newCVREF(0, scalar($1)));
859                           TOKEN_GETMAD($2,$$,'(');
860                           TOKEN_GETMAD($3,$$,')');
861                         }
862         |       '(' expr ')' '[' expr ']'            /* list slice */
863                         { $$ = newSLICEOP(0, $5, $2);
864                           TOKEN_GETMAD($1,$$,'(');
865                           TOKEN_GETMAD($3,$$,')');
866                           TOKEN_GETMAD($4,$$,'[');
867                           TOKEN_GETMAD($6,$$,']');
868                         }
869         |       '(' ')' '[' expr ']'                 /* empty list slice! */
870                         { $$ = newSLICEOP(0, $4, (OP*)NULL);
871                           TOKEN_GETMAD($1,$$,'(');
872                           TOKEN_GETMAD($2,$$,')');
873                           TOKEN_GETMAD($3,$$,'[');
874                           TOKEN_GETMAD($5,$$,']');
875                         }
876     ;
877
878 /* Binary operators between terms */
879 termbinop:      term ASSIGNOP term                     /* $x = $y */
880                         { $$ = newASSIGNOP(OPf_STACKED, $1, IVAL($2), $3);
881                           TOKEN_GETMAD($2,$$,'o');
882                         }
883         |       term POWOP term                        /* $x ** $y */
884                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
885                           TOKEN_GETMAD($2,$$,'o');
886                         }
887         |       term MULOP term                        /* $x * $y, $x x $y */
888                         {   if (IVAL($2) != OP_REPEAT)
889                                 scalar($1);
890                             $$ = newBINOP(IVAL($2), 0, $1, scalar($3));
891                           TOKEN_GETMAD($2,$$,'o');
892                         }
893         |       term ADDOP term                        /* $x + $y */
894                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
895                           TOKEN_GETMAD($2,$$,'o');
896                         }
897         |       term SHIFTOP term                      /* $x >> $y, $x << $y */
898                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
899                           TOKEN_GETMAD($2,$$,'o');
900                         }
901         |       term RELOP term                        /* $x > $y, etc. */
902                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
903                           TOKEN_GETMAD($2,$$,'o');
904                         }
905         |       term EQOP term                         /* $x == $y, $x eq $y */
906                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
907                           TOKEN_GETMAD($2,$$,'o');
908                         }
909         |       term BITANDOP term                     /* $x & $y */
910                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
911                           TOKEN_GETMAD($2,$$,'o');
912                         }
913         |       term BITOROP term                      /* $x | $y */
914                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
915                           TOKEN_GETMAD($2,$$,'o');
916                         }
917         |       term DOTDOT term                       /* $x..$y, $x...$y */
918                         {
919                           $$ = newRANGE(IVAL($2), scalar($1), scalar($3));
920                           DO_MAD({
921                               UNOP *op;
922                               op = (UNOP*)$$;
923                               op = (UNOP*)op->op_first; /* get to flop */
924                               op = (UNOP*)op->op_first; /* get to flip */
925                               op = (UNOP*)op->op_first; /* get to range */
926                               token_getmad($2,(OP*)op,'o');
927                             })
928                         }
929         |       term ANDAND term                       /* $x && $y */
930                         { $$ = newLOGOP(OP_AND, 0, $1, $3);
931                           TOKEN_GETMAD($2,$$,'o');
932                         }
933         |       term OROR term                         /* $x || $y */
934                         { $$ = newLOGOP(OP_OR, 0, $1, $3);
935                           TOKEN_GETMAD($2,$$,'o');
936                         }
937         |       term DORDOR term                       /* $x // $y */
938                         { $$ = newLOGOP(OP_DOR, 0, $1, $3);
939                           TOKEN_GETMAD($2,$$,'o');
940                         }
941         |       term MATCHOP term                      /* $x =~ /$y/ */
942                         { $$ = bind_match(IVAL($2), $1, $3);
943                           TOKEN_GETMAD($2,
944                                 ($$->op_type == OP_NOT
945                                     ? ((UNOP*)$$)->op_first : $$),
946                                 '~');
947                         }
948     ;
949
950 /* Unary operators and terms */
951 termunop : '-' term %prec UMINUS                       /* -$x */
952                         { $$ = newUNOP(OP_NEGATE, 0, scalar($2));
953                           TOKEN_GETMAD($1,$$,'o');
954                         }
955         |       '+' term %prec UMINUS                  /* +$x */
956                         { $$ = IF_MAD(
957                                     newUNOP(OP_NULL, 0, $2),
958                                     $2
959                                 );
960                           TOKEN_GETMAD($1,$$,'+');
961                         }
962         |       '!' term                               /* !$x */
963                         { $$ = newUNOP(OP_NOT, 0, scalar($2));
964                           TOKEN_GETMAD($1,$$,'o');
965                         }
966         |       '~' term                               /* ~$x */
967                         { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));
968                           TOKEN_GETMAD($1,$$,'o');
969                         }
970         |       term POSTINC                           /* $x++ */
971                         { $$ = newUNOP(OP_POSTINC, 0,
972                                         mod(scalar($1), OP_POSTINC));
973                           TOKEN_GETMAD($2,$$,'o');
974                         }
975         |       term POSTDEC                           /* $x-- */
976                         { $$ = newUNOP(OP_POSTDEC, 0,
977                                         mod(scalar($1), OP_POSTDEC));
978                           TOKEN_GETMAD($2,$$,'o');
979                         }
980         |       PREINC term                            /* ++$x */
981                         { $$ = newUNOP(OP_PREINC, 0,
982                                         mod(scalar($2), OP_PREINC));
983                           TOKEN_GETMAD($1,$$,'o');
984                         }
985         |       PREDEC term                            /* --$x */
986                         { $$ = newUNOP(OP_PREDEC, 0,
987                                         mod(scalar($2), OP_PREDEC));
988                           TOKEN_GETMAD($1,$$,'o');
989                         }
990
991     ;
992
993 /* Constructors for anonymous data */
994 anonymous:      '[' expr ']'
995                         { $$ = newANONLIST($2);
996                           TOKEN_GETMAD($1,$$,'[');
997                           TOKEN_GETMAD($3,$$,']');
998                         }
999         |       '[' ']'
1000                         { $$ = newANONLIST((OP*)NULL);
1001                           TOKEN_GETMAD($1,$$,'[');
1002                           TOKEN_GETMAD($2,$$,']');
1003                         }
1004         |       HASHBRACK expr ';' '}'  %prec '(' /* { foo => "Bar" } */
1005                         { $$ = newANONHASH($2);
1006                           TOKEN_GETMAD($1,$$,'{');
1007                           TOKEN_GETMAD($3,$$,';');
1008                           TOKEN_GETMAD($4,$$,'}');
1009                         }
1010         |       HASHBRACK ';' '}'       %prec '(' /* { } (';' by tokener) */
1011                         { $$ = newANONHASH((OP*)NULL);
1012                           TOKEN_GETMAD($1,$$,'{');
1013                           TOKEN_GETMAD($2,$$,';');
1014                           TOKEN_GETMAD($3,$$,'}');
1015                         }
1016         |       ANONSUB startanonsub proto subattrlist block    %prec '('
1017                         { SvREFCNT_inc_simple_void(PL_compcv);
1018                           $$ = newANONATTRSUB($2, $3, $4, $5);
1019                           TOKEN_GETMAD($1,$$,'o');
1020                           OP_GETMAD($3,$$,'s');
1021                           OP_GETMAD($4,$$,'a');
1022                         }
1023
1024     ;
1025
1026 /* Things called with "do" */
1027 termdo  :       DO term %prec UNIOP                     /* do $filename */
1028                         { $$ = dofile($2, IVAL($1));
1029                           TOKEN_GETMAD($1,$$,'o');
1030                         }
1031         |       DO block        %prec '('               /* do { code */
1032                         { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2));
1033                           TOKEN_GETMAD($1,$$,'D');
1034                         }
1035         |       DO WORD '(' ')'                         /* do somesub() */
1036                         { $$ = newUNOP(OP_ENTERSUB,
1037                             OPf_SPECIAL|OPf_STACKED,
1038                             prepend_elem(OP_LIST,
1039                                 scalar(newCVREF(
1040                                     (OPpENTERSUB_AMPER<<8),
1041                                     scalar($2)
1042                                 )),(OP*)NULL)); dep();
1043                           TOKEN_GETMAD($1,$$,'o');
1044                           TOKEN_GETMAD($3,$$,'(');
1045                           TOKEN_GETMAD($4,$$,')');
1046                         }
1047         |       DO WORD '(' expr ')'                    /* do somesub(@args) */
1048                         { $$ = newUNOP(OP_ENTERSUB,
1049                             OPf_SPECIAL|OPf_STACKED,
1050                             append_elem(OP_LIST,
1051                                 $4,
1052                                 scalar(newCVREF(
1053                                     (OPpENTERSUB_AMPER<<8),
1054                                     scalar($2)
1055                                 )))); dep();
1056                           TOKEN_GETMAD($1,$$,'o');
1057                           TOKEN_GETMAD($3,$$,'(');
1058                           TOKEN_GETMAD($5,$$,')');
1059                         }
1060         |       DO scalar '(' ')'                      /* do $subref () */
1061                         { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
1062                             prepend_elem(OP_LIST,
1063                                 scalar(newCVREF(0,scalar($2))), (OP*)NULL)); dep();
1064                           TOKEN_GETMAD($1,$$,'o');
1065                           TOKEN_GETMAD($3,$$,'(');
1066                           TOKEN_GETMAD($4,$$,')');
1067                         }
1068         |       DO scalar '(' expr ')'                 /* do $subref (@args) */
1069                         { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
1070                             prepend_elem(OP_LIST,
1071                                 $4,
1072                                 scalar(newCVREF(0,scalar($2))))); dep();
1073                           TOKEN_GETMAD($1,$$,'o');
1074                           TOKEN_GETMAD($3,$$,'(');
1075                           TOKEN_GETMAD($5,$$,')');
1076                         }
1077
1078         ;
1079
1080 term    :       termbinop
1081         |       termunop
1082         |       anonymous
1083         |       termdo
1084         |       term '?' term ':' term
1085                         { $$ = newCONDOP(0, $1, $3, $5);
1086                           TOKEN_GETMAD($2,$$,'?');
1087                           TOKEN_GETMAD($4,$$,':');
1088                         }
1089         |       REFGEN term                          /* \$x, \@y, \%z */
1090                         { $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN));
1091                           TOKEN_GETMAD($1,$$,'o');
1092                         }
1093         |       myattrterm      %prec UNIOP
1094                         { $$ = $1; }
1095         |       LOCAL term      %prec UNIOP
1096                         { $$ = localize($2,IVAL($1));
1097                           TOKEN_GETMAD($1,$$,'k');
1098                         }
1099         |       '(' expr ')'
1100                         { $$ = sawparens(IF_MAD(newUNOP(OP_NULL,0,$2), $2));
1101                           TOKEN_GETMAD($1,$$,'(');
1102                           TOKEN_GETMAD($3,$$,')');
1103                         }
1104         |       '(' ')'
1105                         { $$ = sawparens(newNULLLIST());
1106                           TOKEN_GETMAD($1,$$,'(');
1107                           TOKEN_GETMAD($2,$$,')');
1108                         }
1109         |       scalar  %prec '('
1110                         { $$ = $1; }
1111         |       star    %prec '('
1112                         { $$ = $1; }
1113         |       hsh     %prec '('
1114                         { $$ = $1; }
1115         |       ary     %prec '('
1116                         { $$ = $1; }
1117         |       arylen  %prec '('                    /* $#x, $#{ something } */
1118                         { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
1119         |       subscripted
1120                         { $$ = $1; }
1121         |       ary '[' expr ']'                     /* array slice */
1122                         { $$ = prepend_elem(OP_ASLICE,
1123                                 newOP(OP_PUSHMARK, 0),
1124                                     newLISTOP(OP_ASLICE, 0,
1125                                         list($3),
1126                                         ref($1, OP_ASLICE)));
1127                           TOKEN_GETMAD($2,$$,'[');
1128                           TOKEN_GETMAD($4,$$,']');
1129                         }
1130         |       ary '{' expr ';' '}'                 /* @hash{@keys} */
1131                         { $$ = prepend_elem(OP_HSLICE,
1132                                 newOP(OP_PUSHMARK, 0),
1133                                     newLISTOP(OP_HSLICE, 0,
1134                                         list($3),
1135                                         ref(oopsHV($1), OP_HSLICE)));
1136                             PL_parser->expect = XOPERATOR;
1137                           TOKEN_GETMAD($2,$$,'{');
1138                           TOKEN_GETMAD($4,$$,';');
1139                           TOKEN_GETMAD($5,$$,'}');
1140                         }
1141         |       THING   %prec '('
1142                         { $$ = $1; }
1143         |       amper                                /* &foo; */
1144                         { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
1145         |       amper '(' ')'                        /* &foo() */
1146                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1));
1147                           TOKEN_GETMAD($2,$$,'(');
1148                           TOKEN_GETMAD($3,$$,')');
1149                         }
1150         |       amper '(' expr ')'                   /* &foo(@args) */
1151                         {
1152                           $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1153                                 append_elem(OP_LIST, $3, scalar($1)));
1154                           DO_MAD({
1155                               OP* op = $$;
1156                               if (op->op_type == OP_CONST) { /* defeat const fold */
1157                                 op = (OP*)op->op_madprop->mad_val;
1158                               }
1159                               token_getmad($2,op,'(');
1160                               token_getmad($4,op,')');
1161                           })
1162                         }
1163         |       NOAMP WORD listexpr                  /* foo(@args) */
1164                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1165                             append_elem(OP_LIST, $3, scalar($2)));
1166                           TOKEN_GETMAD($1,$$,'o');
1167                         }
1168         |       LOOPEX  /* loop exiting command (goto, last, dump, etc) */
1169                         { $$ = newOP(IVAL($1), OPf_SPECIAL);
1170                             PL_hints |= HINT_BLOCK_SCOPE;
1171                           TOKEN_GETMAD($1,$$,'o');
1172                         }
1173         |       LOOPEX term
1174                         { $$ = newLOOPEX(IVAL($1),$2);
1175                           TOKEN_GETMAD($1,$$,'o');
1176                         }
1177         |       NOTOP argexpr                        /* not $foo */
1178                         { $$ = newUNOP(OP_NOT, 0, scalar($2));
1179                           TOKEN_GETMAD($1,$$,'o');
1180                         }
1181         |       UNIOP                                /* Unary op, $_ implied */
1182                         { $$ = newOP(IVAL($1), 0);
1183                           TOKEN_GETMAD($1,$$,'o');
1184                         }
1185         |       UNIOP block                          /* eval { foo }* */
1186                         { $$ = newUNOP(IVAL($1), 0, $2);
1187                           TOKEN_GETMAD($1,$$,'o');
1188                         }
1189         |       UNIOP term                           /* Unary op */
1190                         { $$ = newUNOP(IVAL($1), 0, $2);
1191                           TOKEN_GETMAD($1,$$,'o');
1192                         }
1193         |       REQUIRE                              /* require, $_ implied */
1194                         { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0);
1195                           TOKEN_GETMAD($1,$$,'o');
1196                         }
1197         |       REQUIRE term                         /* require Foo */
1198                         { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2);
1199                           TOKEN_GETMAD($1,$$,'o');
1200                         }
1201         |       UNIOPSUB
1202                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
1203         |       UNIOPSUB term                        /* Sub treated as unop */
1204                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1205                             append_elem(OP_LIST, $2, scalar($1))); }
1206         |       FUNC0                                /* Nullary operator */
1207                         { $$ = newOP(IVAL($1), 0);
1208                           TOKEN_GETMAD($1,$$,'o');
1209                         }
1210         |       FUNC0 '(' ')'
1211                         { $$ = newOP(IVAL($1), 0);
1212                           TOKEN_GETMAD($1,$$,'o');
1213                           TOKEN_GETMAD($2,$$,'(');
1214                           TOKEN_GETMAD($3,$$,')');
1215                         }
1216         |       FUNC0SUB                             /* Sub treated as nullop */
1217                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1218                                 scalar($1)); }
1219         |       FUNC1 '(' ')'                        /* not () */
1220                         { $$ = (IVAL($1) == OP_NOT)
1221                             ? newUNOP(IVAL($1), 0, newSVOP(OP_CONST, 0, newSViv(0)))
1222                             : newOP(IVAL($1), OPf_SPECIAL);
1223
1224                           TOKEN_GETMAD($1,$$,'o');
1225                           TOKEN_GETMAD($2,$$,'(');
1226                           TOKEN_GETMAD($3,$$,')');
1227                         }
1228         |       FUNC1 '(' expr ')'                   /* not($foo) */
1229                         { $$ = newUNOP(IVAL($1), 0, $3);
1230                           TOKEN_GETMAD($1,$$,'o');
1231                           TOKEN_GETMAD($2,$$,'(');
1232                           TOKEN_GETMAD($4,$$,')');
1233                         }
1234         |       PMFUNC '(' argexpr ')'          /* m//, s///, tr/// */
1235                         { $$ = pmruntime($1, $3, 1);
1236                           TOKEN_GETMAD($2,$$,'(');
1237                           TOKEN_GETMAD($4,$$,')');
1238                         }
1239         |       WORD
1240         |       listop
1241         |       YADAYADA
1242                         {
1243                           $$ = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0),
1244                                 newSVOP(OP_CONST, 0, newSVpvs("Unimplemented")));
1245                           TOKEN_GETMAD($1,$$,'X');
1246                         }
1247         ;
1248
1249 /* "my" declarations, with optional attributes */
1250 myattrterm:     MY myterm myattrlist
1251                         { $$ = my_attrs($2,$3);
1252                           DO_MAD(
1253                               token_getmad($1,$$,'d');
1254                               append_madprops($3->op_madprop, $$, 'a');
1255                               $3->op_madprop = 0;
1256                           )
1257                         }
1258         |       MY myterm
1259                         { $$ = localize($2,IVAL($1));
1260                           TOKEN_GETMAD($1,$$,'d');
1261                         }
1262         ;
1263
1264 /* Things that can be "my"'d */
1265 myterm  :       '(' expr ')'
1266                         { $$ = sawparens($2);
1267                           TOKEN_GETMAD($1,$$,'(');
1268                           TOKEN_GETMAD($3,$$,')');
1269                         }
1270         |       '(' ')'
1271                         { $$ = sawparens(newNULLLIST());
1272                           TOKEN_GETMAD($1,$$,'(');
1273                           TOKEN_GETMAD($2,$$,')');
1274                         }
1275         |       scalar  %prec '('
1276                         { $$ = $1; }
1277         |       hsh     %prec '('
1278                         { $$ = $1; }
1279         |       ary     %prec '('
1280                         { $$ = $1; }
1281         ;
1282
1283 /* Basic list expressions */
1284 listexpr:       /* NULL */ %prec PREC_LOW
1285                         { $$ = (OP*)NULL; }
1286         |       argexpr    %prec PREC_LOW
1287                         { $$ = $1; }
1288         ;
1289
1290 listexprcom:    /* NULL */
1291                         { $$ = (OP*)NULL; }
1292         |       expr
1293                         { $$ = $1; }
1294         |       expr ','
1295                         {
1296 #ifdef MAD
1297                           OP* op = newNULLLIST();
1298                           token_getmad($2,op,',');
1299                           $$ = append_elem(OP_LIST, $1, op);
1300 #else
1301                           $$ = $1;
1302 #endif
1303
1304                         }
1305         ;
1306
1307 /* A little bit of trickery to make "for my $foo (@bar)" actually be
1308    lexical */
1309 my_scalar:      scalar
1310                         { PL_parser->in_my = 0; $$ = my($1); }
1311         ;
1312
1313 amper   :       '&' indirob
1314                         { $$ = newCVREF(IVAL($1),$2);
1315                           TOKEN_GETMAD($1,$$,'&');
1316                         }
1317         ;
1318
1319 scalar  :       '$' indirob
1320                         { $$ = newSVREF($2);
1321                           TOKEN_GETMAD($1,$$,'$');
1322                         }
1323         ;
1324
1325 ary     :       '@' indirob
1326                         { $$ = newAVREF($2);
1327                           TOKEN_GETMAD($1,$$,'@');
1328                         }
1329         ;
1330
1331 hsh     :       '%' indirob
1332                         { $$ = newHVREF($2);
1333                           TOKEN_GETMAD($1,$$,'%');
1334                         }
1335         ;
1336
1337 arylen  :       DOLSHARP indirob
1338                         { $$ = newAVREF($2);
1339                           TOKEN_GETMAD($1,$$,'l');
1340                         }
1341         ;
1342
1343 star    :       '*' indirob
1344                         { $$ = newGVREF(0,$2);
1345                           TOKEN_GETMAD($1,$$,'*');
1346                         }
1347         ;
1348
1349 /* Indirect objects */
1350 indirob :       WORD
1351                         { $$ = scalar($1); }
1352         |       scalar %prec PREC_LOW
1353                         { $$ = scalar($1); }
1354         |       block
1355                         { $$ = scope($1); }
1356
1357         |       PRIVATEREF
1358                         { $$ = $1; }
1359         ;