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