This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
One more to ignore for metaconfig
[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         ;
273
274 /* else and elsif blocks */
275 else    :       /* NULL */
276                         { $$ = (OP*)NULL; }
277         |       ELSE mblock
278                         { ($2)->op_flags |= OPf_PARENS; $$ = scope($2);
279                           TOKEN_GETMAD($1,$$,'o');
280                         }
281         |       ELSIF '(' mexpr ')' mblock else
282                         { PL_parser->copline = (line_t)IVAL($1);
283                             $$ = newCONDOP(0, newSTATEOP(OPf_SPECIAL,NULL,$3), scope($5), $6);
284                             PL_hints |= HINT_BLOCK_SCOPE;
285                           TOKEN_GETMAD($1,$$,'I');
286                           TOKEN_GETMAD($2,$$,'(');
287                           TOKEN_GETMAD($4,$$,')');
288                         }
289         ;
290
291 /* Real conditional expressions */
292 cond    :       IF '(' remember mexpr ')' mblock else
293                         { PL_parser->copline = (line_t)IVAL($1);
294                             $$ = block_end($3,
295                                    newCONDOP(0, $4, scope($6), $7));
296                           TOKEN_GETMAD($1,$$,'I');
297                           TOKEN_GETMAD($2,$$,'(');
298                           TOKEN_GETMAD($5,$$,')');
299                         }
300         |       UNLESS '(' remember miexpr ')' mblock else
301                         { PL_parser->copline = (line_t)IVAL($1);
302                             $$ = block_end($3,
303                                    newCONDOP(0, $4, scope($6), $7));
304                           TOKEN_GETMAD($1,$$,'I');
305                           TOKEN_GETMAD($2,$$,'(');
306                           TOKEN_GETMAD($5,$$,')');
307                         }
308         ;
309
310 /* Cases for a switch statement */
311 case    :       WHEN '(' remember mexpr ')' mblock
312         { $$ = block_end($3,
313                 newWHENOP($4, scope($6))); }
314         |       DEFAULT block
315         { $$ = newWHENOP(0, scope($2)); }
316         ;
317
318 /* Continue blocks */
319 cont    :       /* NULL */
320                         { $$ = (OP*)NULL; }
321         |       CONTINUE block
322                         { $$ = scope($2);
323                           TOKEN_GETMAD($1,$$,'o');
324                         }
325         ;
326
327 /* Loops: while, until, for, and a bare block */
328 loop    :       label WHILE '(' remember texpr ')' mintro mblock cont
329                         { OP *innerop;
330                           PL_parser->copline = (line_t)$2;
331                             $$ = block_end($4,
332                                    newSTATEOP(0, PVAL($1),
333                                      innerop = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
334                                                 IVAL($2), $5, $8, $9, $7)));
335                           TOKEN_GETMAD($1,innerop,'L');
336                           TOKEN_GETMAD($2,innerop,'W');
337                           TOKEN_GETMAD($3,innerop,'(');
338                           TOKEN_GETMAD($6,innerop,')');
339                         }
340
341         |       label UNTIL '(' remember iexpr ')' mintro mblock cont
342                         { OP *innerop;
343                           PL_parser->copline = (line_t)$2;
344                             $$ = block_end($4,
345                                    newSTATEOP(0, PVAL($1),
346                                      innerop = newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
347                                                 IVAL($2), $5, $8, $9, $7)));
348                           TOKEN_GETMAD($1,innerop,'L');
349                           TOKEN_GETMAD($2,innerop,'W');
350                           TOKEN_GETMAD($3,innerop,'(');
351                           TOKEN_GETMAD($6,innerop,')');
352                         }
353         |       label FOR MY remember my_scalar '(' mexpr ')' mblock cont
354                         { OP *innerop;
355                           $$ = block_end($4,
356                              innerop = newFOROP(0, PVAL($1), (line_t)IVAL($2),
357                                             $5, $7, $9, $10));
358                           TOKEN_GETMAD($1,((LISTOP*)innerop)->op_first,'L');
359                           TOKEN_GETMAD($2,((LISTOP*)innerop)->op_first->op_sibling,'W');
360                           TOKEN_GETMAD($3,((LISTOP*)innerop)->op_first->op_sibling,'d');
361                           TOKEN_GETMAD($6,((LISTOP*)innerop)->op_first->op_sibling,'(');
362                           TOKEN_GETMAD($8,((LISTOP*)innerop)->op_first->op_sibling,')');
363                         }
364         |       label FOR scalar '(' remember mexpr ')' mblock cont
365                         { OP *innerop;
366                           $$ = block_end($5,
367                              innerop = newFOROP(0, PVAL($1), (line_t)IVAL($2),
368                                     mod($3, OP_ENTERLOOP), $6, $8, $9));
369                           TOKEN_GETMAD($1,((LISTOP*)innerop)->op_first,'L');
370                           TOKEN_GETMAD($2,((LISTOP*)innerop)->op_first->op_sibling,'W');
371                           TOKEN_GETMAD($4,((LISTOP*)innerop)->op_first->op_sibling,'(');
372                           TOKEN_GETMAD($7,((LISTOP*)innerop)->op_first->op_sibling,')');
373                         }
374         |       label FOR '(' remember mexpr ')' mblock cont
375                         { OP *innerop;
376                           $$ = block_end($4,
377                              innerop = newFOROP(0, PVAL($1), (line_t)IVAL($2),
378                                                     (OP*)NULL, $5, $7, $8));
379                           TOKEN_GETMAD($1,((LISTOP*)innerop)->op_first,'L');
380                           TOKEN_GETMAD($2,((LISTOP*)innerop)->op_first->op_sibling,'W');
381                           TOKEN_GETMAD($3,((LISTOP*)innerop)->op_first->op_sibling,'(');
382                           TOKEN_GETMAD($6,((LISTOP*)innerop)->op_first->op_sibling,')');
383                         }
384         |       label FOR '(' remember mnexpr ';' texpr ';' mintro mnexpr ')'
385                     mblock
386                         /* basically fake up an initialize-while lineseq */
387                         { OP *forop;
388                           PL_parser->copline = (line_t)IVAL($2);
389                           forop = newSTATEOP(0, PVAL($1),
390                                             newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
391                                                 IVAL($2), scalar($7),
392                                                 $12, $10, $9));
393 #ifdef MAD
394                           forop = newUNOP(OP_NULL, 0, append_elem(OP_LINESEQ,
395                                 newSTATEOP(0,
396                                            CopLABEL_alloc(($1)->tk_lval.pval),
397                                            ($5 ? $5 : newOP(OP_NULL, 0)) ),
398                                 forop));
399
400                           token_getmad($2,forop,'3');
401                           token_getmad($3,forop,'(');
402                           token_getmad($6,forop,'1');
403                           token_getmad($8,forop,'2');
404                           token_getmad($11,forop,')');
405                           token_getmad($1,forop,'L');
406 #else
407                           if ($5) {
408                                 forop = append_elem(OP_LINESEQ,
409                                         newSTATEOP(0, CopLABEL_alloc($1), $5),
410                                         forop);
411                           }
412
413
414 #endif
415                           $$ = block_end($4, forop); }
416         |       label block cont  /* a block is a loop that happens once */
417                         { $$ = newSTATEOP(0, PVAL($1),
418                                  newWHILEOP(0, 1, (LOOP*)(OP*)NULL,
419                                             NOLINE, (OP*)NULL, $2, $3, 0));
420                           TOKEN_GETMAD($1,((LISTOP*)$$)->op_first,'L'); }
421         ;
422
423 /* Switch blocks */
424 switch  :       label GIVEN '(' remember mydefsv mexpr ')' mblock
425                         { PL_parser->copline = (line_t) $2;
426                             $$ = block_end($4,
427                                 newSTATEOP(0, PVAL($1),
428                                     newGIVENOP($6, scope($8),
429                                         (PADOFFSET) $5) )); }
430         ;
431
432 /* determine whether there are any new my declarations */
433 mintro  :       /* NULL */
434                         { $$ = (PL_min_intro_pending &&
435                             PL_max_intro_pending >=  PL_min_intro_pending);
436                           intro_my(); }
437
438 /* Normal expression */
439 nexpr   :       /* NULL */
440                         { $$ = (OP*)NULL; }
441         |       sideff
442         ;
443
444 /* Boolean expression */
445 texpr   :       /* NULL means true */
446                         { YYSTYPE tmplval;
447                           (void)scan_num("1", &tmplval);
448                           $$ = tmplval.opval; }
449         |       expr
450         ;
451
452 /* Inverted boolean expression */
453 iexpr   :       expr
454                         { $$ = invert(scalar($1)); }
455         ;
456
457 /* Expression with its own lexical scope */
458 mexpr   :       expr
459                         { $$ = $1; intro_my(); }
460         ;
461
462 mnexpr  :       nexpr
463                         { $$ = $1; intro_my(); }
464         ;
465
466 miexpr  :       iexpr
467                         { $$ = $1; intro_my(); }
468         ;
469
470 /* Optional "MAIN:"-style loop labels */
471 label   :       /* empty */
472                         {
473 #ifdef MAD
474                           YYSTYPE tmplval;
475                           tmplval.pval = NULL;
476                           $$ = newTOKEN(OP_NULL, tmplval, 0);
477 #else
478                           $$ = NULL;
479 #endif
480                         }
481         |       LABEL
482         ;
483
484 /* Some kind of declaration - just hang on peg in the parse tree */
485 decl    :       format
486                         { $$ = $1; }
487         |       subrout
488                         { $$ = $1; }
489         |       mysubrout
490                         { $$ = $1; }
491         |       package
492                         { $$ = $1; }
493         |       use
494                         { $$ = $1; }
495
496     /* these two are only used by MAD */
497
498         |       peg
499                         { $$ = $1; }
500         ;
501
502 peg     :       PEG
503                         { $$ = newOP(OP_NULL,0);
504                           TOKEN_GETMAD($1,$$,'p');
505                         }
506         ;
507
508 format  :       FORMAT startformsub formname block
509                         { SvREFCNT_inc_simple_void(PL_compcv);
510 #ifdef MAD
511                           $$ = newFORM($2, $3, $4);
512                           prepend_madprops($1->tk_mad, $$, 'F');
513                           $1->tk_mad = 0;
514                           token_free($1);
515 #else
516                           newFORM($2, $3, $4);
517                           $$ = (OP*)NULL;
518 #endif
519                         }
520         ;
521
522 formname:       WORD            { $$ = $1; }
523         |       /* NULL */      { $$ = (OP*)NULL; }
524         ;
525
526 /* Unimplemented "my sub foo { }" */
527 mysubrout:      MYSUB startsub subname proto subattrlist subbody
528                         { SvREFCNT_inc_simple_void(PL_compcv);
529 #ifdef MAD
530                           $$ = newMYSUB($2, $3, $4, $5, $6);
531                           token_getmad($1,$$,'d');
532 #else
533                           newMYSUB($2, $3, $4, $5, $6);
534                           $$ = (OP*)NULL;
535 #endif
536                         }
537         ;
538
539 /* Subroutine definition */
540 subrout :       SUB startsub subname proto subattrlist subbody
541                         { SvREFCNT_inc_simple_void(PL_compcv);
542 #ifdef MAD
543                           {
544                               OP* o = newSVOP(OP_ANONCODE, 0,
545                                 (SV*)newATTRSUB($2, $3, $4, $5, $6));
546                               $$ = newOP(OP_NULL,0);
547                               op_getmad(o,$$,'&');
548                               op_getmad($3,$$,'n');
549                               op_getmad($4,$$,'s');
550                               op_getmad($5,$$,'a');
551                               token_getmad($1,$$,'d');
552                               append_madprops($6->op_madprop, $$, 0);
553                               $6->op_madprop = 0;
554                             }
555 #else
556                           newATTRSUB($2, $3, $4, $5, $6);
557                           $$ = (OP*)NULL;
558 #endif
559                         }
560         ;
561
562 startsub:       /* NULL */      /* start a regular subroutine scope */
563                         { $$ = start_subparse(FALSE, 0);
564                             SAVEFREESV(PL_compcv); }
565
566         ;
567
568 startanonsub:   /* NULL */      /* start an anonymous subroutine scope */
569                         { $$ = start_subparse(FALSE, CVf_ANON);
570                             SAVEFREESV(PL_compcv); }
571         ;
572
573 startformsub:   /* NULL */      /* start a format subroutine scope */
574                         { $$ = start_subparse(TRUE, 0);
575                             SAVEFREESV(PL_compcv); }
576         ;
577
578 /* Name of a subroutine - must be a bareword, could be special */
579 subname :       WORD    { const char *const name = SvPV_nolen_const(((SVOP*)$1)->op_sv);
580                           if (strEQ(name, "BEGIN") || strEQ(name, "END")
581                               || strEQ(name, "INIT") || strEQ(name, "CHECK")
582                               || strEQ(name, "UNITCHECK"))
583                               CvSPECIAL_on(PL_compcv);
584                           $$ = $1; }
585         ;
586
587 /* Subroutine prototype */
588 proto   :       /* NULL */
589                         { $$ = (OP*)NULL; }
590         |       THING
591         ;
592
593 /* Optional list of subroutine attributes */
594 subattrlist:    /* NULL */
595                         { $$ = (OP*)NULL; }
596         |       COLONATTR THING
597                         { $$ = $2;
598                           TOKEN_GETMAD($1,$$,':');
599                         }
600         |       COLONATTR
601                         { $$ = IF_MAD(
602                                     newOP(OP_NULL, 0),
603                                     (OP*)NULL
604                                 );
605                           TOKEN_GETMAD($1,$$,':');
606                         }
607         ;
608
609 /* List of attributes for a "my" variable declaration */
610 myattrlist:     COLONATTR THING
611                         { $$ = $2;
612                           TOKEN_GETMAD($1,$$,':');
613                         }
614         |       COLONATTR
615                         { $$ = IF_MAD(
616                                     newOP(OP_NULL, 0),
617                                     (OP*)NULL
618                                 );
619                           TOKEN_GETMAD($1,$$,':');
620                         }
621         ;
622
623 /* Subroutine body - either null or a block */
624 subbody :       block   { $$ = $1; }
625         |       ';'     { $$ = IF_MAD(
626                                     newOP(OP_NULL,0),
627                                     (OP*)NULL
628                                 );
629                           PL_parser->expect = XSTATE;
630                           TOKEN_GETMAD($1,$$,';');
631                         }
632         ;
633
634 package :       PACKAGE WORD ';'
635                         {
636 #ifdef MAD
637                           $$ = package($2);
638                           token_getmad($1,$$,'o');
639                           token_getmad($3,$$,';');
640 #else
641                           package($2);
642                           $$ = (OP*)NULL;
643 #endif
644                         }
645         ;
646
647 use     :       USE startsub
648                         { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
649                     WORD WORD listexpr ';'
650                         { SvREFCNT_inc_simple_void(PL_compcv);
651 #ifdef MAD
652                           $$ = utilize(IVAL($1), $2, $4, $5, $6);
653                           token_getmad($1,$$,'o');
654                           token_getmad($7,$$,';');
655                           if (PL_parser->rsfp_filters &&
656                                       AvFILLp(PL_parser->rsfp_filters) >= 0)
657                               append_madprops(newMADPROP('!', MAD_PV, "", 0), $$, 0);
658 #else
659                           utilize(IVAL($1), $2, $4, $5, $6);
660                           $$ = (OP*)NULL;
661 #endif
662                         }
663         ;
664
665 /* Ordinary expressions; logical combinations */
666 expr    :       expr ANDOP expr
667                         { $$ = newLOGOP(OP_AND, 0, $1, $3);
668                           TOKEN_GETMAD($2,$$,'o');
669                         }
670         |       expr OROP expr
671                         { $$ = newLOGOP(IVAL($2), 0, $1, $3);
672                           TOKEN_GETMAD($2,$$,'o');
673                         }
674         |       expr DOROP expr
675                         { $$ = newLOGOP(OP_DOR, 0, $1, $3);
676                           TOKEN_GETMAD($2,$$,'o');
677                         }
678         |       argexpr %prec PREC_LOW
679         ;
680
681 /* Expressions are a list of terms joined by commas */
682 argexpr :       argexpr ','
683                         {
684 #ifdef MAD
685                           OP* op = newNULLLIST();
686                           token_getmad($2,op,',');
687                           $$ = append_elem(OP_LIST, $1, op);
688 #else
689                           $$ = $1;
690 #endif
691                         }
692         |       argexpr ',' term
693                         { 
694                           OP* term = $3;
695                           DO_MAD(
696                               term = newUNOP(OP_NULL, 0, term);
697                               token_getmad($2,term,',');
698                           )
699                           $$ = append_elem(OP_LIST, $1, term);
700                         }
701         |       term %prec PREC_LOW
702         ;
703
704 /* List operators */
705 listop  :       LSTOP indirob argexpr /* map {...} @args or print $fh @args */
706                         { $$ = convert(IVAL($1), OPf_STACKED,
707                                 prepend_elem(OP_LIST, newGVREF(IVAL($1),$2), $3) );
708                           TOKEN_GETMAD($1,$$,'o');
709                         }
710         |       FUNC '(' indirob expr ')'      /* print ($fh @args */
711                         { $$ = convert(IVAL($1), OPf_STACKED,
712                                 prepend_elem(OP_LIST, newGVREF(IVAL($1),$3), $4) );
713                           TOKEN_GETMAD($1,$$,'o');
714                           TOKEN_GETMAD($2,$$,'(');
715                           TOKEN_GETMAD($5,$$,')');
716                         }
717         |       term ARROW method '(' listexprcom ')' /* $foo->bar(list) */
718                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
719                                 append_elem(OP_LIST,
720                                     prepend_elem(OP_LIST, scalar($1), $5),
721                                     newUNOP(OP_METHOD, 0, $3)));
722                           TOKEN_GETMAD($2,$$,'A');
723                           TOKEN_GETMAD($4,$$,'(');
724                           TOKEN_GETMAD($6,$$,')');
725                         }
726         |       term ARROW method                     /* $foo->bar */
727                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
728                                 append_elem(OP_LIST, scalar($1),
729                                     newUNOP(OP_METHOD, 0, $3)));
730                           TOKEN_GETMAD($2,$$,'A');
731                         }
732         |       METHOD indirob listexpr              /* new Class @args */
733                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
734                                 append_elem(OP_LIST,
735                                     prepend_elem(OP_LIST, $2, $3),
736                                     newUNOP(OP_METHOD, 0, $1)));
737                         }
738         |       FUNCMETH indirob '(' listexprcom ')' /* method $object (@args) */
739                         { $$ = convert(OP_ENTERSUB, OPf_STACKED,
740                                 append_elem(OP_LIST,
741                                     prepend_elem(OP_LIST, $2, $4),
742                                     newUNOP(OP_METHOD, 0, $1)));
743                           TOKEN_GETMAD($3,$$,'(');
744                           TOKEN_GETMAD($5,$$,')');
745                         }
746         |       LSTOP listexpr                       /* print @args */
747                         { $$ = convert(IVAL($1), 0, $2);
748                           TOKEN_GETMAD($1,$$,'o');
749                         }
750         |       FUNC '(' listexprcom ')'             /* print (@args) */
751                         { $$ = convert(IVAL($1), 0, $3);
752                           TOKEN_GETMAD($1,$$,'o');
753                           TOKEN_GETMAD($2,$$,'(');
754                           TOKEN_GETMAD($4,$$,')');
755                         }
756         |       LSTOPSUB startanonsub block /* sub f(&@);   f { foo } ... */
757                         { SvREFCNT_inc_simple_void(PL_compcv);
758                           $<opval>$ = newANONATTRSUB($2, 0, (OP*)NULL, $3); }
759                     listexpr            %prec LSTOP  /* ... @bar */
760                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
761                                  append_elem(OP_LIST,
762                                    prepend_elem(OP_LIST, $<opval>4, $5), $1));
763                         }
764         ;
765
766 /* Names of methods. May use $object->$methodname */
767 method  :       METHOD
768         |       scalar
769         ;
770
771 /* Some kind of subscripted expression */
772 subscripted:    star '{' expr ';' '}'        /* *main::{something} */
773                         /* In this and all the hash accessors, ';' is
774                          * provided by the tokeniser */
775                         { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3));
776                             PL_parser->expect = XOPERATOR;
777                           TOKEN_GETMAD($2,$$,'{');
778                           TOKEN_GETMAD($4,$$,';');
779                           TOKEN_GETMAD($5,$$,'}');
780                         }
781         |       scalar '[' expr ']'          /* $array[$element] */
782                         { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3));
783                           TOKEN_GETMAD($2,$$,'[');
784                           TOKEN_GETMAD($4,$$,']');
785                         }
786         |       term ARROW '[' expr ']'      /* somearef->[$element] */
787                         { $$ = newBINOP(OP_AELEM, 0,
788                                         ref(newAVREF($1),OP_RV2AV),
789                                         scalar($4));
790                           TOKEN_GETMAD($2,$$,'a');
791                           TOKEN_GETMAD($3,$$,'[');
792                           TOKEN_GETMAD($5,$$,']');
793                         }
794         |       subscripted '[' expr ']'    /* $foo->[$bar]->[$baz] */
795                         { $$ = newBINOP(OP_AELEM, 0,
796                                         ref(newAVREF($1),OP_RV2AV),
797                                         scalar($3));
798                           TOKEN_GETMAD($2,$$,'[');
799                           TOKEN_GETMAD($4,$$,']');
800                         }
801         |       scalar '{' expr ';' '}'    /* $foo->{bar();} */
802                         { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
803                             PL_parser->expect = XOPERATOR;
804                           TOKEN_GETMAD($2,$$,'{');
805                           TOKEN_GETMAD($4,$$,';');
806                           TOKEN_GETMAD($5,$$,'}');
807                         }
808         |       term ARROW '{' expr ';' '}' /* somehref->{bar();} */
809                         { $$ = newBINOP(OP_HELEM, 0,
810                                         ref(newHVREF($1),OP_RV2HV),
811                                         jmaybe($4));
812                             PL_parser->expect = XOPERATOR;
813                           TOKEN_GETMAD($2,$$,'a');
814                           TOKEN_GETMAD($3,$$,'{');
815                           TOKEN_GETMAD($5,$$,';');
816                           TOKEN_GETMAD($6,$$,'}');
817                         }
818         |       subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */
819                         { $$ = newBINOP(OP_HELEM, 0,
820                                         ref(newHVREF($1),OP_RV2HV),
821                                         jmaybe($3));
822                             PL_parser->expect = XOPERATOR;
823                           TOKEN_GETMAD($2,$$,'{');
824                           TOKEN_GETMAD($4,$$,';');
825                           TOKEN_GETMAD($5,$$,'}');
826                         }
827         |       term ARROW '(' ')'          /* $subref->() */
828                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
829                                    newCVREF(0, scalar($1)));
830                           TOKEN_GETMAD($2,$$,'a');
831                           TOKEN_GETMAD($3,$$,'(');
832                           TOKEN_GETMAD($4,$$,')');
833                         }
834         |       term ARROW '(' expr ')'     /* $subref->(@args) */
835                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
836                                    append_elem(OP_LIST, $4,
837                                        newCVREF(0, scalar($1))));
838                           TOKEN_GETMAD($2,$$,'a');
839                           TOKEN_GETMAD($3,$$,'(');
840                           TOKEN_GETMAD($5,$$,')');
841                         }
842
843         |       subscripted '(' expr ')'   /* $foo->{bar}->(@args) */
844                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
845                                    append_elem(OP_LIST, $3,
846                                                newCVREF(0, scalar($1))));
847                           TOKEN_GETMAD($2,$$,'(');
848                           TOKEN_GETMAD($4,$$,')');
849                         }
850         |       subscripted '(' ')'        /* $foo->{bar}->() */
851                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
852                                    newCVREF(0, scalar($1)));
853                           TOKEN_GETMAD($2,$$,'(');
854                           TOKEN_GETMAD($3,$$,')');
855                         }
856         |       '(' expr ')' '[' expr ']'            /* list slice */
857                         { $$ = newSLICEOP(0, $5, $2);
858                           TOKEN_GETMAD($1,$$,'(');
859                           TOKEN_GETMAD($3,$$,')');
860                           TOKEN_GETMAD($4,$$,'[');
861                           TOKEN_GETMAD($6,$$,']');
862                         }
863         |       '(' ')' '[' expr ']'                 /* empty list slice! */
864                         { $$ = newSLICEOP(0, $4, (OP*)NULL);
865                           TOKEN_GETMAD($1,$$,'(');
866                           TOKEN_GETMAD($2,$$,')');
867                           TOKEN_GETMAD($3,$$,'[');
868                           TOKEN_GETMAD($5,$$,']');
869                         }
870     ;
871
872 /* Binary operators between terms */
873 termbinop:      term ASSIGNOP term                     /* $x = $y */
874                         { $$ = newASSIGNOP(OPf_STACKED, $1, IVAL($2), $3);
875                           TOKEN_GETMAD($2,$$,'o');
876                         }
877         |       term POWOP term                        /* $x ** $y */
878                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
879                           TOKEN_GETMAD($2,$$,'o');
880                         }
881         |       term MULOP term                        /* $x * $y, $x x $y */
882                         {   if (IVAL($2) != OP_REPEAT)
883                                 scalar($1);
884                             $$ = newBINOP(IVAL($2), 0, $1, scalar($3));
885                           TOKEN_GETMAD($2,$$,'o');
886                         }
887         |       term ADDOP term                        /* $x + $y */
888                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
889                           TOKEN_GETMAD($2,$$,'o');
890                         }
891         |       term SHIFTOP term                      /* $x >> $y, $x << $y */
892                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
893                           TOKEN_GETMAD($2,$$,'o');
894                         }
895         |       term RELOP term                        /* $x > $y, etc. */
896                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
897                           TOKEN_GETMAD($2,$$,'o');
898                         }
899         |       term EQOP term                         /* $x == $y, $x eq $y */
900                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
901                           TOKEN_GETMAD($2,$$,'o');
902                         }
903         |       term BITANDOP term                     /* $x & $y */
904                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
905                           TOKEN_GETMAD($2,$$,'o');
906                         }
907         |       term BITOROP term                      /* $x | $y */
908                         { $$ = newBINOP(IVAL($2), 0, scalar($1), scalar($3));
909                           TOKEN_GETMAD($2,$$,'o');
910                         }
911         |       term DOTDOT term                       /* $x..$y, $x...$y */
912                         {
913                           $$ = newRANGE(IVAL($2), scalar($1), scalar($3));
914                           DO_MAD({
915                               UNOP *op;
916                               op = (UNOP*)$$;
917                               op = (UNOP*)op->op_first; /* get to flop */
918                               op = (UNOP*)op->op_first; /* get to flip */
919                               op = (UNOP*)op->op_first; /* get to range */
920                               token_getmad($2,(OP*)op,'o');
921                             })
922                         }
923         |       term ANDAND term                       /* $x && $y */
924                         { $$ = newLOGOP(OP_AND, 0, $1, $3);
925                           TOKEN_GETMAD($2,$$,'o');
926                         }
927         |       term OROR term                         /* $x || $y */
928                         { $$ = newLOGOP(OP_OR, 0, $1, $3);
929                           TOKEN_GETMAD($2,$$,'o');
930                         }
931         |       term DORDOR term                       /* $x // $y */
932                         { $$ = newLOGOP(OP_DOR, 0, $1, $3);
933                           TOKEN_GETMAD($2,$$,'o');
934                         }
935         |       term MATCHOP term                      /* $x =~ /$y/ */
936                         { $$ = bind_match(IVAL($2), $1, $3);
937                           TOKEN_GETMAD($2,
938                                 ($$->op_type == OP_NOT
939                                     ? ((UNOP*)$$)->op_first : $$),
940                                 '~');
941                         }
942     ;
943
944 /* Unary operators and terms */
945 termunop : '-' term %prec UMINUS                       /* -$x */
946                         { $$ = newUNOP(OP_NEGATE, 0, scalar($2));
947                           TOKEN_GETMAD($1,$$,'o');
948                         }
949         |       '+' term %prec UMINUS                  /* +$x */
950                         { $$ = IF_MAD(
951                                     newUNOP(OP_NULL, 0, $2),
952                                     $2
953                                 );
954                           TOKEN_GETMAD($1,$$,'+');
955                         }
956         |       '!' term                               /* !$x */
957                         { $$ = newUNOP(OP_NOT, 0, scalar($2));
958                           TOKEN_GETMAD($1,$$,'o');
959                         }
960         |       '~' term                               /* ~$x */
961                         { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));
962                           TOKEN_GETMAD($1,$$,'o');
963                         }
964         |       term POSTINC                           /* $x++ */
965                         { $$ = newUNOP(OP_POSTINC, 0,
966                                         mod(scalar($1), OP_POSTINC));
967                           TOKEN_GETMAD($2,$$,'o');
968                         }
969         |       term POSTDEC                           /* $x-- */
970                         { $$ = newUNOP(OP_POSTDEC, 0,
971                                         mod(scalar($1), OP_POSTDEC));
972                           TOKEN_GETMAD($2,$$,'o');
973                         }
974         |       PREINC term                            /* ++$x */
975                         { $$ = newUNOP(OP_PREINC, 0,
976                                         mod(scalar($2), OP_PREINC));
977                           TOKEN_GETMAD($1,$$,'o');
978                         }
979         |       PREDEC term                            /* --$x */
980                         { $$ = newUNOP(OP_PREDEC, 0,
981                                         mod(scalar($2), OP_PREDEC));
982                           TOKEN_GETMAD($1,$$,'o');
983                         }
984
985     ;
986
987 /* Constructors for anonymous data */
988 anonymous:      '[' expr ']'
989                         { $$ = newANONLIST($2);
990                           TOKEN_GETMAD($1,$$,'[');
991                           TOKEN_GETMAD($3,$$,']');
992                         }
993         |       '[' ']'
994                         { $$ = newANONLIST((OP*)NULL);
995                           TOKEN_GETMAD($1,$$,'[');
996                           TOKEN_GETMAD($2,$$,']');
997                         }
998         |       HASHBRACK expr ';' '}'  %prec '(' /* { foo => "Bar" } */
999                         { $$ = newANONHASH($2);
1000                           TOKEN_GETMAD($1,$$,'{');
1001                           TOKEN_GETMAD($3,$$,';');
1002                           TOKEN_GETMAD($4,$$,'}');
1003                         }
1004         |       HASHBRACK ';' '}'       %prec '(' /* { } (';' by tokener) */
1005                         { $$ = newANONHASH((OP*)NULL);
1006                           TOKEN_GETMAD($1,$$,'{');
1007                           TOKEN_GETMAD($2,$$,';');
1008                           TOKEN_GETMAD($3,$$,'}');
1009                         }
1010         |       ANONSUB startanonsub proto subattrlist block    %prec '('
1011                         { SvREFCNT_inc_simple_void(PL_compcv);
1012                           $$ = newANONATTRSUB($2, $3, $4, $5);
1013                           TOKEN_GETMAD($1,$$,'o');
1014                           OP_GETMAD($3,$$,'s');
1015                           OP_GETMAD($4,$$,'a');
1016                         }
1017
1018     ;
1019
1020 /* Things called with "do" */
1021 termdo  :       DO term %prec UNIOP                     /* do $filename */
1022                         { $$ = dofile($2, IVAL($1));
1023                           TOKEN_GETMAD($1,$$,'o');
1024                         }
1025         |       DO block        %prec '('               /* do { code */
1026                         { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2));
1027                           TOKEN_GETMAD($1,$$,'D');
1028                         }
1029         |       DO WORD '(' ')'                         /* do somesub() */
1030                         { $$ = newUNOP(OP_ENTERSUB,
1031                             OPf_SPECIAL|OPf_STACKED,
1032                             prepend_elem(OP_LIST,
1033                                 scalar(newCVREF(
1034                                     (OPpENTERSUB_AMPER<<8),
1035                                     scalar($2)
1036                                 )),(OP*)NULL)); dep();
1037                           TOKEN_GETMAD($1,$$,'o');
1038                           TOKEN_GETMAD($3,$$,'(');
1039                           TOKEN_GETMAD($4,$$,')');
1040                         }
1041         |       DO WORD '(' expr ')'                    /* do somesub(@args) */
1042                         { $$ = newUNOP(OP_ENTERSUB,
1043                             OPf_SPECIAL|OPf_STACKED,
1044                             append_elem(OP_LIST,
1045                                 $4,
1046                                 scalar(newCVREF(
1047                                     (OPpENTERSUB_AMPER<<8),
1048                                     scalar($2)
1049                                 )))); dep();
1050                           TOKEN_GETMAD($1,$$,'o');
1051                           TOKEN_GETMAD($3,$$,'(');
1052                           TOKEN_GETMAD($5,$$,')');
1053                         }
1054         |       DO scalar '(' ')'                      /* do $subref () */
1055                         { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
1056                             prepend_elem(OP_LIST,
1057                                 scalar(newCVREF(0,scalar($2))), (OP*)NULL)); dep();
1058                           TOKEN_GETMAD($1,$$,'o');
1059                           TOKEN_GETMAD($3,$$,'(');
1060                           TOKEN_GETMAD($4,$$,')');
1061                         }
1062         |       DO scalar '(' expr ')'                 /* do $subref (@args) */
1063                         { $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
1064                             prepend_elem(OP_LIST,
1065                                 $4,
1066                                 scalar(newCVREF(0,scalar($2))))); dep();
1067                           TOKEN_GETMAD($1,$$,'o');
1068                           TOKEN_GETMAD($3,$$,'(');
1069                           TOKEN_GETMAD($5,$$,')');
1070                         }
1071
1072         ;
1073
1074 term    :       termbinop
1075         |       termunop
1076         |       anonymous
1077         |       termdo
1078         |       term '?' term ':' term
1079                         { $$ = newCONDOP(0, $1, $3, $5);
1080                           TOKEN_GETMAD($2,$$,'?');
1081                           TOKEN_GETMAD($4,$$,':');
1082                         }
1083         |       REFGEN term                          /* \$x, \@y, \%z */
1084                         { $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN));
1085                           TOKEN_GETMAD($1,$$,'o');
1086                         }
1087         |       myattrterm      %prec UNIOP
1088                         { $$ = $1; }
1089         |       LOCAL term      %prec UNIOP
1090                         { $$ = localize($2,IVAL($1));
1091                           TOKEN_GETMAD($1,$$,'k');
1092                         }
1093         |       '(' expr ')'
1094                         { $$ = sawparens(IF_MAD(newUNOP(OP_NULL,0,$2), $2));
1095                           TOKEN_GETMAD($1,$$,'(');
1096                           TOKEN_GETMAD($3,$$,')');
1097                         }
1098         |       '(' ')'
1099                         { $$ = sawparens(newNULLLIST());
1100                           TOKEN_GETMAD($1,$$,'(');
1101                           TOKEN_GETMAD($2,$$,')');
1102                         }
1103         |       scalar  %prec '('
1104                         { $$ = $1; }
1105         |       star    %prec '('
1106                         { $$ = $1; }
1107         |       hsh     %prec '('
1108                         { $$ = $1; }
1109         |       ary     %prec '('
1110                         { $$ = $1; }
1111         |       arylen  %prec '('                    /* $#x, $#{ something } */
1112                         { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
1113         |       subscripted
1114                         { $$ = $1; }
1115         |       ary '[' expr ']'                     /* array slice */
1116                         { $$ = prepend_elem(OP_ASLICE,
1117                                 newOP(OP_PUSHMARK, 0),
1118                                     newLISTOP(OP_ASLICE, 0,
1119                                         list($3),
1120                                         ref($1, OP_ASLICE)));
1121                           TOKEN_GETMAD($2,$$,'[');
1122                           TOKEN_GETMAD($4,$$,']');
1123                         }
1124         |       ary '{' expr ';' '}'                 /* @hash{@keys} */
1125                         { $$ = prepend_elem(OP_HSLICE,
1126                                 newOP(OP_PUSHMARK, 0),
1127                                     newLISTOP(OP_HSLICE, 0,
1128                                         list($3),
1129                                         ref(oopsHV($1), OP_HSLICE)));
1130                             PL_parser->expect = XOPERATOR;
1131                           TOKEN_GETMAD($2,$$,'{');
1132                           TOKEN_GETMAD($4,$$,';');
1133                           TOKEN_GETMAD($5,$$,'}');
1134                         }
1135         |       THING   %prec '('
1136                         { $$ = $1; }
1137         |       amper                                /* &foo; */
1138                         { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
1139         |       amper '(' ')'                        /* &foo() */
1140                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1));
1141                           TOKEN_GETMAD($2,$$,'(');
1142                           TOKEN_GETMAD($3,$$,')');
1143                         }
1144         |       amper '(' expr ')'                   /* &foo(@args) */
1145                         {
1146                           $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1147                                 append_elem(OP_LIST, $3, scalar($1)));
1148                           DO_MAD({
1149                               OP* op = $$;
1150                               if (op->op_type == OP_CONST) { /* defeat const fold */
1151                                 op = (OP*)op->op_madprop->mad_val;
1152                               }
1153                               token_getmad($2,op,'(');
1154                               token_getmad($4,op,')');
1155                           })
1156                         }
1157         |       NOAMP WORD listexpr                  /* foo(@args) */
1158                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1159                             append_elem(OP_LIST, $3, scalar($2)));
1160                           TOKEN_GETMAD($1,$$,'o');
1161                         }
1162         |       LOOPEX  /* loop exiting command (goto, last, dump, etc) */
1163                         { $$ = newOP(IVAL($1), OPf_SPECIAL);
1164                             PL_hints |= HINT_BLOCK_SCOPE;
1165                           TOKEN_GETMAD($1,$$,'o');
1166                         }
1167         |       LOOPEX term
1168                         { $$ = newLOOPEX(IVAL($1),$2);
1169                           TOKEN_GETMAD($1,$$,'o');
1170                         }
1171         |       NOTOP argexpr                        /* not $foo */
1172                         { $$ = newUNOP(OP_NOT, 0, scalar($2));
1173                           TOKEN_GETMAD($1,$$,'o');
1174                         }
1175         |       UNIOP                                /* Unary op, $_ implied */
1176                         { $$ = newOP(IVAL($1), 0);
1177                           TOKEN_GETMAD($1,$$,'o');
1178                         }
1179         |       UNIOP block                          /* eval { foo }* */
1180                         { $$ = newUNOP(IVAL($1), 0, $2);
1181                           TOKEN_GETMAD($1,$$,'o');
1182                         }
1183         |       UNIOP term                           /* Unary op */
1184                         { $$ = newUNOP(IVAL($1), 0, $2);
1185                           TOKEN_GETMAD($1,$$,'o');
1186                         }
1187         |       REQUIRE                              /* require, $_ implied */
1188                         { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0);
1189                           TOKEN_GETMAD($1,$$,'o');
1190                         }
1191         |       REQUIRE term                         /* require Foo */
1192                         { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2);
1193                           TOKEN_GETMAD($1,$$,'o');
1194                         }
1195         |       UNIOPSUB
1196                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
1197         |       UNIOPSUB term                        /* Sub treated as unop */
1198                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1199                             append_elem(OP_LIST, $2, scalar($1))); }
1200         |       FUNC0                                /* Nullary operator */
1201                         { $$ = newOP(IVAL($1), 0);
1202                           TOKEN_GETMAD($1,$$,'o');
1203                         }
1204         |       FUNC0 '(' ')'
1205                         { $$ = newOP(IVAL($1), 0);
1206                           TOKEN_GETMAD($1,$$,'o');
1207                           TOKEN_GETMAD($2,$$,'(');
1208                           TOKEN_GETMAD($3,$$,')');
1209                         }
1210         |       FUNC0SUB                             /* Sub treated as nullop */
1211                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1212                                 scalar($1)); }
1213         |       FUNC1 '(' ')'                        /* not () */
1214                         { $$ = (IVAL($1) == OP_NOT)
1215                             ? newUNOP(IVAL($1), 0, newSVOP(OP_CONST, 0, newSViv(0)))
1216                             : newOP(IVAL($1), OPf_SPECIAL);
1217
1218                           TOKEN_GETMAD($1,$$,'o');
1219                           TOKEN_GETMAD($2,$$,'(');
1220                           TOKEN_GETMAD($3,$$,')');
1221                         }
1222         |       FUNC1 '(' expr ')'                   /* not($foo) */
1223                         { $$ = newUNOP(IVAL($1), 0, $3);
1224                           TOKEN_GETMAD($1,$$,'o');
1225                           TOKEN_GETMAD($2,$$,'(');
1226                           TOKEN_GETMAD($4,$$,')');
1227                         }
1228         |       PMFUNC '(' argexpr ')'          /* m//, s///, tr/// */
1229                         { $$ = pmruntime($1, $3, 1);
1230                           TOKEN_GETMAD($2,$$,'(');
1231                           TOKEN_GETMAD($4,$$,')');
1232                         }
1233         |       WORD
1234         |       listop
1235         |       YADAYADA
1236                         {
1237                           $$ = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0),
1238                                 newSVOP(OP_CONST, 0, newSVpvs("Unimplemented")));
1239                         }
1240         ;
1241
1242 /* "my" declarations, with optional attributes */
1243 myattrterm:     MY myterm myattrlist
1244                         { $$ = my_attrs($2,$3);
1245                           DO_MAD(
1246                               token_getmad($1,$$,'d');
1247                               append_madprops($3->op_madprop, $$, 'a');
1248                               $3->op_madprop = 0;
1249                           )
1250                         }
1251         |       MY myterm
1252                         { $$ = localize($2,IVAL($1));
1253                           TOKEN_GETMAD($1,$$,'d');
1254                         }
1255         ;
1256
1257 /* Things that can be "my"'d */
1258 myterm  :       '(' expr ')'
1259                         { $$ = sawparens($2);
1260                           TOKEN_GETMAD($1,$$,'(');
1261                           TOKEN_GETMAD($3,$$,')');
1262                         }
1263         |       '(' ')'
1264                         { $$ = sawparens(newNULLLIST());
1265                           TOKEN_GETMAD($1,$$,'(');
1266                           TOKEN_GETMAD($2,$$,')');
1267                         }
1268         |       scalar  %prec '('
1269                         { $$ = $1; }
1270         |       hsh     %prec '('
1271                         { $$ = $1; }
1272         |       ary     %prec '('
1273                         { $$ = $1; }
1274         ;
1275
1276 /* Basic list expressions */
1277 listexpr:       /* NULL */ %prec PREC_LOW
1278                         { $$ = (OP*)NULL; }
1279         |       argexpr    %prec PREC_LOW
1280                         { $$ = $1; }
1281         ;
1282
1283 listexprcom:    /* NULL */
1284                         { $$ = (OP*)NULL; }
1285         |       expr
1286                         { $$ = $1; }
1287         |       expr ','
1288                         {
1289 #ifdef MAD
1290                           OP* op = newNULLLIST();
1291                           token_getmad($2,op,',');
1292                           $$ = append_elem(OP_LIST, $1, op);
1293 #else
1294                           $$ = $1;
1295 #endif
1296
1297                         }
1298         ;
1299
1300 /* A little bit of trickery to make "for my $foo (@bar)" actually be
1301    lexical */
1302 my_scalar:      scalar
1303                         { PL_parser->in_my = 0; $$ = my($1); }
1304         ;
1305
1306 amper   :       '&' indirob
1307                         { $$ = newCVREF(IVAL($1),$2);
1308                           TOKEN_GETMAD($1,$$,'&');
1309                         }
1310         ;
1311
1312 scalar  :       '$' indirob
1313                         { $$ = newSVREF($2);
1314                           TOKEN_GETMAD($1,$$,'$');
1315                         }
1316         ;
1317
1318 ary     :       '@' indirob
1319                         { $$ = newAVREF($2);
1320                           TOKEN_GETMAD($1,$$,'@');
1321                         }
1322         ;
1323
1324 hsh     :       '%' indirob
1325                         { $$ = newHVREF($2);
1326                           TOKEN_GETMAD($1,$$,'%');
1327                         }
1328         ;
1329
1330 arylen  :       DOLSHARP indirob
1331                         { $$ = newAVREF($2);
1332                           TOKEN_GETMAD($1,$$,'l');
1333                         }
1334         ;
1335
1336 star    :       '*' indirob
1337                         { $$ = newGVREF(0,$2);
1338                           TOKEN_GETMAD($1,$$,'*');
1339                         }
1340         ;
1341
1342 /* Indirect objects */
1343 indirob :       WORD
1344                         { $$ = scalar($1); }
1345         |       scalar %prec PREC_LOW
1346                         { $$ = scalar($1); }
1347         |       block
1348                         { $$ = scope($1); }
1349
1350         |       PRIVATEREF
1351                         { $$ = $1; }
1352         ;