xref: /openbsd/gnu/usr.bin/perl/perly.y (revision f2dfb0a4)
1 /*    perly.y
2  *
3  *    Copyright (c) 1991-1997, 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 %{
16 #include "EXTERN.h"
17 #include "perl.h"
18 
19 static void
20 dep()
21 {
22     deprecate("\"do\" to call subroutines");
23 }
24 
25 %}
26 
27 %start prog
28 
29 %union {
30     I32	ival;
31     char *pval;
32     OP *opval;
33     GV *gvval;
34 }
35 
36 %token <ival> '{' ')'
37 
38 %token <opval> WORD METHOD FUNCMETH THING PMFUNC PRIVATEREF
39 %token <opval> FUNC0SUB UNIOPSUB LSTOPSUB
40 %token <pval> LABEL
41 %token <ival> FORMAT SUB ANONSUB PACKAGE USE
42 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
43 %token <ival> LOOPEX DOTDOT
44 %token <ival> FUNC0 FUNC1 FUNC UNIOP LSTOP
45 %token <ival> RELOP EQOP MULOP ADDOP
46 %token <ival> DOLSHARP DO HASHBRACK NOAMP
47 %token LOCAL MY
48 
49 %type <ival> prog decl local format startsub startanonsub startformsub
50 %type <ival> remember mremember '&'
51 %type <opval> block mblock lineseq line loop cond else
52 %type <opval> expr term scalar ary hsh arylen star amper sideff
53 %type <opval> argexpr nexpr texpr iexpr mexpr mnexpr mtexpr miexpr
54 %type <opval> listexpr listexprcom indirob listop method
55 %type <opval> formname subname proto subbody cont my_scalar
56 %type <pval> label
57 
58 %left <ival> OROP
59 %left ANDOP
60 %right NOTOP
61 %nonassoc LSTOP LSTOPSUB
62 %left ','
63 %right <ival> ASSIGNOP
64 %right '?' ':'
65 %nonassoc DOTDOT
66 %left OROR
67 %left ANDAND
68 %left <ival> BITOROP
69 %left <ival> BITANDOP
70 %nonassoc EQOP
71 %nonassoc RELOP
72 %nonassoc UNIOP UNIOPSUB
73 %left <ival> SHIFTOP
74 %left ADDOP
75 %left MULOP
76 %left <ival> MATCHOP
77 %right '!' '~' UMINUS REFGEN
78 %right <ival> POWOP
79 %nonassoc PREINC PREDEC POSTINC POSTDEC
80 %left ARROW
81 %left '('
82 
83 %% /* RULES */
84 
85 prog	:	/* NULL */
86 		{
87 #if defined(YYDEBUG) && defined(DEBUGGING)
88 		    yydebug = (debug & 1);
89 #endif
90 		    expect = XSTATE;
91 		}
92 	/*CONTINUED*/	lineseq
93 			{ newPROG($2); }
94 	;
95 
96 block	:	'{' remember lineseq '}'
97 			{ if (copline > (line_t)$1)
98 			      copline = $1;
99 			  $$ = block_end($2, $3); }
100 	;
101 
102 remember:	/* NULL */	/* start a full lexical scope */
103 			{ $$ = block_start(TRUE); }
104 	;
105 
106 mblock	:	'{' mremember lineseq '}'
107 			{ if (copline > (line_t)$1)
108 			      copline = $1;
109 			  $$ = block_end($2, $3); }
110 	;
111 
112 mremember:	/* NULL */	/* start a partial lexical scope */
113 			{ $$ = block_start(FALSE); }
114 	;
115 
116 lineseq	:	/* NULL */
117 			{ $$ = Nullop; }
118 	|	lineseq decl
119 			{ $$ = $1; }
120 	|	lineseq line
121 			{   $$ = append_list(OP_LINESEQ,
122 				(LISTOP*)$1, (LISTOP*)$2);
123 			    pad_reset_pending = TRUE;
124 			    if ($1 && $2) hints |= HINT_BLOCK_SCOPE; }
125 	;
126 
127 line	:	label cond
128 			{ $$ = newSTATEOP(0, $1, $2); }
129 	|	loop	/* loops add their own labels */
130 	|	label ';'
131 			{ if ($1 != Nullch) {
132 			      $$ = newSTATEOP(0, $1, newOP(OP_NULL, 0));
133 			    }
134 			    else {
135 			      $$ = Nullop;
136 			      copline = NOLINE;
137 			    }
138 			    expect = XSTATE; }
139 	|	label sideff ';'
140 			{ $$ = newSTATEOP(0, $1, $2);
141 			  expect = XSTATE; }
142 	;
143 
144 sideff	:	error
145 			{ $$ = Nullop; }
146 	|	expr
147 			{ $$ = $1; }
148 	|	expr IF expr
149 			{ $$ = newLOGOP(OP_AND, 0, $3, $1); }
150 	|	expr UNLESS expr
151 			{ $$ = newLOGOP(OP_OR, 0, $3, $1); }
152 	|	expr WHILE expr
153 			{ $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); }
154 	|	expr UNTIL iexpr
155 			{ $$ = newLOOPOP(OPf_PARENS, 1, $3, $1);}
156 	;
157 
158 else	:	/* NULL */
159 			{ $$ = Nullop; }
160 	|	ELSE mblock
161 			{ $$ = scope($2); }
162 	|	ELSIF '(' mexpr ')' mblock else
163 			{ copline = $1;
164 			    $$ = newSTATEOP(0, Nullch,
165 				   newCONDOP(0, $3, scope($5), $6));
166 			    hints |= HINT_BLOCK_SCOPE; }
167 	;
168 
169 cond	:	IF '(' remember mexpr ')' mblock else
170 			{ copline = $1;
171 			    $$ = block_end($3,
172 				   newCONDOP(0, $4, scope($6), $7)); }
173 	|	UNLESS '(' remember miexpr ')' mblock else
174 			{ copline = $1;
175 			    $$ = block_end($3,
176 				   newCONDOP(0, $4, scope($6), $7)); }
177 	;
178 
179 cont	:	/* NULL */
180 			{ $$ = Nullop; }
181 	|	CONTINUE block
182 			{ $$ = scope($2); }
183 	;
184 
185 loop	:	label WHILE '(' remember mtexpr ')' mblock cont
186 			{ copline = $2;
187 			    $$ = block_end($4,
188 				   newSTATEOP(0, $1,
189 				     newWHILEOP(0, 1, (LOOP*)Nullop,
190 						$2, $5, $7, $8))); }
191 	|	label UNTIL '(' remember miexpr ')' mblock cont
192 			{ copline = $2;
193 			    $$ = block_end($4,
194 				   newSTATEOP(0, $1,
195 				     newWHILEOP(0, 1, (LOOP*)Nullop,
196 						$2, $5, $7, $8))); }
197 	|	label FOR MY remember my_scalar '(' mexpr ')' mblock cont
198 			{ $$ = block_end($4,
199 				 newFOROP(0, $1, $2, $5, $7, $9, $10)); }
200 	|	label FOR scalar '(' remember mexpr ')' mblock cont
201 			{ $$ = block_end($5,
202 				 newFOROP(0, $1, $2, mod($3, OP_ENTERLOOP),
203 					  $6, $8, $9)); }
204 	|	label FOR '(' remember mexpr ')' mblock cont
205 			{ $$ = block_end($4,
206 				 newFOROP(0, $1, $2, Nullop, $5, $7, $8)); }
207 	|	label FOR '(' remember mnexpr ';' mtexpr ';' mnexpr ')' mblock
208 			/* basically fake up an initialize-while lineseq */
209 			{ OP *forop = append_elem(OP_LINESEQ,
210 					scalar($5),
211 					newWHILEOP(0, 1, (LOOP*)Nullop,
212 						   $2, scalar($7),
213 						   $11, scalar($9)));
214 			  copline = $2;
215 			  $$ = block_end($4, newSTATEOP(0, $1, forop)); }
216 	|	label block cont  /* a block is a loop that happens once */
217 			{ $$ = newSTATEOP(0, $1,
218 				 newWHILEOP(0, 1, (LOOP*)Nullop,
219 					    NOLINE, Nullop, $2, $3)); }
220 	;
221 
222 nexpr	:	/* NULL */
223 			{ $$ = Nullop; }
224 	|	sideff
225 	;
226 
227 texpr	:	/* NULL means true */
228 			{ (void)scan_num("1"); $$ = yylval.opval; }
229 	|	expr
230 	;
231 
232 iexpr	:	expr
233 			{ $$ = invert(scalar($1)); }
234 	;
235 
236 mexpr	:	expr
237 			{ $$ = $1; intro_my(); }
238 	;
239 
240 mnexpr	:	nexpr
241 			{ $$ = $1; intro_my(); }
242 	;
243 
244 mtexpr	:	texpr
245 			{ $$ = $1; intro_my(); }
246 	;
247 
248 miexpr	:	iexpr
249 			{ $$ = $1; intro_my(); }
250 	;
251 
252 label	:	/* empty */
253 			{ $$ = Nullch; }
254 	|	LABEL
255 	;
256 
257 decl	:	format
258 			{ $$ = 0; }
259 	|	subrout
260 			{ $$ = 0; }
261 	|	package
262 			{ $$ = 0; }
263 	|	use
264 			{ $$ = 0; }
265 	;
266 
267 format	:	FORMAT startformsub formname block
268 			{ newFORM($2, $3, $4); }
269 	;
270 
271 formname:	WORD		{ $$ = $1; }
272 	|	/* NULL */	{ $$ = Nullop; }
273 	;
274 
275 subrout	:	SUB startsub subname proto subbody
276 			{ newSUB($2, $3, $4, $5); }
277 	;
278 
279 startsub:	/* NULL */	/* start a regular subroutine scope */
280 			{ $$ = start_subparse(FALSE, 0); }
281 	;
282 
283 startanonsub:	/* NULL */	/* start an anonymous subroutine scope */
284 			{ $$ = start_subparse(FALSE, CVf_ANON); }
285 	;
286 
287 startformsub:	/* NULL */	/* start a format subroutine scope */
288 			{ $$ = start_subparse(TRUE, 0); }
289 	;
290 
291 subname	:	WORD	{ char *name = SvPVx(((SVOP*)$1)->op_sv, na);
292 			  if (strEQ(name, "BEGIN") || strEQ(name, "END"))
293 			      CvUNIQUE_on(compcv);
294 			  $$ = $1; }
295 	;
296 
297 proto	:	/* NULL */
298 			{ $$ = Nullop; }
299 	|	THING
300 	;
301 
302 subbody	:	block	{ $$ = $1; }
303 	|	';'	{ $$ = Nullop; expect = XSTATE; }
304 	;
305 
306 package :	PACKAGE WORD ';'
307 			{ package($2); }
308 	|	PACKAGE ';'
309 			{ package(Nullop); }
310 	;
311 
312 use	:	USE startsub
313 			{ CvUNIQUE_on(compcv); /* It's a BEGIN {} */ }
314 		    WORD WORD listexpr ';'
315 			{ utilize($1, $2, $4, $5, $6); }
316 	;
317 
318 expr	:	expr ANDOP expr
319 			{ $$ = newLOGOP(OP_AND, 0, $1, $3); }
320 	|	expr OROP expr
321 			{ $$ = newLOGOP($2, 0, $1, $3); }
322 	|	argexpr
323 	;
324 
325 argexpr	:	argexpr ','
326 			{ $$ = $1; }
327 	|	argexpr ',' term
328 			{ $$ = append_elem(OP_LIST, $1, $3); }
329 	|	term
330 	;
331 
332 listop	:	LSTOP indirob argexpr
333 			{ $$ = convert($1, OPf_STACKED,
334 				prepend_elem(OP_LIST, newGVREF($1,$2), $3) ); }
335 	|	FUNC '(' indirob expr ')'
336 			{ $$ = convert($1, OPf_STACKED,
337 				prepend_elem(OP_LIST, newGVREF($1,$3), $4) ); }
338 	|	term ARROW method '(' listexprcom ')'
339 			{ $$ = convert(OP_ENTERSUB, OPf_STACKED,
340 				append_elem(OP_LIST,
341 				    prepend_elem(OP_LIST, scalar($1), $5),
342 				    newUNOP(OP_METHOD, 0, $3))); }
343 	|	METHOD indirob listexpr
344 			{ $$ = convert(OP_ENTERSUB, OPf_STACKED,
345 				append_elem(OP_LIST,
346 				    prepend_elem(OP_LIST, $2, $3),
347 				    newUNOP(OP_METHOD, 0, $1))); }
348 	|	FUNCMETH indirob '(' listexprcom ')'
349 			{ $$ = convert(OP_ENTERSUB, OPf_STACKED,
350 				append_elem(OP_LIST,
351 				    prepend_elem(OP_LIST, $2, $4),
352 				    newUNOP(OP_METHOD, 0, $1))); }
353 	|	LSTOP listexpr
354 			{ $$ = convert($1, 0, $2); }
355 	|	FUNC '(' listexprcom ')'
356 			{ $$ = convert($1, 0, $3); }
357 	|	LSTOPSUB startanonsub block
358 			{ $3 = newANONSUB($2, 0, $3); }
359 		    listexpr		%prec LSTOP
360 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
361 				 append_elem(OP_LIST,
362 				   prepend_elem(OP_LIST, $3, $5), $1)); }
363 	;
364 
365 method	:	METHOD
366 	|	scalar
367 	;
368 
369 term	:	term ASSIGNOP term
370 			{ $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); }
371 	|	term POWOP term
372 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
373 	|	term MULOP term
374 			{   if ($2 != OP_REPEAT)
375 				scalar($1);
376 			    $$ = newBINOP($2, 0, $1, scalar($3)); }
377 	|	term ADDOP term
378 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
379 	|	term SHIFTOP term
380 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
381 	|	term RELOP term
382 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
383 	|	term EQOP term
384 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
385 	|	term BITANDOP term
386 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
387 	|	term BITOROP term
388 			{ $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
389 	|	term DOTDOT term
390 			{ $$ = newRANGE($2, scalar($1), scalar($3));}
391 	|	term ANDAND term
392 			{ $$ = newLOGOP(OP_AND, 0, $1, $3); }
393 	|	term OROR term
394 			{ $$ = newLOGOP(OP_OR, 0, $1, $3); }
395 	|	term '?' term ':' term
396 			{ $$ = newCONDOP(0, $1, $3, $5); }
397 	|	term MATCHOP term
398 			{ $$ = bind_match($2, $1, $3); }
399 
400 	|	'-' term %prec UMINUS
401 			{ $$ = newUNOP(OP_NEGATE, 0, scalar($2)); }
402 	|	'+' term %prec UMINUS
403 			{ $$ = $2; }
404 	|	'!' term
405 			{ $$ = newUNOP(OP_NOT, 0, scalar($2)); }
406 	|	'~' term
407 			{ $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));}
408 	|	REFGEN term
409 			{ $$ = newUNOP(OP_REFGEN, 0, mod($2,OP_REFGEN)); }
410 	|	term POSTINC
411 			{ $$ = newUNOP(OP_POSTINC, 0,
412 					mod(scalar($1), OP_POSTINC)); }
413 	|	term POSTDEC
414 			{ $$ = newUNOP(OP_POSTDEC, 0,
415 					mod(scalar($1), OP_POSTDEC)); }
416 	|	PREINC term
417 			{ $$ = newUNOP(OP_PREINC, 0,
418 					mod(scalar($2), OP_PREINC)); }
419 	|	PREDEC term
420 			{ $$ = newUNOP(OP_PREDEC, 0,
421 					mod(scalar($2), OP_PREDEC)); }
422 	|	local term	%prec UNIOP
423 			{ $$ = localize($2,$1); }
424 	|	'(' expr ')'
425 			{ $$ = sawparens($2); }
426 	|	'(' ')'
427 			{ $$ = sawparens(newNULLLIST()); }
428 	|	'[' expr ']'				%prec '('
429 			{ $$ = newANONLIST($2); }
430 	|	'[' ']'					%prec '('
431 			{ $$ = newANONLIST(Nullop); }
432 	|	HASHBRACK expr ';' '}'			%prec '('
433 			{ $$ = newANONHASH($2); }
434 	|	HASHBRACK ';' '}'				%prec '('
435 			{ $$ = newANONHASH(Nullop); }
436 	|	ANONSUB startanonsub proto block		%prec '('
437 			{ $$ = newANONSUB($2, $3, $4); }
438 	|	scalar	%prec '('
439 			{ $$ = $1; }
440 	|	star '{' expr ';' '}'
441 			{ $$ = newBINOP(OP_GELEM, 0, newGVREF(0,$1), $3); }
442 	|	star	%prec '('
443 			{ $$ = $1; }
444 	|	scalar '[' expr ']'	%prec '('
445 			{ $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); }
446 	|	term ARROW '[' expr ']'	%prec '('
447 			{ $$ = newBINOP(OP_AELEM, 0,
448 					ref(newAVREF($1),OP_RV2AV),
449 					scalar($4));}
450 	|	term '[' expr ']'	%prec '('
451 			{ assertref($1); $$ = newBINOP(OP_AELEM, 0,
452 					ref(newAVREF($1),OP_RV2AV),
453 					scalar($3));}
454 	|	hsh 	%prec '('
455 			{ $$ = $1; }
456 	|	ary 	%prec '('
457 			{ $$ = $1; }
458 	|	arylen 	%prec '('
459 			{ $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
460 	|	scalar '{' expr ';' '}'	%prec '('
461 			{ $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
462 			    expect = XOPERATOR; }
463 	|	term ARROW '{' expr ';' '}'	%prec '('
464 			{ $$ = newBINOP(OP_HELEM, 0,
465 					ref(newHVREF($1),OP_RV2HV),
466 					jmaybe($4));
467 			    expect = XOPERATOR; }
468 	|	term '{' expr ';' '}'	%prec '('
469 			{ assertref($1); $$ = newBINOP(OP_HELEM, 0,
470 					ref(newHVREF($1),OP_RV2HV),
471 					jmaybe($3));
472 			    expect = XOPERATOR; }
473 	|	'(' expr ')' '[' expr ']'	%prec '('
474 			{ $$ = newSLICEOP(0, $5, $2); }
475 	|	'(' ')' '[' expr ']'	%prec '('
476 			{ $$ = newSLICEOP(0, $4, Nullop); }
477 	|	ary '[' expr ']'	%prec '('
478 			{ $$ = prepend_elem(OP_ASLICE,
479 				newOP(OP_PUSHMARK, 0),
480 				    newLISTOP(OP_ASLICE, 0,
481 					list($3),
482 					ref($1, OP_ASLICE))); }
483 	|	ary '{' expr ';' '}'	%prec '('
484 			{ $$ = prepend_elem(OP_HSLICE,
485 				newOP(OP_PUSHMARK, 0),
486 				    newLISTOP(OP_HSLICE, 0,
487 					list($3),
488 					ref(oopsHV($1), OP_HSLICE)));
489 			    expect = XOPERATOR; }
490 	|	THING	%prec '('
491 			{ $$ = $1; }
492 	|	amper
493 			{ $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
494 	|	amper '(' ')'
495 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
496 	|	amper '(' expr ')'
497 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
498 			    append_elem(OP_LIST, $3, scalar($1))); }
499 	|	NOAMP WORD listexpr
500 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
501 			    append_elem(OP_LIST, $3, scalar($2))); }
502 	|	DO term	%prec UNIOP
503 			{ $$ = newUNOP(OP_DOFILE, 0, scalar($2)); }
504 	|	DO block	%prec '('
505 			{ $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); }
506 	|	DO WORD '(' ')'
507 			{ $$ = newUNOP(OP_ENTERSUB,
508 			    OPf_SPECIAL|OPf_STACKED,
509 			    prepend_elem(OP_LIST,
510 				scalar(newCVREF(
511 				    (OPpENTERSUB_AMPER<<8),
512 				    scalar($2)
513 				)),Nullop)); dep();}
514 	|	DO WORD '(' expr ')'
515 			{ $$ = newUNOP(OP_ENTERSUB,
516 			    OPf_SPECIAL|OPf_STACKED,
517 			    append_elem(OP_LIST,
518 				$4,
519 				scalar(newCVREF(
520 				    (OPpENTERSUB_AMPER<<8),
521 				    scalar($2)
522 				)))); dep();}
523 	|	DO scalar '(' ')'
524 			{ $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
525 			    prepend_elem(OP_LIST,
526 				scalar(newCVREF(0,scalar($2))), Nullop)); dep();}
527 	|	DO scalar '(' expr ')'
528 			{ $$ = newUNOP(OP_ENTERSUB, OPf_SPECIAL|OPf_STACKED,
529 			    prepend_elem(OP_LIST,
530 				$4,
531 				scalar(newCVREF(0,scalar($2))))); dep();}
532 	|	term ARROW '(' ')'	%prec '('
533 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
534 				   newCVREF(0, scalar($1))); }
535 	|	term ARROW '(' expr ')'	%prec '('
536 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
537 				   append_elem(OP_LIST, $4,
538 				       newCVREF(0, scalar($1)))); }
539 	|	LOOPEX
540 			{ $$ = newOP($1, OPf_SPECIAL);
541 			    hints |= HINT_BLOCK_SCOPE; }
542 	|	LOOPEX term
543 			{ $$ = newLOOPEX($1,$2); }
544 	|	NOTOP argexpr
545 			{ $$ = newUNOP(OP_NOT, 0, scalar($2)); }
546 	|	UNIOP
547 			{ $$ = newOP($1, 0); }
548 	|	UNIOP block
549 			{ $$ = newUNOP($1, 0, $2); }
550 	|	UNIOP term
551 			{ $$ = newUNOP($1, 0, $2); }
552 	|	UNIOPSUB term
553 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
554 			    append_elem(OP_LIST, $2, scalar($1))); }
555 	|	FUNC0
556 			{ $$ = newOP($1, 0); }
557 	|	FUNC0 '(' ')'
558 			{ $$ = newOP($1, 0); }
559 	|	FUNC0SUB
560 			{ $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
561 				scalar($1)); }
562 	|	FUNC1 '(' ')'
563 			{ $$ = newOP($1, OPf_SPECIAL); }
564 	|	FUNC1 '(' expr ')'
565 			{ $$ = newUNOP($1, 0, $3); }
566 	|	PMFUNC '(' term ')'
567 			{ $$ = pmruntime($1, $3, Nullop); }
568 	|	PMFUNC '(' term ',' term ')'
569 			{ $$ = pmruntime($1, $3, $5); }
570 	|	WORD
571 	|	listop
572 	;
573 
574 listexpr:	/* NULL */
575 			{ $$ = Nullop; }
576 	|	argexpr
577 			{ $$ = $1; }
578 	;
579 
580 listexprcom:	/* NULL */
581 			{ $$ = Nullop; }
582 	|	expr
583 			{ $$ = $1; }
584 	|	expr ','
585 			{ $$ = $1; }
586 	;
587 
588 local	:	LOCAL	{ $$ = 0; }
589 	|	MY	{ $$ = 1; }
590 	;
591 
592 my_scalar:	scalar
593 			{ in_my = 0; $$ = my($1); }
594 	;
595 
596 amper	:	'&' indirob
597 			{ $$ = newCVREF($1,$2); }
598 	;
599 
600 scalar	:	'$' indirob
601 			{ $$ = newSVREF($2); }
602 	;
603 
604 ary	:	'@' indirob
605 			{ $$ = newAVREF($2); }
606 	;
607 
608 hsh	:	'%' indirob
609 			{ $$ = newHVREF($2); }
610 	;
611 
612 arylen	:	DOLSHARP indirob
613 			{ $$ = newAVREF($2); }
614 	;
615 
616 star	:	'*' indirob
617 			{ $$ = newGVREF(0,$2); }
618 	;
619 
620 indirob	:	WORD
621 			{ $$ = scalar($1); }
622 	|	scalar
623 			{ $$ = scalar($1);  }
624 	|	block
625 			{ $$ = scope($1); }
626 
627 	|	PRIVATEREF
628 			{ $$ = $1; }
629 	;
630 
631 %% /* PROGRAM */
632