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