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