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