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