This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Distinguish C- and perly- literals - PERLY_PAREN_OPEN
[perl5.git] / perly.y
1 /*    perly.y
2  *
3  *    Copyright (c) 1991-2002, 2003, 2004, 2005, 2006 Larry Wall
4  *    Copyright (c) 2007, 2008, 2009, 2010, 2011 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  * The main job of this grammar is to call the various newFOO()
24  * functions in op.c to build a syntax tree of OP structs.
25  * It relies on the lexer in toke.c to do the tokenizing.
26  *
27  * Note: due to the way that the cleanup code works WRT to freeing ops on
28  * the parse stack, it is dangerous to assign to the $n variables within
29  * an action.
30  */
31
32 /*  Make the parser re-entrant. */
33
34 %define api.pure
35
36 %start grammar
37
38 %union {
39     I32 ival; /* __DEFAULT__ (marker for regen_perly.pl;
40                                 must always be 1st union member) */
41     char *pval;
42     OP *opval;
43     GV *gvval;
44 }
45
46 %token <ival> GRAMPROG GRAMEXPR GRAMBLOCK GRAMBARESTMT GRAMFULLSTMT GRAMSTMTSEQ GRAMSUBSIGNATURE
47
48 %token <ival> PERLY_AMPERSAND
49 %token <ival> PERLY_BRACE_OPEN
50 %token <ival> PERLY_BRACE_CLOSE
51 %token <ival> PERLY_BRACKET_OPEN
52 %token <ival> PERLY_BRACKET_CLOSE
53 %token <ival> PERLY_COMMA
54 %token <ival> PERLY_DOT
55 %token <ival> PERLY_EQUAL_SIGN
56 %token <ival> PERLY_MINUS
57 %token <ival> PERLY_PERCENT_SIGN
58 %token <ival> PERLY_PLUS
59 %token <ival> PERLY_SEMICOLON
60 %token <ival> PERLY_SNAIL
61
62 %token <opval> BAREWORD METHOD FUNCMETH THING PMFUNC PRIVATEREF QWLIST
63 %token <opval> FUNC0OP FUNC0SUB UNIOPSUB LSTOPSUB
64 %token <opval> PLUGEXPR PLUGSTMT
65 %token <opval> LABEL
66 %token <ival> FORMAT SUB SIGSUB ANONSUB ANON_SIGSUB PACKAGE USE
67 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
68 %token <ival> GIVEN WHEN DEFAULT
69 %token <ival> LOOPEX DOTDOT YADAYADA
70 %token <ival> FUNC0 FUNC1 FUNC UNIOP LSTOP
71 %token <ival> MULOP ADDOP
72 %token <ival> DOLSHARP DO HASHBRACK NOAMP
73 %token <ival> LOCAL MY REQUIRE
74 %token <ival> COLONATTR FORMLBRACK FORMRBRACK
75 %token <ival> SUBLEXSTART SUBLEXEND
76
77 %type <ival> grammar remember mremember
78 %type <ival>  startsub startanonsub startformsub
79
80 %type <ival> mintro
81
82 %type <opval> stmtseq fullstmt labfullstmt barestmt block mblock else
83 %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
84 %type <opval> condition
85 %type <opval> sliceme kvslice gelem
86 %type <opval> listexpr nexpr texpr iexpr mexpr mnexpr
87 %type <opval> optlistexpr optexpr optrepl indirob listop method
88 %type <opval> formname subname proto cont my_scalar my_var
89 %type <opval> refgen_topic formblock
90 %type <opval> subattrlist myattrlist myattrterm myterm
91 %type <opval> termbinop termunop anonymous termdo
92 %type <opval> termrelop relopchain termeqop eqopchain
93 %type <ival>  sigslurpsigil
94 %type <opval> sigvarname sigdefault sigscalarelem sigslurpelem
95 %type <opval> sigelem siglist siglistornull subsigguts subsignature optsubsignature
96 %type <opval> subbody optsubbody sigsubbody optsigsubbody
97 %type <opval> formstmtseq formline formarg
98
99 %nonassoc <ival> PREC_LOW
100 %nonassoc LOOPEX
101
102 %left <ival> OROP DOROP
103 %left <ival> ANDOP
104 %right <ival> NOTOP
105 %nonassoc LSTOP LSTOPSUB
106 %left PERLY_COMMA
107 %right <ival> ASSIGNOP
108 %right <ival> PERLY_QUESTION_MARK PERLY_COLON
109 %nonassoc DOTDOT
110 %left <ival> OROR DORDOR
111 %left <ival> ANDAND
112 %left <ival> BITOROP
113 %left <ival> BITANDOP
114 %left <ival> CHEQOP NCEQOP
115 %left <ival> CHRELOP NCRELOP
116 %nonassoc UNIOP UNIOPSUB
117 %nonassoc REQUIRE
118 %left <ival> SHIFTOP
119 %left ADDOP
120 %left MULOP
121 %left <ival> MATCHOP
122 %right <ival> PERLY_EXCLAMATION_MARK PERLY_TILDE UMINUS REFGEN
123 %right <ival> POWOP
124 %nonassoc <ival> PREINC PREDEC POSTINC POSTDEC POSTJOIN
125 %left <ival> ARROW
126 %nonassoc <ival> ')'
127 %left <ival> PERLY_PAREN_OPEN
128 %left PERLY_BRACKET_OPEN PERLY_BRACE_OPEN
129
130 %% /* RULES */
131
132 /* Top-level choice of what kind of thing yyparse was called to parse */
133 grammar :       GRAMPROG
134                         {
135                           parser->expect = XSTATE;
136                           $<ival>$ = 0;
137                         }
138                 remember stmtseq
139                         {
140                           newPROG(block_end($remember,$stmtseq));
141                           PL_compiling.cop_seq = 0;
142                           $$ = 0;
143                         }
144         |       GRAMEXPR
145                         {
146                           parser->expect = XTERM;
147                           $<ival>$ = 0;
148                         }
149                 optexpr
150                         {
151                           PL_eval_root = $optexpr;
152                           $$ = 0;
153                         }
154         |       GRAMBLOCK
155                         {
156                           parser->expect = XBLOCK;
157                           $<ival>$ = 0;
158                         }
159                 block
160                         {
161                           PL_pad_reset_pending = TRUE;
162                           PL_eval_root = $block;
163                           $$ = 0;
164                           yyunlex();
165                           parser->yychar = yytoken = YYEOF;
166                         }
167         |       GRAMBARESTMT
168                         {
169                           parser->expect = XSTATE;
170                           $<ival>$ = 0;
171                         }
172                 barestmt
173                         {
174                           PL_pad_reset_pending = TRUE;
175                           PL_eval_root = $barestmt;
176                           $$ = 0;
177                           yyunlex();
178                           parser->yychar = yytoken = YYEOF;
179                         }
180         |       GRAMFULLSTMT
181                         {
182                           parser->expect = XSTATE;
183                           $<ival>$ = 0;
184                         }
185                 fullstmt
186                         {
187                           PL_pad_reset_pending = TRUE;
188                           PL_eval_root = $fullstmt;
189                           $$ = 0;
190                           yyunlex();
191                           parser->yychar = yytoken = YYEOF;
192                         }
193         |       GRAMSTMTSEQ
194                         {
195                           parser->expect = XSTATE;
196                           $<ival>$ = 0;
197                         }
198                 stmtseq
199                         {
200                           PL_eval_root = $stmtseq;
201                           $$ = 0;
202                         }
203         |       GRAMSUBSIGNATURE
204                         {
205                           parser->expect = XSTATE;
206                           $<ival>$ = 0;
207                         }
208                 subsigguts
209                         {
210                           PL_eval_root = $subsigguts;
211                           $$ = 0;
212                         }
213         ;
214
215 /* An ordinary block */
216 block   :       PERLY_BRACE_OPEN remember stmtseq PERLY_BRACE_CLOSE
217                         { if (parser->copline > (line_t)$PERLY_BRACE_OPEN)
218                               parser->copline = (line_t)$PERLY_BRACE_OPEN;
219                           $$ = block_end($remember, $stmtseq);
220                         }
221         ;
222
223 /* format body */
224 formblock:      PERLY_EQUAL_SIGN remember PERLY_SEMICOLON FORMRBRACK formstmtseq PERLY_SEMICOLON PERLY_DOT
225                         { if (parser->copline > (line_t)$PERLY_EQUAL_SIGN)
226                               parser->copline = (line_t)$PERLY_EQUAL_SIGN;
227                           $$ = block_end($remember, $formstmtseq);
228                         }
229         ;
230
231 remember:       /* NULL */      /* start a full lexical scope */
232                         { $$ = block_start(TRUE);
233                           parser->parsed_sub = 0; }
234         ;
235
236 mblock  :       PERLY_BRACE_OPEN mremember stmtseq PERLY_BRACE_CLOSE
237                         { if (parser->copline > (line_t)$PERLY_BRACE_OPEN)
238                               parser->copline = (line_t)$PERLY_BRACE_OPEN;
239                           $$ = block_end($mremember, $stmtseq);
240                         }
241         ;
242
243 mremember:      /* NULL */      /* start a partial lexical scope */
244                         { $$ = block_start(FALSE);
245                           parser->parsed_sub = 0; }
246         ;
247
248 /* A sequence of statements in the program */
249 stmtseq :       /* NULL */
250                         { $$ = NULL; }
251         |       stmtseq[list] fullstmt
252                         {   $$ = op_append_list(OP_LINESEQ, $list, $fullstmt);
253                             PL_pad_reset_pending = TRUE;
254                             if ($list && $fullstmt)
255                                 PL_hints |= HINT_BLOCK_SCOPE;
256                         }
257         ;
258
259 /* A sequence of format lines */
260 formstmtseq:    /* NULL */
261                         { $$ = NULL; }
262         |       formstmtseq[list] formline
263                         {   $$ = op_append_list(OP_LINESEQ, $list, $formline);
264                             PL_pad_reset_pending = TRUE;
265                             if ($list && $formline)
266                                 PL_hints |= HINT_BLOCK_SCOPE;
267                         }
268         ;
269
270 /* A statement in the program, including optional labels */
271 fullstmt:       barestmt
272                         {
273                           $$ = $barestmt ? newSTATEOP(0, NULL, $barestmt) : NULL;
274                         }
275         |       labfullstmt
276                         { $$ = $labfullstmt; }
277         ;
278
279 labfullstmt:    LABEL barestmt
280                         {
281                           SV *label = cSVOPx_sv($LABEL);
282                           $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8,
283                                             savepv(SvPVX_const(label)), $barestmt);
284                           op_free($LABEL);
285                         }
286         |       LABEL labfullstmt[list]
287                         {
288                           SV *label = cSVOPx_sv($LABEL);
289                           $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8,
290                                             savepv(SvPVX_const(label)), $list);
291                           op_free($LABEL);
292                         }
293         ;
294
295 /* A bare statement, lacking label and other aspects of state op */
296 barestmt:       PLUGSTMT
297                         { $$ = $PLUGSTMT; }
298         |       FORMAT startformsub formname formblock
299                         {
300                           CV *fmtcv = PL_compcv;
301                           newFORM($startformsub, $formname, $formblock);
302                           $$ = NULL;
303                           if (CvOUTSIDE(fmtcv) && !CvEVAL(CvOUTSIDE(fmtcv))) {
304                               pad_add_weakref(fmtcv);
305                           }
306                           parser->parsed_sub = 1;
307                         }
308         |       SUB subname startsub
309                     /* sub declaration or definition not within scope
310                        of 'use feature "signatures"'*/
311                         {
312                           init_named_cv(PL_compcv, $subname);
313                           parser->in_my = 0;
314                           parser->in_my_stash = NULL;
315                         }
316                     proto subattrlist optsubbody
317                         {
318                           SvREFCNT_inc_simple_void(PL_compcv);
319                           $subname->op_type == OP_CONST
320                               ? newATTRSUB($startsub, $subname, $proto, $subattrlist, $optsubbody)
321                               : newMYSUB($startsub, $subname, $proto, $subattrlist, $optsubbody)
322                           ;
323                           $$ = NULL;
324                           intro_my();
325                           parser->parsed_sub = 1;
326                         }
327         |       SIGSUB subname startsub
328                     /* sub declaration or definition under 'use feature
329                      * "signatures"'. (Note that a signature isn't
330                      * allowed in a declaration)
331                      */
332                         {
333                           init_named_cv(PL_compcv, $subname);
334                           parser->in_my = 0;
335                           parser->in_my_stash = NULL;
336                         }
337                     subattrlist optsigsubbody
338                         {
339                           SvREFCNT_inc_simple_void(PL_compcv);
340                           $subname->op_type == OP_CONST
341                               ? newATTRSUB($startsub, $subname, NULL, $subattrlist, $optsigsubbody)
342                               : newMYSUB(  $startsub, $subname, NULL, $subattrlist, $optsigsubbody)
343                           ;
344                           $$ = NULL;
345                           intro_my();
346                           parser->parsed_sub = 1;
347                         }
348         |       PACKAGE BAREWORD[version] BAREWORD[package] PERLY_SEMICOLON
349                         {
350                           package($package);
351                           if ($version)
352                               package_version($version);
353                           $$ = NULL;
354                         }
355         |       USE startsub
356                         { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
357                 BAREWORD[version] BAREWORD[module] optlistexpr PERLY_SEMICOLON
358                         {
359                           SvREFCNT_inc_simple_void(PL_compcv);
360                           utilize($USE, $startsub, $version, $module, $optlistexpr);
361                           parser->parsed_sub = 1;
362                           $$ = NULL;
363                         }
364         |       IF PERLY_PAREN_OPEN remember mexpr ')' mblock else
365                         {
366                           $$ = block_end($remember,
367                               newCONDOP(0, $mexpr, op_scope($mblock), $else));
368                           parser->copline = (line_t)$IF;
369                         }
370         |       UNLESS PERLY_PAREN_OPEN remember mexpr ')' mblock else
371                         {
372                           $$ = block_end($remember,
373                               newCONDOP(0, $mexpr, $else, op_scope($mblock)));
374                           parser->copline = (line_t)$UNLESS;
375                         }
376         |       GIVEN PERLY_PAREN_OPEN remember mexpr ')' mblock
377                         {
378                           $$ = block_end($remember, newGIVENOP($mexpr, op_scope($mblock), 0));
379                           parser->copline = (line_t)$GIVEN;
380                         }
381         |       WHEN PERLY_PAREN_OPEN remember mexpr ')' mblock
382                         { $$ = block_end($remember, newWHENOP($mexpr, op_scope($mblock))); }
383         |       DEFAULT block
384                         { $$ = newWHENOP(0, op_scope($block)); }
385         |       WHILE PERLY_PAREN_OPEN remember texpr ')' mintro mblock cont
386                         {
387                           $$ = block_end($remember,
388                                   newWHILEOP(0, 1, NULL,
389                                       $texpr, $mblock, $cont, $mintro));
390                           parser->copline = (line_t)$WHILE;
391                         }
392         |       UNTIL PERLY_PAREN_OPEN remember iexpr ')' mintro mblock cont
393                         {
394                           $$ = block_end($remember,
395                                   newWHILEOP(0, 1, NULL,
396                                       $iexpr, $mblock, $cont, $mintro));
397                           parser->copline = (line_t)$UNTIL;
398                         }
399         |       FOR PERLY_PAREN_OPEN remember mnexpr[init_mnexpr] PERLY_SEMICOLON
400                         { parser->expect = XTERM; }
401                 texpr PERLY_SEMICOLON
402                         { parser->expect = XTERM; }
403                 mintro mnexpr[iterate_mnexpr] ')'
404                 mblock
405                         {
406                           OP *initop = $init_mnexpr;
407                           OP *forop = newWHILEOP(0, 1, NULL,
408                                       scalar($texpr), $mblock, $iterate_mnexpr, $mintro);
409                           if (initop) {
410                               forop = op_prepend_elem(OP_LINESEQ, initop,
411                                   op_append_elem(OP_LINESEQ,
412                                       newOP(OP_UNSTACK, OPf_SPECIAL),
413                                       forop));
414                           }
415                           PL_hints |= HINT_BLOCK_SCOPE;
416                           $$ = block_end($remember, forop);
417                           parser->copline = (line_t)$FOR;
418                         }
419         |       FOR MY remember my_scalar PERLY_PAREN_OPEN mexpr ')' mblock cont
420                         {
421                           $$ = block_end($remember, newFOROP(0, $my_scalar, $mexpr, $mblock, $cont));
422                           parser->copline = (line_t)$FOR;
423                         }
424         |       FOR scalar PERLY_PAREN_OPEN remember mexpr ')' mblock cont
425                         {
426                           $$ = block_end($remember, newFOROP(0,
427                                       op_lvalue($scalar, OP_ENTERLOOP), $mexpr, $mblock, $cont));
428                           parser->copline = (line_t)$FOR;
429                         }
430         |       FOR my_refgen remember my_var
431                         { parser->in_my = 0; $<opval>$ = my($my_var); }[variable]
432                 PERLY_PAREN_OPEN mexpr ')' mblock cont
433                         {
434                           $$ = block_end(
435                                 $remember,
436                                 newFOROP(0,
437                                          op_lvalue(
438                                             newUNOP(OP_REFGEN, 0,
439                                                     $<opval>variable),
440                                             OP_ENTERLOOP),
441                                          $mexpr, $mblock, $cont)
442                           );
443                           parser->copline = (line_t)$FOR;
444                         }
445         |       FOR REFGEN refgen_topic PERLY_PAREN_OPEN remember mexpr ')' mblock cont
446                         {
447                           $$ = block_end($remember, newFOROP(
448                                 0, op_lvalue(newUNOP(OP_REFGEN, 0,
449                                                      $refgen_topic),
450                                              OP_ENTERLOOP), $mexpr, $mblock, $cont));
451                           parser->copline = (line_t)$FOR;
452                         }
453         |       FOR PERLY_PAREN_OPEN remember mexpr ')' mblock cont
454                         {
455                           $$ = block_end($remember,
456                                   newFOROP(0, NULL, $mexpr, $mblock, $cont));
457                           parser->copline = (line_t)$FOR;
458                         }
459         |       block cont
460                         {
461                           /* a block is a loop that happens once */
462                           $$ = newWHILEOP(0, 1, NULL,
463                                   NULL, $block, $cont, 0);
464                         }
465         |       PACKAGE BAREWORD[version] BAREWORD[package] PERLY_BRACE_OPEN remember
466                         {
467                           package($package);
468                           if ($version) {
469                               package_version($version);
470                           }
471                         }
472                 stmtseq PERLY_BRACE_CLOSE
473                         {
474                           /* a block is a loop that happens once */
475                           $$ = newWHILEOP(0, 1, NULL,
476                                   NULL, block_end($remember, $stmtseq), NULL, 0);
477                           if (parser->copline > (line_t)$PERLY_BRACE_OPEN)
478                               parser->copline = (line_t)$PERLY_BRACE_OPEN;
479                         }
480         |       sideff PERLY_SEMICOLON
481                         {
482                           $$ = $sideff;
483                         }
484         |       YADAYADA PERLY_SEMICOLON
485                         {
486                           $$ = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0),
487                                 newSVOP(OP_CONST, 0, newSVpvs("Unimplemented")));
488                         }
489         |       PERLY_SEMICOLON
490                         {
491                           $$ = NULL;
492                           parser->copline = NOLINE;
493                         }
494         ;
495
496 /* Format line */
497 formline:       THING formarg
498                         { OP *list;
499                           if ($formarg) {
500                               OP *term = $formarg;
501                               list = op_append_elem(OP_LIST, $THING, term);
502                           }
503                           else {
504                               list = $THING;
505                           }
506                           if (parser->copline == NOLINE)
507                                parser->copline = CopLINE(PL_curcop)-1;
508                           else parser->copline--;
509                           $$ = newSTATEOP(0, NULL,
510                                           op_convert_list(OP_FORMLINE, 0, list));
511                         }
512         ;
513
514 formarg :       /* NULL */
515                         { $$ = NULL; }
516         |       FORMLBRACK stmtseq FORMRBRACK
517                         { $$ = op_unscope($stmtseq); }
518         ;
519
520 condition: expr
521 ;
522
523 /* An expression which may have a side-effect */
524 sideff  :       error
525                         { $$ = NULL; }
526         |       expr[body]
527                         { $$ = $body; }
528         |       expr[body] IF condition
529                         { $$ = newLOGOP(OP_AND, 0, $condition, $body); }
530         |       expr[body] UNLESS condition
531                         { $$ = newLOGOP(OP_OR, 0, $condition, $body); }
532         |       expr[body] WHILE condition
533                         { $$ = newLOOPOP(OPf_PARENS, 1, scalar($condition), $body); }
534         |       expr[body] UNTIL iexpr
535                         { $$ = newLOOPOP(OPf_PARENS, 1, $iexpr, $body); }
536         |       expr[body] FOR condition
537                         { $$ = newFOROP(0, NULL, $condition, $body, NULL);
538                           parser->copline = (line_t)$FOR; }
539         |       expr[body] WHEN condition
540                         { $$ = newWHENOP($condition, op_scope($body)); }
541         ;
542
543 /* else and elsif blocks */
544 else    :       /* NULL */
545                         { $$ = NULL; }
546         |       ELSE mblock
547                         {
548                           ($mblock)->op_flags |= OPf_PARENS;
549                           $$ = op_scope($mblock);
550                         }
551         |       ELSIF PERLY_PAREN_OPEN mexpr ')' mblock else[else.recurse]
552                         { parser->copline = (line_t)$ELSIF;
553                             $$ = newCONDOP(0,
554                                 newSTATEOP(OPf_SPECIAL,NULL,$mexpr),
555                                 op_scope($mblock), $[else.recurse]);
556                           PL_hints |= HINT_BLOCK_SCOPE;
557                         }
558         ;
559
560 /* Continue blocks */
561 cont    :       /* NULL */
562                         { $$ = NULL; }
563         |       CONTINUE block
564                         { $$ = op_scope($block); }
565         ;
566
567 /* determine whether there are any new my declarations */
568 mintro  :       /* NULL */
569                         { $$ = (PL_min_intro_pending &&
570                             PL_max_intro_pending >=  PL_min_intro_pending);
571                           intro_my(); }
572
573 /* Normal expression */
574 nexpr   :       /* NULL */
575                         { $$ = NULL; }
576         |       sideff
577         ;
578
579 /* Boolean expression */
580 texpr   :       /* NULL means true */
581                         { YYSTYPE tmplval;
582                           (void)scan_num("1", &tmplval);
583                           $$ = tmplval.opval; }
584         |       expr
585         ;
586
587 /* Inverted boolean expression */
588 iexpr   :       expr
589                         { $$ = invert(scalar($expr)); }
590         ;
591
592 /* Expression with its own lexical scope */
593 mexpr   :       expr
594                         { $$ = $expr; intro_my(); }
595         ;
596
597 mnexpr  :       nexpr
598                         { $$ = $nexpr; intro_my(); }
599         ;
600
601 formname:       BAREWORD        { $$ = $BAREWORD; }
602         |       /* NULL */      { $$ = NULL; }
603         ;
604
605 startsub:       /* NULL */      /* start a regular subroutine scope */
606                         { $$ = start_subparse(FALSE, 0);
607                             SAVEFREESV(PL_compcv); }
608
609         ;
610
611 startanonsub:   /* NULL */      /* start an anonymous subroutine scope */
612                         { $$ = start_subparse(FALSE, CVf_ANON);
613                             SAVEFREESV(PL_compcv); }
614         ;
615
616 startformsub:   /* NULL */      /* start a format subroutine scope */
617                         { $$ = start_subparse(TRUE, 0);
618                             SAVEFREESV(PL_compcv); }
619         ;
620
621 /* Name of a subroutine - must be a bareword, could be special */
622 subname :       BAREWORD
623         |       PRIVATEREF
624         ;
625
626 /* Subroutine prototype */
627 proto   :       /* NULL */
628                         { $$ = NULL; }
629         |       THING
630         ;
631
632 /* Optional list of subroutine attributes */
633 subattrlist:    /* NULL */
634                         { $$ = NULL; }
635         |       COLONATTR THING
636                         { $$ = $THING; }
637         |       COLONATTR
638                         { $$ = NULL; }
639         ;
640
641 /* List of attributes for a "my" variable declaration */
642 myattrlist:     COLONATTR THING
643                         { $$ = $THING; }
644         |       COLONATTR
645                         { $$ = NULL; }
646         ;
647
648
649
650 /* --------------------------------------
651  * subroutine signature parsing
652  */
653
654 /* the '' or 'foo' part of a '$' or '@foo' etc signature variable  */
655 sigvarname:     /* NULL */
656                         { parser->in_my = 0; $$ = NULL; }
657         |       PRIVATEREF
658                         { parser->in_my = 0; $$ = $PRIVATEREF; }
659         ;
660
661 sigslurpsigil:
662                 PERLY_SNAIL
663                         { $$ = '@'; }
664         |       PERLY_PERCENT_SIGN
665                         { $$ = '%'; }
666
667 /* @, %, @foo, %foo */
668 sigslurpelem: sigslurpsigil sigvarname sigdefault/* def only to catch errors */ 
669                         {
670                             I32 sigil   = $sigslurpsigil;
671                             OP *var     = $sigvarname;
672                             OP *defexpr = $sigdefault;
673
674                             if (parser->sig_slurpy)
675                                 yyerror("Multiple slurpy parameters not allowed");
676                             parser->sig_slurpy = (char)sigil;
677
678                             if (defexpr)
679                                 yyerror("A slurpy parameter may not have "
680                                         "a default value");
681
682                             $$ = var ? newSTATEOP(0, NULL, var) : NULL;
683                         }
684         ;
685
686 /* default part of sub signature scalar element: i.e. '= default_expr' */
687 sigdefault:     /* NULL */
688                         { $$ = NULL; }
689         |       ASSIGNOP
690                         { $$ = newOP(OP_NULL, 0); }
691         |       ASSIGNOP term
692                         { $$ = $term; }
693
694
695 /* subroutine signature scalar element: e.g. '$x', '$=', '$x = $default' */
696 sigscalarelem:
697                 '$' sigvarname sigdefault
698                         {
699                             OP *var     = $sigvarname;
700                             OP *defexpr = $sigdefault;
701
702                             if (parser->sig_slurpy)
703                                 yyerror("Slurpy parameter not last");
704
705                             parser->sig_elems++;
706
707                             if (defexpr) {
708                                 parser->sig_optelems++;
709
710                                 if (   defexpr->op_type == OP_NULL
711                                     && !(defexpr->op_flags & OPf_KIDS))
712                                 {
713                                     /* handle '$=' special case */
714                                     if (var)
715                                         yyerror("Optional parameter "
716                                                     "lacks default expression");
717                                     op_free(defexpr);
718                                 }
719                                 else { 
720                                     /* a normal '=default' expression */ 
721                                     OP *defop = (OP*)alloc_LOGOP(OP_ARGDEFELEM,
722                                                         defexpr,
723                                                         LINKLIST(defexpr));
724                                     /* re-purpose op_targ to hold @_ index */
725                                     defop->op_targ =
726                                         (PADOFFSET)(parser->sig_elems - 1);
727
728                                     if (var) {
729                                         var->op_flags |= OPf_STACKED;
730                                         (void)op_sibling_splice(var,
731                                                         NULL, 0, defop);
732                                         scalar(defop);
733                                     }
734                                     else
735                                         var = newUNOP(OP_NULL, 0, defop);
736
737                                     LINKLIST(var);
738                                     /* NB: normally the first child of a
739                                      * logop is executed before the logop,
740                                      * and it pushes a boolean result
741                                      * ready for the logop. For ARGDEFELEM,
742                                      * the op itself does the boolean
743                                      * calculation, so set the first op to
744                                      * it instead.
745                                      */
746                                     var->op_next = defop;
747                                     defexpr->op_next = var;
748                                 }
749                             }
750                             else {
751                                 if (parser->sig_optelems)
752                                     yyerror("Mandatory parameter "
753                                             "follows optional parameter");
754                             }
755
756                             $$ = var ? newSTATEOP(0, NULL, var) : NULL;
757                         }
758         ;
759
760
761 /* subroutine signature element: e.g. '$x = $default' or '%h' */
762 sigelem:        sigscalarelem
763                         { parser->in_my = KEY_sigvar; $$ = $sigscalarelem; }
764         |       sigslurpelem
765                         { parser->in_my = KEY_sigvar; $$ = $sigslurpelem; }
766         ;
767
768 /* list of subroutine signature elements */
769 siglist:
770                 siglist[list] PERLY_COMMA
771                         { $$ = $list; }
772         |       siglist[list] PERLY_COMMA sigelem[element]
773                         {
774                           $$ = op_append_list(OP_LINESEQ, $list, $element);
775                         }
776         |       sigelem[element]  %prec PREC_LOW
777                         { $$ = $element; }
778         ;
779
780 /* () or (....) */
781 siglistornull:          /* NULL */
782                         { $$ = NULL; }
783         |       siglist
784                         { $$ = $siglist; }
785
786 /* optional subroutine signature */
787 optsubsignature:        /* NULL */
788                         { $$ = NULL; }
789         |       subsignature
790                         { $$ = $subsignature; }
791
792 /* Subroutine signature */
793 subsignature:   PERLY_PAREN_OPEN subsigguts ')'
794                         { $$ = $subsigguts; }
795
796 subsigguts:
797                         {
798                             ENTER;
799                             SAVEIV(parser->sig_elems);
800                             SAVEIV(parser->sig_optelems);
801                             SAVEI8(parser->sig_slurpy);
802                             parser->sig_elems    = 0;
803                             parser->sig_optelems = 0;
804                             parser->sig_slurpy   = 0;
805                             parser->in_my        = KEY_sigvar;
806                         }
807                 siglistornull
808                         {
809                             OP            *sigops = $siglistornull;
810                             struct op_argcheck_aux *aux;
811                             OP            *check;
812
813                             if (!FEATURE_SIGNATURES_IS_ENABLED)
814                                 Perl_croak(aTHX_ "Experimental "
815                                     "subroutine signatures not enabled");
816
817                             /* We shouldn't get here otherwise */
818                             Perl_ck_warner_d(aTHX_
819                                 packWARN(WARN_EXPERIMENTAL__SIGNATURES),
820                                 "The signatures feature is experimental");
821
822                             aux = (struct op_argcheck_aux*)
823                                     PerlMemShared_malloc(
824                                         sizeof(struct op_argcheck_aux));
825                             aux->params     = parser->sig_elems;
826                             aux->opt_params = parser->sig_optelems;
827                             aux->slurpy     = parser->sig_slurpy;
828                             check = newUNOP_AUX(OP_ARGCHECK, 0, NULL,
829                                             (UNOP_AUX_item *)aux);
830                             sigops = op_prepend_elem(OP_LINESEQ, check, sigops);
831                             sigops = op_prepend_elem(OP_LINESEQ,
832                                                 newSTATEOP(0, NULL, NULL),
833                                                 sigops);
834                             /* a nextstate at the end handles context
835                              * correctly for an empty sub body */
836                             sigops = op_append_elem(OP_LINESEQ,
837                                                 sigops,
838                                                 newSTATEOP(0, NULL, NULL));
839                             /* wrap the list of arg ops in a NULL aux op.
840                               This serves two purposes. First, it makes
841                               the arg list a separate subtree from the
842                               body of the sub, and secondly the null op
843                               may in future be upgraded to an OP_SIGNATURE
844                               when implemented. For now leave it as
845                               ex-argcheck */
846                             $$ = newUNOP_AUX(OP_ARGCHECK, 0, sigops, NULL);
847                             op_null($$);
848
849                             parser->in_my = 0;
850                             /* tell the toker that attrributes can follow
851                              * this sig, but only so that the toker
852                              * can skip through any (illegal) trailing
853                              * attribute text then give a useful error
854                              * message about "attributes before sig",
855                              * rather than falling over ina mess at
856                              * unrecognised syntax.
857                              */
858                             parser->expect = XATTRBLOCK;
859                             parser->sig_seen = TRUE;
860                             LEAVE;
861                         }
862         ;
863
864 /* Optional subroutine body (for named subroutine declaration) */
865 optsubbody:     subbody { $$ = $subbody; }
866         |       PERLY_SEMICOLON { $$ = NULL; }
867         ;
868
869
870 /* Subroutine body (without signature) */
871 subbody:        remember  PERLY_BRACE_OPEN stmtseq PERLY_BRACE_CLOSE
872                         {
873                           if (parser->copline > (line_t)$PERLY_BRACE_OPEN)
874                               parser->copline = (line_t)$PERLY_BRACE_OPEN;
875                           $$ = block_end($remember, $stmtseq);
876                         }
877         ;
878
879
880 /* optional [ Subroutine body with optional signature ] (for named
881  * subroutine declaration) */
882 optsigsubbody:  sigsubbody { $$ = $sigsubbody; }
883         |       PERLY_SEMICOLON    { $$ = NULL; }
884
885 /* Subroutine body with optional signature */
886 sigsubbody:     remember optsubsignature PERLY_BRACE_OPEN stmtseq PERLY_BRACE_CLOSE
887                         {
888                           if (parser->copline > (line_t)$PERLY_BRACE_OPEN)
889                               parser->copline = (line_t)$PERLY_BRACE_OPEN;
890                           $$ = block_end($remember,
891                                 op_append_list(OP_LINESEQ, $optsubsignature, $stmtseq));
892                         }
893         ;
894
895
896 /* Ordinary expressions; logical combinations */
897 expr    :       expr[lhs] ANDOP expr[rhs]
898                         { $$ = newLOGOP(OP_AND, 0, $lhs, $rhs); }
899         |       expr[lhs] OROP[operator] expr[rhs]
900                         { $$ = newLOGOP($operator, 0, $lhs, $rhs); }
901         |       expr[lhs] DOROP expr[rhs]
902                         { $$ = newLOGOP(OP_DOR, 0, $lhs, $rhs); }
903         |       listexpr %prec PREC_LOW
904         ;
905
906 /* Expressions are a list of terms joined by commas */
907 listexpr:       listexpr[list] PERLY_COMMA
908                         { $$ = $list; }
909         |       listexpr[list] PERLY_COMMA term
910                         {
911                           OP* term = $term;
912                           $$ = op_append_elem(OP_LIST, $list, term);
913                         }
914         |       term %prec PREC_LOW
915         ;
916
917 /* List operators */
918 listop  :       LSTOP indirob listexpr /* map {...} @args or print $fh @args */
919                         { $$ = op_convert_list($LSTOP, OPf_STACKED,
920                                 op_prepend_elem(OP_LIST, newGVREF($LSTOP,$indirob), $listexpr) );
921                         }
922         |       FUNC PERLY_PAREN_OPEN indirob expr ')'      /* print ($fh @args */
923                         { $$ = op_convert_list($FUNC, OPf_STACKED,
924                                 op_prepend_elem(OP_LIST, newGVREF($FUNC,$indirob), $expr) );
925                         }
926         |       term ARROW method PERLY_PAREN_OPEN optexpr ')' /* $foo->bar(list) */
927                         { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED,
928                                 op_append_elem(OP_LIST,
929                                     op_prepend_elem(OP_LIST, scalar($term), $optexpr),
930                                     newMETHOP(OP_METHOD, 0, $method)));
931                         }
932         |       term ARROW method                     /* $foo->bar */
933                         { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED,
934                                 op_append_elem(OP_LIST, scalar($term),
935                                     newMETHOP(OP_METHOD, 0, $method)));
936                         }
937         |       METHOD indirob optlistexpr           /* new Class @args */
938                         { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED,
939                                 op_append_elem(OP_LIST,
940                                     op_prepend_elem(OP_LIST, $indirob, $optlistexpr),
941                                     newMETHOP(OP_METHOD, 0, $METHOD)));
942                         }
943         |       FUNCMETH indirob PERLY_PAREN_OPEN optexpr ')'    /* method $object (@args) */
944                         { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED,
945                                 op_append_elem(OP_LIST,
946                                     op_prepend_elem(OP_LIST, $indirob, $optexpr),
947                                     newMETHOP(OP_METHOD, 0, $FUNCMETH)));
948                         }
949         |       LSTOP optlistexpr                    /* print @args */
950                         { $$ = op_convert_list($LSTOP, 0, $optlistexpr); }
951         |       FUNC PERLY_PAREN_OPEN optexpr ')'                 /* print (@args) */
952                         { $$ = op_convert_list($FUNC, 0, $optexpr); }
953         |       FUNC SUBLEXSTART optexpr SUBLEXEND          /* uc($arg) from "\U..." */
954                         { $$ = op_convert_list($FUNC, 0, $optexpr); }
955         |       LSTOPSUB startanonsub block /* sub f(&@);   f { foo } ... */
956                         { SvREFCNT_inc_simple_void(PL_compcv);
957                           $<opval>$ = newANONATTRSUB($startanonsub, 0, NULL, $block); }[anonattrsub]
958                     optlistexpr         %prec LSTOP  /* ... @bar */
959                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
960                                  op_append_elem(OP_LIST,
961                                    op_prepend_elem(OP_LIST, $<opval>anonattrsub, $optlistexpr), $LSTOPSUB));
962                         }
963         ;
964
965 /* Names of methods. May use $object->$methodname */
966 method  :       METHOD
967         |       scalar
968         ;
969
970 /* Some kind of subscripted expression */
971 subscripted:    gelem PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE        /* *main::{something} */
972                         /* In this and all the hash accessors, PERLY_SEMICOLON is
973                          * provided by the tokeniser */
974                         { $$ = newBINOP(OP_GELEM, 0, $gelem, scalar($expr)); }
975         |       scalar[array] PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE          /* $array[$element] */
976                         { $$ = newBINOP(OP_AELEM, 0, oopsAV($array), scalar($expr));
977                         }
978         |       term[array_reference] ARROW PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE      /* somearef->[$element] */
979                         { $$ = newBINOP(OP_AELEM, 0,
980                                         ref(newAVREF($array_reference),OP_RV2AV),
981                                         scalar($expr));
982                         }
983         |       subscripted[array_reference] PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE    /* $foo->[$bar]->[$baz] */
984                         { $$ = newBINOP(OP_AELEM, 0,
985                                         ref(newAVREF($array_reference),OP_RV2AV),
986                                         scalar($expr));
987                         }
988         |       scalar[hash] PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE    /* $foo{bar();} */
989                         { $$ = newBINOP(OP_HELEM, 0, oopsHV($hash), jmaybe($expr));
990                         }
991         |       term[hash_reference] ARROW PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE /* somehref->{bar();} */
992                         { $$ = newBINOP(OP_HELEM, 0,
993                                         ref(newHVREF($hash_reference),OP_RV2HV),
994                                         jmaybe($expr)); }
995         |       subscripted[hash_reference] PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE /* $foo->[bar]->{baz;} */
996                         { $$ = newBINOP(OP_HELEM, 0,
997                                         ref(newHVREF($hash_reference),OP_RV2HV),
998                                         jmaybe($expr)); }
999         |       term[code_reference] ARROW PERLY_PAREN_OPEN ')'          /* $subref->() */
1000                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1001                                    newCVREF(0, scalar($code_reference)));
1002                           if (parser->expect == XBLOCK)
1003                               parser->expect = XOPERATOR;
1004                         }
1005         |       term[code_reference] ARROW PERLY_PAREN_OPEN expr ')'     /* $subref->(@args) */
1006                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1007                                    op_append_elem(OP_LIST, $expr,
1008                                        newCVREF(0, scalar($code_reference))));
1009                           if (parser->expect == XBLOCK)
1010                               parser->expect = XOPERATOR;
1011                         }
1012
1013         |       subscripted[code_reference] PERLY_PAREN_OPEN expr ')'   /* $foo->{bar}->(@args) */
1014                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1015                                    op_append_elem(OP_LIST, $expr,
1016                                                newCVREF(0, scalar($code_reference))));
1017                           if (parser->expect == XBLOCK)
1018                               parser->expect = XOPERATOR;
1019                         }
1020         |       subscripted[code_reference] PERLY_PAREN_OPEN ')'        /* $foo->{bar}->() */
1021                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1022                                    newCVREF(0, scalar($code_reference)));
1023                           if (parser->expect == XBLOCK)
1024                               parser->expect = XOPERATOR;
1025                         }
1026         |       PERLY_PAREN_OPEN expr[list] ')' PERLY_BRACKET_OPEN expr[slice] PERLY_BRACKET_CLOSE            /* list slice */
1027                         { $$ = newSLICEOP(0, $slice, $list); }
1028         |       QWLIST PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE            /* list literal slice */
1029                         { $$ = newSLICEOP(0, $expr, $QWLIST); }
1030         |       PERLY_PAREN_OPEN ')' PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE                 /* empty list slice! */
1031                         { $$ = newSLICEOP(0, $expr, NULL); }
1032     ;
1033
1034 /* Binary operators between terms */
1035 termbinop:      term[lhs] ASSIGNOP term[rhs]                     /* $x = $y, $x += $y */
1036                         { $$ = newASSIGNOP(OPf_STACKED, $lhs, $ASSIGNOP, $rhs); }
1037         |       term[lhs] POWOP term[rhs]                        /* $x ** $y */
1038                         { $$ = newBINOP($POWOP, 0, scalar($lhs), scalar($rhs)); }
1039         |       term[lhs] MULOP term[rhs]                        /* $x * $y, $x x $y */
1040                         {   if ($MULOP != OP_REPEAT)
1041                                 scalar($lhs);
1042                             $$ = newBINOP($MULOP, 0, $lhs, scalar($rhs));
1043                         }
1044         |       term[lhs] ADDOP term[rhs]                        /* $x + $y */
1045                         { $$ = newBINOP($ADDOP, 0, scalar($lhs), scalar($rhs)); }
1046         |       term[lhs] SHIFTOP term[rhs]                      /* $x >> $y, $x << $y */
1047                         { $$ = newBINOP($SHIFTOP, 0, scalar($lhs), scalar($rhs)); }
1048         |       termrelop %prec PREC_LOW               /* $x > $y, etc. */
1049                         { $$ = $termrelop; }
1050         |       termeqop %prec PREC_LOW                /* $x == $y, $x cmp $y */
1051                         { $$ = $termeqop; }
1052         |       term[lhs] BITANDOP term[rhs]                     /* $x & $y */
1053                         { $$ = newBINOP($BITANDOP, 0, scalar($lhs), scalar($rhs)); }
1054         |       term[lhs] BITOROP term[rhs]                      /* $x | $y */
1055                         { $$ = newBINOP($BITOROP, 0, scalar($lhs), scalar($rhs)); }
1056         |       term[lhs] DOTDOT term[rhs]                       /* $x..$y, $x...$y */
1057                         { $$ = newRANGE($DOTDOT, scalar($lhs), scalar($rhs)); }
1058         |       term[lhs] ANDAND term[rhs]                       /* $x && $y */
1059                         { $$ = newLOGOP(OP_AND, 0, $lhs, $rhs); }
1060         |       term[lhs] OROR term[rhs]                         /* $x || $y */
1061                         { $$ = newLOGOP(OP_OR, 0, $lhs, $rhs); }
1062         |       term[lhs] DORDOR term[rhs]                       /* $x // $y */
1063                         { $$ = newLOGOP(OP_DOR, 0, $lhs, $rhs); }
1064         |       term[lhs] MATCHOP term[rhs]                      /* $x =~ /$y/ */
1065                         { $$ = bind_match($MATCHOP, $lhs, $rhs); }
1066     ;
1067
1068 termrelop:      relopchain %prec PREC_LOW
1069                         { $$ = cmpchain_finish($relopchain); }
1070         |       term[lhs] NCRELOP term[rhs]
1071                         { $$ = newBINOP($NCRELOP, 0, scalar($lhs), scalar($rhs)); }
1072         |       termrelop NCRELOP
1073                         { yyerror("syntax error"); YYERROR; }
1074         |       termrelop CHRELOP
1075                         { yyerror("syntax error"); YYERROR; }
1076         ;
1077
1078 relopchain:     term[lhs] CHRELOP term[rhs]
1079                         { $$ = cmpchain_start($CHRELOP, $lhs, $rhs); }
1080         |       relopchain[lhs] CHRELOP term[rhs]
1081                         { $$ = cmpchain_extend($CHRELOP, $lhs, $rhs); }
1082         ;
1083
1084 termeqop:       eqopchain %prec PREC_LOW
1085                         { $$ = cmpchain_finish($eqopchain); }
1086         |       term[lhs] NCEQOP term[rhs]
1087                         { $$ = newBINOP($NCEQOP, 0, scalar($lhs), scalar($rhs)); }
1088         |       termeqop NCEQOP
1089                         { yyerror("syntax error"); YYERROR; }
1090         |       termeqop CHEQOP
1091                         { yyerror("syntax error"); YYERROR; }
1092         ;
1093
1094 eqopchain:      term[lhs] CHEQOP term[rhs]
1095                         { $$ = cmpchain_start($CHEQOP, $lhs, $rhs); }
1096         |       eqopchain[lhs] CHEQOP term[rhs]
1097                         { $$ = cmpchain_extend($CHEQOP, $lhs, $rhs); }
1098         ;
1099
1100 /* Unary operators and terms */
1101 termunop : PERLY_MINUS term %prec UMINUS                       /* -$x */
1102                         { $$ = newUNOP(OP_NEGATE, 0, scalar($term)); }
1103         |       PERLY_PLUS term %prec UMINUS                  /* +$x */
1104                         { $$ = $term; }
1105
1106         |       PERLY_EXCLAMATION_MARK term                               /* !$x */
1107                         { $$ = newUNOP(OP_NOT, 0, scalar($term)); }
1108         |       PERLY_TILDE term                               /* ~$x */
1109                         { $$ = newUNOP($PERLY_TILDE, 0, scalar($term)); }
1110         |       term POSTINC                           /* $x++ */
1111                         { $$ = newUNOP(OP_POSTINC, 0,
1112                                         op_lvalue(scalar($term), OP_POSTINC)); }
1113         |       term POSTDEC                           /* $x-- */
1114                         { $$ = newUNOP(OP_POSTDEC, 0,
1115                                         op_lvalue(scalar($term), OP_POSTDEC));}
1116         |       term POSTJOIN    /* implicit join after interpolated ->@ */
1117                         { $$ = op_convert_list(OP_JOIN, 0,
1118                                        op_append_elem(
1119                                         OP_LIST,
1120                                         newSVREF(scalar(
1121                                             newSVOP(OP_CONST,0,
1122                                                     newSVpvs("\""))
1123                                         )),
1124                                         $term
1125                                        ));
1126                         }
1127         |       PREINC term                            /* ++$x */
1128                         { $$ = newUNOP(OP_PREINC, 0,
1129                                         op_lvalue(scalar($term), OP_PREINC)); }
1130         |       PREDEC term                            /* --$x */
1131                         { $$ = newUNOP(OP_PREDEC, 0,
1132                                         op_lvalue(scalar($term), OP_PREDEC)); }
1133
1134     ;
1135
1136 /* Constructors for anonymous data */
1137 anonymous:      PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE
1138                         { $$ = newANONLIST($expr); }
1139         |       PERLY_BRACKET_OPEN PERLY_BRACKET_CLOSE
1140                         { $$ = newANONLIST(NULL);}
1141         |       HASHBRACK expr PERLY_SEMICOLON PERLY_BRACE_CLOSE        %prec PERLY_PAREN_OPEN /* { foo => "Bar" } */
1142                         { $$ = newANONHASH($expr); }
1143         |       HASHBRACK PERLY_SEMICOLON PERLY_BRACE_CLOSE     %prec PERLY_PAREN_OPEN /* { } (PERLY_SEMICOLON by tokener) */
1144                         { $$ = newANONHASH(NULL); }
1145         |       ANONSUB     startanonsub proto subattrlist subbody    %prec PERLY_PAREN_OPEN
1146                         { SvREFCNT_inc_simple_void(PL_compcv);
1147                           $$ = newANONATTRSUB($startanonsub, $proto, $subattrlist, $subbody); }
1148         |       ANON_SIGSUB startanonsub subattrlist sigsubbody %prec PERLY_PAREN_OPEN
1149                         { SvREFCNT_inc_simple_void(PL_compcv);
1150                           $$ = newANONATTRSUB($startanonsub, NULL, $subattrlist, $sigsubbody); }
1151     ;
1152
1153 /* Things called with "do" */
1154 termdo  :       DO term %prec UNIOP                     /* do $filename */
1155                         { $$ = dofile($term, $DO);}
1156         |       DO block        %prec PERLY_PAREN_OPEN               /* do { code */
1157                         { $$ = newUNOP(OP_NULL, OPf_SPECIAL, op_scope($block));}
1158         ;
1159
1160 term[product]   :       termbinop
1161         |       termunop
1162         |       anonymous
1163         |       termdo
1164         |       term[condition] PERLY_QUESTION_MARK term[then] PERLY_COLON term[else]
1165                         { $$ = newCONDOP(0, $condition, $then, $else); }
1166         |       REFGEN term[operand]                          /* \$x, \@y, \%z */
1167                         { $$ = newUNOP(OP_REFGEN, 0, $operand); }
1168         |       MY REFGEN term[operand]
1169                         { $$ = newUNOP(OP_REFGEN, 0, localize($operand,1)); }
1170         |       myattrterm      %prec UNIOP
1171                         { $$ = $myattrterm; }
1172         |       LOCAL term[operand]     %prec UNIOP
1173                         { $$ = localize($operand,0); }
1174         |       PERLY_PAREN_OPEN expr ')'
1175                         { $$ = sawparens($expr); }
1176         |       QWLIST
1177                         { $$ = $QWLIST; }
1178         |       PERLY_PAREN_OPEN ')'
1179                         { $$ = sawparens(newNULLLIST()); }
1180         |       scalar  %prec PERLY_PAREN_OPEN
1181                         { $$ = $scalar; }
1182         |       star    %prec PERLY_PAREN_OPEN
1183                         { $$ = $star; }
1184         |       hsh     %prec PERLY_PAREN_OPEN
1185                         { $$ = $hsh; }
1186         |       ary     %prec PERLY_PAREN_OPEN
1187                         { $$ = $ary; }
1188         |       arylen  %prec PERLY_PAREN_OPEN                    /* $#x, $#{ something } */
1189                         { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($arylen, OP_AV2ARYLEN));}
1190         |       subscripted
1191                         { $$ = $subscripted; }
1192         |       sliceme PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE                     /* array slice */
1193                         { $$ = op_prepend_elem(OP_ASLICE,
1194                                 newOP(OP_PUSHMARK, 0),
1195                                     newLISTOP(OP_ASLICE, 0,
1196                                         list($expr),
1197                                         ref($sliceme, OP_ASLICE)));
1198                           if ($$ && $sliceme)
1199                               $$->op_private |=
1200                                   $sliceme->op_private & OPpSLICEWARNING;
1201                         }
1202         |       kvslice PERLY_BRACKET_OPEN expr PERLY_BRACKET_CLOSE                 /* array key/value slice */
1203                         { $$ = op_prepend_elem(OP_KVASLICE,
1204                                 newOP(OP_PUSHMARK, 0),
1205                                     newLISTOP(OP_KVASLICE, 0,
1206                                         list($expr),
1207                                         ref(oopsAV($kvslice), OP_KVASLICE)));
1208                           if ($$ && $kvslice)
1209                               $$->op_private |=
1210                                   $kvslice->op_private & OPpSLICEWARNING;
1211                         }
1212         |       sliceme PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE                 /* @hash{@keys} */
1213                         { $$ = op_prepend_elem(OP_HSLICE,
1214                                 newOP(OP_PUSHMARK, 0),
1215                                     newLISTOP(OP_HSLICE, 0,
1216                                         list($expr),
1217                                         ref(oopsHV($sliceme), OP_HSLICE)));
1218                           if ($$ && $sliceme)
1219                               $$->op_private |=
1220                                   $sliceme->op_private & OPpSLICEWARNING;
1221                         }
1222         |       kvslice PERLY_BRACE_OPEN expr PERLY_SEMICOLON PERLY_BRACE_CLOSE                 /* %hash{@keys} */
1223                         { $$ = op_prepend_elem(OP_KVHSLICE,
1224                                 newOP(OP_PUSHMARK, 0),
1225                                     newLISTOP(OP_KVHSLICE, 0,
1226                                         list($expr),
1227                                         ref($kvslice, OP_KVHSLICE)));
1228                           if ($$ && $kvslice)
1229                               $$->op_private |=
1230                                   $kvslice->op_private & OPpSLICEWARNING;
1231                         }
1232         |       THING   %prec PERLY_PAREN_OPEN
1233                         { $$ = $THING; }
1234         |       amper                                /* &foo; */
1235                         { $$ = newUNOP(OP_ENTERSUB, 0, scalar($amper)); }
1236         |       amper PERLY_PAREN_OPEN ')'                 /* &foo() or foo() */
1237                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($amper));
1238                         }
1239         |       amper PERLY_PAREN_OPEN expr ')'          /* &foo(@args) or foo(@args) */
1240                         {
1241                           $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1242                                 op_append_elem(OP_LIST, $expr, scalar($amper)));
1243                         }
1244         |       NOAMP subname optlistexpr       /* foo @args (no parens) */
1245                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1246                             op_append_elem(OP_LIST, $optlistexpr, scalar($subname)));
1247                         }
1248         |       term[operand] ARROW '$' '*'
1249                         { $$ = newSVREF($operand); }
1250         |       term[operand] ARROW PERLY_SNAIL '*'
1251                         { $$ = newAVREF($operand); }
1252         |       term[operand] ARROW PERLY_PERCENT_SIGN '*'
1253                         { $$ = newHVREF($operand); }
1254         |       term[operand] ARROW PERLY_AMPERSAND '*'
1255                         { $$ = newUNOP(OP_ENTERSUB, 0,
1256                                        scalar(newCVREF($PERLY_AMPERSAND,$operand))); }
1257         |       term[operand] ARROW '*' '*'     %prec PERLY_PAREN_OPEN
1258                         { $$ = newGVREF(0,$operand); }
1259         |       LOOPEX  /* loop exiting command (goto, last, dump, etc) */
1260                         { $$ = newOP($LOOPEX, OPf_SPECIAL);
1261                             PL_hints |= HINT_BLOCK_SCOPE; }
1262         |       LOOPEX term[operand]
1263                         { $$ = newLOOPEX($LOOPEX,$operand); }
1264         |       NOTOP listexpr                       /* not $foo */
1265                         { $$ = newUNOP(OP_NOT, 0, scalar($listexpr)); }
1266         |       UNIOP                                /* Unary op, $_ implied */
1267                         { $$ = newOP($UNIOP, 0); }
1268         |       UNIOP block                          /* eval { foo }* */
1269                         { $$ = newUNOP($UNIOP, 0, $block); }
1270         |       UNIOP term[operand]                           /* Unary op */
1271                         { $$ = newUNOP($UNIOP, 0, $operand); }
1272         |       REQUIRE                              /* require, $_ implied */
1273                         { $$ = newOP(OP_REQUIRE, $REQUIRE ? OPf_SPECIAL : 0); }
1274         |       REQUIRE term[operand]                         /* require Foo */
1275                         { $$ = newUNOP(OP_REQUIRE, $REQUIRE ? OPf_SPECIAL : 0, $operand); }
1276         |       UNIOPSUB
1277                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($UNIOPSUB)); }
1278         |       UNIOPSUB term[operand]                        /* Sub treated as unop */
1279                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
1280                             op_append_elem(OP_LIST, $operand, scalar($UNIOPSUB))); }
1281         |       FUNC0                                /* Nullary operator */
1282                         { $$ = newOP($FUNC0, 0); }
1283         |       FUNC0 PERLY_PAREN_OPEN ')'
1284                         { $$ = newOP($FUNC0, 0);}
1285         |       FUNC0OP       /* Same as above, but op created in toke.c */
1286                         { $$ = $FUNC0OP; }
1287         |       FUNC0OP PERLY_PAREN_OPEN ')'
1288                         { $$ = $FUNC0OP; }
1289         |       FUNC0SUB                             /* Sub treated as nullop */
1290                         { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($FUNC0SUB)); }
1291         |       FUNC1 PERLY_PAREN_OPEN ')'                        /* not () */
1292                         { $$ = ($FUNC1 == OP_NOT)
1293                           ? newUNOP($FUNC1, 0, newSVOP(OP_CONST, 0, newSViv(0)))
1294                           : newOP($FUNC1, OPf_SPECIAL); }
1295         |       FUNC1 PERLY_PAREN_OPEN expr ')'                   /* not($foo) */
1296                         { $$ = newUNOP($FUNC1, 0, $expr); }
1297         |       PMFUNC /* m//, s///, qr//, tr/// */
1298                         {
1299                             if (   $PMFUNC->op_type != OP_TRANS
1300                                 && $PMFUNC->op_type != OP_TRANSR
1301                                 && (((PMOP*)$PMFUNC)->op_pmflags & PMf_HAS_CV))
1302                             {
1303                                 $<ival>$ = start_subparse(FALSE, CVf_ANON);
1304                                 SAVEFREESV(PL_compcv);
1305                             } else
1306                                 $<ival>$ = 0;
1307                         }
1308                     SUBLEXSTART listexpr optrepl SUBLEXEND
1309                         { $$ = pmruntime($PMFUNC, $listexpr, $optrepl, 1, $<ival>2); }
1310         |       BAREWORD
1311         |       listop
1312         |       PLUGEXPR
1313         ;
1314
1315 /* "my" declarations, with optional attributes */
1316 myattrterm:     MY myterm myattrlist
1317                         { $$ = my_attrs($myterm,$myattrlist); }
1318         |       MY myterm
1319                         { $$ = localize($myterm,1); }
1320         |       MY REFGEN myterm myattrlist
1321                         { $$ = newUNOP(OP_REFGEN, 0, my_attrs($myterm,$myattrlist)); }
1322         ;
1323
1324 /* Things that can be "my"'d */
1325 myterm  :       PERLY_PAREN_OPEN expr ')'
1326                         { $$ = sawparens($expr); }
1327         |       PERLY_PAREN_OPEN ')'
1328                         { $$ = sawparens(newNULLLIST()); }
1329
1330         |       scalar  %prec PERLY_PAREN_OPEN
1331                         { $$ = $scalar; }
1332         |       hsh     %prec PERLY_PAREN_OPEN
1333                         { $$ = $hsh; }
1334         |       ary     %prec PERLY_PAREN_OPEN
1335                         { $$ = $ary; }
1336         ;
1337
1338 /* Basic list expressions */
1339 optlistexpr:    /* NULL */ %prec PREC_LOW
1340                         { $$ = NULL; }
1341         |       listexpr    %prec PREC_LOW
1342                         { $$ = $listexpr; }
1343         ;
1344
1345 optexpr:        /* NULL */
1346                         { $$ = NULL; }
1347         |       expr
1348                         { $$ = $expr; }
1349         ;
1350
1351 optrepl:        /* NULL */
1352                         { $$ = NULL; }
1353         |       '/' expr
1354                         { $$ = $expr; }
1355         ;
1356
1357 /* A little bit of trickery to make "for my $foo (@bar)" actually be
1358    lexical */
1359 my_scalar:      scalar
1360                         { parser->in_my = 0; $$ = my($scalar); }
1361         ;
1362
1363 my_var  :       scalar
1364         |       ary
1365         |       hsh
1366         ;
1367
1368 refgen_topic:   my_var
1369         |       amper
1370         ;
1371
1372 my_refgen:      MY REFGEN
1373         |       REFGEN MY
1374         ;
1375
1376 amper   :       PERLY_AMPERSAND indirob
1377                         { $$ = newCVREF($PERLY_AMPERSAND,$indirob); }
1378         ;
1379
1380 scalar  :       '$' indirob
1381                         { $$ = newSVREF($indirob); }
1382         ;
1383
1384 ary     :       PERLY_SNAIL indirob
1385                         { $$ = newAVREF($indirob);
1386                           if ($$) $$->op_private |= $PERLY_SNAIL;
1387                         }
1388         ;
1389
1390 hsh     :       PERLY_PERCENT_SIGN indirob
1391                         { $$ = newHVREF($indirob);
1392                           if ($$) $$->op_private |= $PERLY_PERCENT_SIGN;
1393                         }
1394         ;
1395
1396 arylen  :       DOLSHARP indirob
1397                         { $$ = newAVREF($indirob); }
1398         |       term ARROW DOLSHARP '*'
1399                         { $$ = newAVREF($term); }
1400         ;
1401
1402 star    :       '*' indirob
1403                         { $$ = newGVREF(0,$indirob); }
1404         ;
1405
1406 sliceme :       ary
1407         |       term ARROW PERLY_SNAIL
1408                         { $$ = newAVREF($term); }
1409         ;
1410
1411 kvslice :       hsh
1412         |       term ARROW PERLY_PERCENT_SIGN
1413                         { $$ = newHVREF($term); }
1414         ;
1415
1416 gelem   :       star
1417         |       term ARROW '*'
1418                         { $$ = newGVREF(0,$term); }
1419         ;
1420
1421 /* Indirect objects */
1422 indirob :       BAREWORD
1423                         { $$ = scalar($BAREWORD); }
1424         |       scalar %prec PREC_LOW
1425                         { $$ = scalar($scalar); }
1426         |       block
1427                         { $$ = op_scope($block); }
1428
1429         |       PRIVATEREF
1430                         { $$ = $PRIVATEREF; }
1431         ;