1 /*    perly.y
2  *
3  *    Copyright (c) 1991-2002, Larry Wall
4  *
5  *    You may distribute under the terms of either the GNU General Public
6  *    License or the Artistic License, as specified in the README file.
7  *
8  */
9 
10 /*
11  * 'I see,' laughed Strider.  'I look foul and feel fair.  Is that it?
12  * All that is gold does not glitter, not all those who wander are lost.'
13  */
14 
15 /* This file holds the grammar for the Perl language. If edited, you need
16  * to run regen_perly.pl, which re-creates the files perly.h, perly.tab
17  * and perly.act which are derived from this.
18  *
19  * The main job of of this grammar is to call the various newFOO()
20  * functions in op.c to build a syntax tree of OP structs.
21  * It relies on the lexer in toke.c to do the tokenizing.
22  */
23 
24 %{
25 #include "EXTERN.h"
26 #define PERL_IN_PERLY_C
27 #include "perl.h"
28 #ifdef EBCDIC
29 #undef YYDEBUG
30 #endif
31 #define dep() deprecate("\"do\" to call subroutines")
32 
33 /* stuff included here to make perly_c.diff apply better */
34 
35 #define yydebug	    PL_yydebug
36 #define yynerrs	    PL_yynerrs
37 #define yyerrflag   PL_yyerrflag
38 #define yychar	    PL_yychar
39 #define yyval	    PL_yyval
40 #define yylval	    PL_yylval
41 
42 struct ysv {
43     short* yyss;
44     YYSTYPE* yyvs;
45     int oldyydebug;
46     int oldyynerrs;
47     int oldyyerrflag;
48     int oldyychar;
49     YYSTYPE oldyyval;
50     YYSTYPE oldyylval;
51 };
52 
53 static void yydestruct(pTHX_ void *ptr);
54 
55 %}
56 
57 %start prog
58 
59 %{
60 #if 0 /* get this from perly.h instead */
61 %}
62 
63 %union {
64     I32	ival;
65     char *pval;
66     OP *opval;
67     GV *gvval;
68 }
69 
70 %{
71 #endif /* 0 */
72 
73 #ifdef USE_PURE_BISON
74 #define YYLEX_PARAM (&yychar)
75 #define yylex yylex_r
76 #endif
77 
78 %}
79 
80 %token <ival> '{'
81 
82 %token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF
83 %token <opval> FUNC0SUB UNIOPSUB LSTOPSUB
84 %token <pval> LABEL
85 %token <ival> FORMAT SUB ANONSUB PACKAGE USE
86 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
87 %token <ival> LOOPEX DOTDOT
88 %token <ival> FUNC0 FUNC1 FUNC UNIOP LSTOP
89 %token <ival> RELOP EQOP MULOP ADDOP
90 %token <ival> DOLSHARP DO HASHBRACK NOAMP
91 %token <ival> LOCAL MY MYSUB
92 %token COLONATTR
93 
94 %type <ival> prog decl format startsub startanonsub startformsub
95 %type <ival> progstart remember mremember '&'
96 %type <opval> block mblock lineseq line loop cond else
97 %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
98 %type <opval> argexpr nexpr texpr iexpr mexpr mnexpr mtexpr miexpr
99 %type <opval> listexpr listexprcom indirob listop method
100 %type <opval> formname subname proto subbody cont my_scalar
101 %type <opval> subattrlist myattrlist mysubrout myattrterm myterm
102 %type <opval> termbinop termunop anonymous termdo
103 %type <pval> label
104 
105 %nonassoc PREC_LOW
106 %nonassoc LOOPEX
107 
108 %left <ival> OROP
109 %left ANDOP
110 %right NOTOP
111 %nonassoc LSTOP LSTOPSUB
112 %left ','
113 %right <ival> ASSIGNOP
114 %right '?' ':'
115 %nonassoc DOTDOT
116 %left OROR
117 %left ANDAND
118 %left <ival> BITOROP
119 %left <ival> BITANDOP
120 %nonassoc EQOP
121 %nonassoc RELOP
122 %nonassoc UNIOP UNIOPSUB
123 %left <ival> SHIFTOP
124 %left ADDOP
125 %left MULOP
126 %left <ival> MATCHOP
127 %right '!' '~' UMINUS REFGEN
128 %right <ival> POWOP
129 %nonassoc PREINC PREDEC POSTINC POSTDEC
130 %left ARROW
131 %nonassoc <ival> ')'
132 %left '('
133 %left '[' '{'
134 
135 %% /* RULES */
136 
137 /* The whole program */
138 prog	:	progstart
139 	/*CONTINUED*/	lineseq
140 			{ $$ = $1; newPROG(block_end($1,$2)); }
141 	;
142 
143 /* An ordinary block */
144 block	:	'{' remember lineseq '}'
145 			{ if (PL_copline > (line_t)$1)
146 			      PL_copline = (line_t)$1;
147 			  $$ = block_end($2, $3); }
148 	;
149 
150 remember:	/* NULL */	/* start a full lexical scope */
151 			{ $$ = block_start(TRUE); }
152 	;
153 
154 progstart:
155 		{
156 #if defined(YYDEBUG) && defined(DEBUGGING)
157 		    yydebug = (DEBUG_p_TEST);
158 #endif
159 		    PL_expect = XSTATE; $$ = block_start(TRUE);
160 		}
161 	;
162 
163 
164 mblock	:	'{' mremember lineseq '}'
165 			{ if (PL_copline > (line_t)$1)
166 			      PL_copline = (line_t)$1;
167 			  $$ = block_end($2, $3); }
168 	;
169 
170 mremember:	/* NULL */	/* start a partial lexical scope */
171 			{ $$ = block_start(FALSE); }
172 	;
173 
174 /* A collection of "lines" in the program */
175 lineseq	:	/* NULL */
176 			{ $$ = Nullop; }
177 	|	lineseq decl
178 			{ $$ = $1; }
179 	|	lineseq line
180 			{   $$ = append_list(OP_LINESEQ,
181 				(LISTOP*)$1, (LISTOP*)$2);
182 			    PL_pad_reset_pending = TRUE;
183 			    if ($1 && $2) PL_hints |= HINT_BLOCK_SCOPE; }
184 	;
185 
186 /* A "line" in the program */
187 line	:	label cond
188 			{ $$ = newSTATEOP(0, $1, $2); }
189 	|	loop	/* loops add their own labels */
190 	|	label ';'
191 			{ if ($1 != Nullch) {
192 			      $$ = newSTATEOP(0, $1, newOP(OP_NULL, 0));
193 			    }
194 			    else {
195 			      $$ = Nullop;
196 			      PL_copline = NOLINE;
197 			    }
198 			    PL_expect = XSTATE; }
199 	|	label sideff ';'
200 			{ $$ = newSTATEOP(0, $1, $2);
201 			  PL_expect = XSTATE; }
202 	;
203 
204 /* An expression which may have a side-effect */
205 sideff	:	error
206 			{ $$ = Nullop; }
207 	|	expr
208 			{ $$ = $1; }
209 	|	expr IF expr
210 			{ $$ = newLOGOP(OP_AND, 0, $3, $1); }
211 	|	expr UNLESS expr
212 			{ $$ = newLOGOP(OP_OR, 0, $3, $1); }
213 	|	expr WHILE expr
214 			{ $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); }
215 	|	expr UNTIL iexpr
216 			{ $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);}
217 	|	expr FOR expr
218 			{ $$ = newFOROP(0, Nullch, (line_t)$2,
219 					Nullop, $3, $1, Nullop); }
220 	;
221 
222 /* else and elsif blocks */
223 else	:	/* NULL */
224 			{ $$ = Nullop; }
225 	|	ELSE mblock
226 			{ ($2)->op_flags |= OPf_PARENS; $$ = scope($2); }
227 	|	ELSIF '(' mexpr ')' mblock else
228 			{ PL_copline = (line_t)$1;
229 			    $$ = newCONDOP(0, $3, scope($5), $6);
230 			    PL_hints |= HINT_BLOCK_SCOPE; }
231 	;
232 
233 /* Real conditional expressions */
234 cond	:	IF '(' remember mexpr ')' mblock else
235 			{ PL_copline = (line_t)$1;
236 			    $$ = block_end($3,
237 				   newCONDOP(0, $4, scope($6), $7)); }
238 	|	UNLESS '(' remember miexpr ')' mblock else
239 			{ PL_copline = (line_t)$1;
240 			    $$ = block_end($3,
241 				   newCONDOP(0, $4, scope($6), $7)); }
242 	;
243 
244 /* Continue blocks */
245 cont	:	/* NULL */
246 			{ $$ = Nullop; }
247 	|	CONTINUE block
248 			{ $$ = scope($2); }
249 	;
250 
251 /* Loops: while, until, for, and a bare block */
252 loop	:	label WHILE '(' remember mtexpr ')' mblock cont
253 			{ PL_copline = (line_t)$2;
254 			    $$ = block_end($4,
255 				   newSTATEOP(0, $1,
256 				     newWHILEOP(0, 1, (LOOP*)Nullop,
257 						$2, $5, $7, $8))); }
258 	|	label UNTIL '(' remember miexpr ')' mblock cont
259 			{ PL_copline = (line_t)$2;
260 			    $$ = block_end($4,
261 				   newSTATEOP(0, $1,
262 				     newWHILEOP(0, 1, (LOOP*)Nullop,
263 						$2, $5, $7, $8))); }
264 	|	label FOR MY remember my_scalar '(' mexpr ')' mblock cont
265 			{ $$ = block_end($4,
266 				 newFOROP(0, $1, (line_t)$2, $5, $7, $9, $10)); }
267 	|	label FOR scalar '(' remember mexpr ')' mblock cont
268 			{ $$ = block_end($5,
269 				 newFOROP(0, $1, (line_t)$2, mod($3, OP_ENTERLOOP),
270 					  $6, $8, $9)); }
271 	|	label FOR '(' remember mexpr ')' mblock cont
272 			{ $$ = block_end($4,
273 				 newFOROP(0, $1, (line_t)$2, Nullop, $5, $7, $8)); }
274 	|	label FOR '(' remember mnexpr ';' mtexpr ';' mnexpr ')' mblock
275 			/* basically fake up an initialize-while lineseq */
276 			{ OP *forop;
277 			  PL_copline = (line_t)$2;
278 			  forop = newSTATEOP(0, $1,
279 					    newWHILEOP(0, 1, (LOOP*)Nullop,
280 						$2, scalar($7),
281 						$11, $9));
282 			  if ($5) {
283 				forop = append_elem(OP_LINESEQ,
284                                         newSTATEOP(0, ($1?savepv($1):Nullch),
285 						   $5),
286 					forop);
287 			  }
288 
289 			  $$ = block_end($4, forop); }
290 	|	label block cont  /* a block is a loop that happens once */
291 			{ $$ = newSTATEOP(0, $1,
292 				 newWHILEOP(0, 1, (LOOP*)Nullop,
293 					    NOLINE, Nullop, $2, $3)); }
294 	;
295 
296 /* Normal expression */
297 nexpr	:	/* NULL */
298 			{ $$ = Nullop; }
299 	|	sideff
300 	;
301 
302 /* Boolean expression */
303 texpr	:	/* NULL means true */
304 			{ (void)scan_num("1", &yylval); $$ = yylval.opval; }
305 	|	expr
306 	;
307 
308 /* Inverted boolean expression */
309 iexpr	:	expr
310 			{ $$ = invert(scalar($1)); }
311 	;
312 
313 /* Expression with its own lexical scope */
314 mexpr	:	expr
315 			{ $$ = $1; intro_my(); }
316 	;
317 
318 mnexpr	:	nexpr
319 			{ $$ = $1; intro_my(); }
320 	;
321 
322 mtexpr	:	texpr
323 			{ $$ = $1; intro_my(); }
324 	;
325 
326 miexpr	:	iexpr
327 			{ $$ = $1; intro_my(); }
328 	;
329 
330 /* Optional "MAIN:"-style loop labels */
331 label	:	/* empty */
332 			{ $$ = Nullch; }
333 	|	LABEL
334 	;
335 
336 /* Some kind of declaration - does not take part in the parse tree */
337 decl	:	format
338 			{ $$ = 0; }
339 	|	subrout
340 			{ $$ = 0; }
341 	|	mysubrout
342 			{ $$ = 0; }
343 	|	package
344 			{ $$ = 0; }
345 	|	use
346 			{ $$ = 0; }
347 	;
348 
349 format	:	FORMAT startformsub formname block
350 			{ newFORM($2, $3, $4); }
351 	;
352 
353 formname:	WORD		{ $$ = $1; }
354 	|	/* NULL */	{ $$ = Nullop; }
355 	;
356 
357 /* Unimplemented "my sub foo { }" */
358 mysubrout:	MYSUB startsub subname proto subattrlist subbody
359 			{ newMYSUB($2, $3, $4, $5, $6); }
360 	;
361 
362 /* Subroutine definition */
363 subrout	:	SUB startsub subname proto subattrlist subbody
364 			{ newATTRSUB($2, $3, $4, $5, $6); }
365 	;
366 
367 startsub:	/* NULL */	/* start a regular subroutine scope */
368 			{ $$ = start_subparse(FALSE, 0); }
369 	;
370 
371 startanonsub:	/* NULL */	/* start an anonymous subroutine scope */
372 			{ $$ = start_subparse(FALSE, CVf_ANON); }
373 	;
374 
375 startformsub:	/* NULL */	/* start a format subroutine scope */
376 			{ $$ = start_subparse(TRUE, 0); }
377 	;
378 
379 /* Name of a subroutine - must be a bareword, could be special */
380 subname	:	WORD	{ STRLEN n_a; char *name = SvPV(((SVOP*)$1)->op_sv,n_a);
381 			  if (strEQ(name, "BEGIN") || strEQ(name, "END")
382 			      || strEQ(name, "INIT") || strEQ(name, "CHECK"))
383 			      CvSPECIAL_on(PL_compcv);
384 			  $$ = $1; }
385 	;
386 
387 /* Subroutine prototype */
388 proto	:	/* NULL */
389 			{ $$ = Nullop; }
390 	|	THING
391 	;
392 
393 /* Optional list of subroutine attributes */
394 subattrlist:	/* NULL */
395 			{ $$ = Nullop; }
396 	|	COLONATTR THING
397 			{ $$ = $2; }
398 	|	COLONATTR
399 			{ $$ = Nullop; }
400 	;
401 
402 /* List of attributes for a "my" variable declaration */
403 myattrlist:	COLONATTR THING
404 			{ $$ = $2; }
405 	|	COLONATTR
406 			{ $$ = Nullop; }
407 	;
408 
409 /* Subroutine body - either null or a block */
410 subbody	:	block	{ $$ = $1; }
411 	|	';'	{ $$ = Nullop; PL_expect = XSTATE; }
412 	;
413 
414 package :	PACKAGE WORD ';'
415 			{ package($2); }
416 	|	PACKAGE ';'
417 			{ package(Nullop); }
418 	;
419 
420 use	:	USE startsub
421 			{ CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
422 		    WORD WORD listexpr ';'
423 			{ utilize($1, $2, $4, $5, $6); }
424 	;
425 
426 /* Ordinary expressions; logical combinations */
427 expr	:	expr ANDOP expr
428 			{ $$ = newLOGOP(OP_AND, 0, $1, $3); }
429 	|	expr OROP expr
430 			{ $$ = newLOGOP($2, 0, $1, $3); }
431 	|	argexpr %prec PREC_LOW
432 	;
433 
434 /* Expressions are a list of terms joined by commas */
435 argexpr	:	argexpr ','
436 			{ $$ = $1; }
437 	|	argexpr ',' term
438 			{ $$ = append_elem(OP_LIST, $1, $3); }
439 	|	term %prec PREC_LOW
440 	;
441 
442 /* List operators */
443 listop	:	LSTOP indirob argexpr /* map {...} @args or print $fh @args */
444 			{ $$ = convert($1, OPf_STACKED,
445 				prepend_elem(OP_LIST, newGVREF($1,$2), $3) ); }
446 	|	FUNC '(' indirob expr ')'      /* print ($fh @args */
447 			{ $$ = convert($1, OPf_STACKED,
448 				prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); }
449 	|	term ARROW method '(' listexprcom ')' /* $foo->bar(list) */
450 			{ $$ = convert(OP_ENTERSUB, OPf_STACKED,
451 				append_elem(OP_LIST,
452 				    prepend_elem(OP_LIST, scalar($1), $5),
453 				    newUNOP(OP_METHOD, 0, $3))); }
454 	|	term ARROW method                     /* $foo->bar */
455 			{ $$ = convert(OP_ENTERSUB, OPf_STACKED,
456 				append_elem(OP_LIST, scalar($1),
457 				    newUNOP(OP_METHOD, 0, $3))); }
458 	|	METHOD indirob listexpr              /* new Class @args */
459 			{ $$ = convert(OP_ENTERSUB, OPf_STACKED,
460 				append_elem(OP_LIST,
461 				    prepend_elem(OP_LIST, $2, $3),
462 				    newUNOP(OP_METHOD, 0, $1))); }
463 	|	FUNCMETH indirob '(' listexprcom ')' /* method $object (@args) */
464 			{ $$ = convert(OP_ENTERSUB, OPf_STACKED,
465 				append_elem(OP_LIST,
466 				    prepend_elem(OP_LIST, $2, $4),
467 				    newUNOP(OP_METHOD, 0, $1))); }
468 	|	LSTOP listexpr                       /* print @args */
469 			{ $$ = convert($1, 0, $2); }
470 	|	FUNC '(' listexprcom ')'             /* print (@args) */
471 			{ $$ = convert($1, 0, $3); }
472 	|	LSTOPSUB startanonsub block /* sub f(&@);   f { foo } ... */
473 			{ $3 = newANONATTRSUB($2, 0, Nullop, $3); }
474 		    listexpr		%prec LSTOP  /* ... @bar */
475 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
476 				 append_elem(OP_LIST,
477 				   prepend_elem(OP_LIST, $3, $5), $1)); }
478 	;
479 
480 /* Names of methods. May use $object->$methodname */
481 method	:	METHOD
482 	|	scalar
483 	;
484 
485 /* Some kind of subscripted expression */
486 subscripted:    star '{' expr ';' '}'        /* *main::{something} */
487                         /* In this and all the hash accessors, ';' is
488                          * provided by the tokeniser */
489 			{ $$ = newBINOP(OP_GELEM, 0, $1, scalar($3));
490 			    PL_expect = XOPERATOR; }
491 	|	scalar '[' expr ']'          /* $array[$element] */
492 			{ $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); }
493 	|	term ARROW '[' expr ']'      /* somearef->[$element] */
494 			{ $$ = newBINOP(OP_AELEM, 0,
495 					ref(newAVREF($1),OP_RV2AV),
496 					scalar($4));}
497 	|	subscripted '[' expr ']'    /* $foo->[$bar]->[$baz] */
498 			{ $$ = newBINOP(OP_AELEM, 0,
499 					ref(newAVREF($1),OP_RV2AV),
500 					scalar($3));}
501 	|	scalar '{' expr ';' '}'    /* $foo->{bar();} */
502 			{ $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
503 			    PL_expect = XOPERATOR; }
504 	|	term ARROW '{' expr ';' '}' /* somehref->{bar();} */
505 			{ $$ = newBINOP(OP_HELEM, 0,
506 					ref(newHVREF($1),OP_RV2HV),
507 					jmaybe($4));
508 			    PL_expect = XOPERATOR; }
509 	|	subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */
510 			{ $$ = newBINOP(OP_HELEM, 0,
511 					ref(newHVREF($1),OP_RV2HV),
512 					jmaybe($3));
513 			    PL_expect = XOPERATOR; }
514 	|	term ARROW '(' ')'          /* $subref->() */
515 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
516 				   newCVREF(0, scalar($1))); }
517 	|	term ARROW '(' expr ')'     /* $subref->(@args) */
518 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
519 				   append_elem(OP_LIST, $4,
520 				       newCVREF(0, scalar($1)))); }
521 
522 	|	subscripted '(' expr ')'   /* $foo->{bar}->(@args) */
523 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
524 				   append_elem(OP_LIST, $3,
525 					       newCVREF(0, scalar($1)))); }
526 	|	subscripted '(' ')'        /* $foo->{bar}->() */
527 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
528 				   newCVREF(0, scalar($1))); }
529     ;
530 
531 /* Binary operators between terms */
532 termbinop	:	term ASSIGNOP term             /* $x = $y */
533 			{ $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); }
534 	|	term POWOP term                        /* $x ** $y */
535 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
536 	|	term MULOP term                        /* $x * $y, $x x $y */
537 			{   if ($2 != OP_REPEAT)
538 				scalar($1);
539 			    $$ = newBINOP($2, 0, $1, scalar($3)); }
540 	|	term ADDOP term                        /* $x + $y */
541 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
542 	|	term SHIFTOP term                      /* $x >> $y, $x << $y */
543 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
544 	|	term RELOP term                        /* $x > $y, etc. */
545 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
546 	|	term EQOP term                         /* $x == $y, $x eq $y */
547 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
548 	|	term BITANDOP term                     /* $x & $y */
549 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
550 	|	term BITOROP term                      /* $x | $y */
551 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
552 	|	term DOTDOT term                       /* $x..$y, $x...$y */
553 			{ $$ = newRANGE($2, scalar($1), scalar($3));}
554 	|	term ANDAND term                       /* $x && $y */
555 			{ $$ = newLOGOP(OP_AND, 0, $1, $3); }
556 	|	term OROR term                         /* $x || $y */
557 			{ $$ = newLOGOP(OP_OR, 0, $1, $3); }
558 	|	term MATCHOP term                      /* $x =~ /$y/ */
559 			{ $$ = bind_match($2, $1, $3); }
560     ;
561 
562 /* Unary operators and terms */
563 termunop : '-' term %prec UMINUS                       /* -$x */
564 			{ $$ = newUNOP(OP_NEGATE, 0, scalar($2)); }
565 	|	'+' term %prec UMINUS                  /* +$x */
566 			{ $$ = $2; }
567 	|	'!' term                               /* !$x */
568 			{ $$ = newUNOP(OP_NOT, 0, scalar($2)); }
569 	|	'~' term                               /* ~$x */
570 			{ $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));}
571 	|	term POSTINC                           /* $x++ */
572 			{ $$ = newUNOP(OP_POSTINC, 0,
573 					mod(scalar($1), OP_POSTINC)); }
574 	|	term POSTDEC                           /* $x-- */
575 			{ $$ = newUNOP(OP_POSTDEC, 0,
576 					mod(scalar($1), OP_POSTDEC)); }
577 	|	PREINC term                            /* ++$x */
578 			{ $$ = newUNOP(OP_PREINC, 0,
579 					mod(scalar($2), OP_PREINC)); }
580 	|	PREDEC term                            /* --$x */
581 			{ $$ = newUNOP(OP_PREDEC, 0,
582 					mod(scalar($2), OP_PREDEC)); }
583 
584     ;
585 
586 /* Constructors for anonymous data */
587 anonymous:	'[' expr ']'
588 			{ $$ = newANONLIST($2); }
589 	|	'[' ']'
590 			{ $$ = newANONLIST(Nullop); }
591 	|	HASHBRACK expr ';' '}'	%prec '(' /* { foo => "Bar" } */
592 			{ $$ = newANONHASH($2); }
593 	|	HASHBRACK ';' '}'	%prec '(' /* { } (';' by tokener) */
594 			{ $$ = newANONHASH(Nullop); }
595 	|	ANONSUB startanonsub proto subattrlist block	%prec '('
596 			{ $$ = newANONATTRSUB($2, $3, $4, $5); }
597 
598     ;
599 
600 /* Things called with "do" */
601 termdo	:       DO term	%prec UNIOP                     /* do $filename */
602 			{ $$ = dofile($2); }
603 	|	DO block	%prec '('               /* do { code */
604 			{ $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); }
605 	|	DO WORD '(' ')'                         /* do somesub() */
606 			{ $$ = newUNOP(OP_ENTERSUB,
607 			    OPf_SPECIAL|OPf_STACKED,
608 			    prepend_elem(OP_LIST,
609 				scalar(newCVREF(
610 				    (OPpENTERSUB_AMPER<<8),
611 				    scalar($2)
612 				)),Nullop)); dep();}
613 	|	DO WORD '(' expr ')'                    /* do somesub(@args) */
614 			{ $$ = newUNOP(OP_ENTERSUB,
615 			    OPf_SPECIAL|OPf_STACKED,
616 			    append_elem(OP_LIST,
617 				$4,
618 				scalar(newCVREF(
619 				    (OPpENTERSUB_AMPER<<8),
620 				    scalar($2)
621 				)))); dep();}
622 	|	DO scalar '(' ')'                      /* do $subref () */
623 			{ $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
624 			    prepend_elem(OP_LIST,
625 				scalar(newCVREF(0,scalar($2))), Nullop)); dep();}
626 	|	DO scalar '(' expr ')'                 /* do $subref (@args) */
627 			{ $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
628 			    prepend_elem(OP_LIST,
629 				$4,
630 				scalar(newCVREF(0,scalar($2))))); dep();}
631 
632         ;
633 
634 term	:	termbinop
635 	|	termunop
636 	|	anonymous
637 	|	termdo
638 	|	term '?' term ':' term
639 			{ $$ = newCONDOP(0, $1, $3, $5); }
640 	|	REFGEN term                          /* \$x, \@y, \%z */
641 			{ $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN)); }
642 	|	myattrterm	%prec UNIOP
643 			{ $$ = $1; }
644 	|	LOCAL term	%prec UNIOP
645 			{ $$ = localize($2,$1); }
646 	|	'(' expr ')'
647 			{ $$ = sawparens($2); }
648 	|	'(' ')'
649 			{ $$ = sawparens(newNULLLIST()); }
650 	|	scalar	%prec '('
651 			{ $$ = $1; }
652 	|	star	%prec '('
653 			{ $$ = $1; }
654 	|	hsh 	%prec '('
655 			{ $$ = $1; }
656 	|	ary 	%prec '('
657 			{ $$ = $1; }
658 	|	arylen 	%prec '('                    /* $#x, $#{ something } */
659 			{ $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
660 	|       subscripted
661 			{ $$ = $1; }
662 	|	'(' expr ')' '[' expr ']'            /* list slice */
663 			{ $$ = newSLICEOP(0, $5, $2); }
664 	|	'(' ')' '[' expr ']'                 /* empty list slice! */
665 			{ $$ = newSLICEOP(0, $4, Nullop); }
666 	|	ary '[' expr ']'                     /* array slice */
667 			{ $$ = prepend_elem(OP_ASLICE,
668 				newOP(OP_PUSHMARK, 0),
669 				    newLISTOP(OP_ASLICE, 0,
670 					list($3),
671 					ref($1, OP_ASLICE))); }
672 	|	ary '{' expr ';' '}'                 /* @hash{@keys} */
673 			{ $$ = prepend_elem(OP_HSLICE,
674 				newOP(OP_PUSHMARK, 0),
675 				    newLISTOP(OP_HSLICE, 0,
676 					list($3),
677 					ref(oopsHV($1), OP_HSLICE)));
678 			    PL_expect = XOPERATOR; }
679 	|	THING	%prec '('
680 			{ $$ = $1; }
681 	|	amper                                /* &foo; */
682 			{ $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
683 	|	amper '(' ')'                        /* &foo() */
684 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
685 	|	amper '(' expr ')'                   /* &foo(@args) */
686 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
687 			    append_elem(OP_LIST, $3, scalar($1))); }
688 	|	NOAMP WORD listexpr                  /* foo(@args) */
689 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
690 			    append_elem(OP_LIST, $3, scalar($2))); }
691 	|	LOOPEX  /* loop exiting command (goto, last, dump, etc) */
692 			{ $$ = newOP($1, OPf_SPECIAL);
693 			    PL_hints |= HINT_BLOCK_SCOPE; }
694 	|	LOOPEX term
695 			{ $$ = newLOOPEX($1,$2); }
696 	|	NOTOP argexpr                        /* not $foo */
697 			{ $$ = newUNOP(OP_NOT, 0, scalar($2)); }
698 	|	UNIOP                                /* Unary op, $_ implied */
699 			{ $$ = newOP($1, 0); }
700 	|	UNIOP block                          /* eval { foo }, I *think* */
701 			{ $$ = newUNOP($1, 0, $2); }
702 	|	UNIOP term                           /* Unary op */
703 			{ $$ = newUNOP($1, 0, $2); }
704 	|	UNIOPSUB term                        /* Sub treated as unop */
705 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
706 			    append_elem(OP_LIST, $2, scalar($1))); }
707 	|	FUNC0                                /* Nullary operator */
708 			{ $$ = newOP($1, 0); }
709 	|	FUNC0 '(' ')'
710 			{ $$ = newOP($1, 0); }
711 	|	FUNC0SUB                             /* Sub treated as nullop */
712 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
713 				scalar($1)); }
714 	|	FUNC1 '(' ')'                        /* not () */
715 			{ $$ = $1 == OP_NOT ? newUNOP($1, 0, newSVOP(OP_CONST, 0, newSViv(0)))
716 					    : newOP($1, OPf_SPECIAL); }
717 	|	FUNC1 '(' expr ')'                   /* not($foo) */
718 			{ $$ = newUNOP($1, 0, $3); }
719 	|	PMFUNC '(' term ')'                  /* split (/foo/) */
720 			{ $$ = pmruntime($1, $3, Nullop); }
721 	|	PMFUNC '(' term ',' term ')'         /* split (/foo/,$bar) */
722 			{ $$ = pmruntime($1, $3, $5); }
723 	|	WORD
724 	|	listop
725 	;
726 
727 /* "my" declarations, with optional attributes */
728 myattrterm:	MY myterm myattrlist
729 			{ $$ = my_attrs($2,$3); }
730 	|	MY myterm
731 			{ $$ = localize($2,$1); }
732 	;
733 
734 /* Things that can be "my"'d */
735 myterm	:	'(' expr ')'
736 			{ $$ = sawparens($2); }
737 	|	'(' ')'
738 			{ $$ = sawparens(newNULLLIST()); }
739 	|	scalar	%prec '('
740 			{ $$ = $1; }
741 	|	hsh 	%prec '('
742 			{ $$ = $1; }
743 	|	ary 	%prec '('
744 			{ $$ = $1; }
745 	;
746 
747 /* Basic list expressions */
748 listexpr:	/* NULL */ %prec PREC_LOW
749 			{ $$ = Nullop; }
750 	|	argexpr    %prec PREC_LOW
751 			{ $$ = $1; }
752 	;
753 
754 listexprcom:	/* NULL */
755 			{ $$ = Nullop; }
756 	|	expr
757 			{ $$ = $1; }
758 	|	expr ','
759 			{ $$ = $1; }
760 	;
761 
762 /* A little bit of trickery to make "for my $foo (@bar)" actually be
763    lexical */
764 my_scalar:	scalar
765 			{ PL_in_my = 0; $$ = my($1); }
766 	;
767 
768 amper	:	'&' indirob
769 			{ $$ = newCVREF($1,$2); }
770 	;
771 
772 scalar	:	'$' indirob
773 			{ $$ = newSVREF($2); }
774 	;
775 
776 ary	:	'@' indirob
777 			{ $$ = newAVREF($2); }
778 	;
779 
780 hsh	:	'%' indirob
781 			{ $$ = newHVREF($2); }
782 	;
783 
784 arylen	:	DOLSHARP indirob
785 			{ $$ = newAVREF($2); }
786 	;
787 
788 star	:	'*' indirob
789 			{ $$ = newGVREF(0,$2); }
790 	;
791 
792 /* Indirect objects */
793 indirob	:	WORD
794 			{ $$ = scalar($1); }
795 	|	scalar %prec PREC_LOW
796 			{ $$ = scalar($1);  }
797 	|	block
798 			{ $$ = scope($1); }
799 
800 	|	PRIVATEREF
801 			{ $$ = $1; }
802 	;
803 
804 %% /* PROGRAM */
805 
806 /* more stuff added to make perly_c.diff easier to apply */
807 
808 #ifdef yyparse
809 #undef yyparse
810 #endif
811 #define yyparse() Perl_yyparse(pTHX)
812 
813