ac73fc08180e1f1c7d260f95baec4c979d5c3c20
[p5sagit/p5-mst-13.2.git] / perly.y
1 /* $RCSfile: perly.y,v $$Revision: 4.1 $$Date: 92/08/07 18:26:16 $
2  *
3  *    Copyright (c) 1991, 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  * $Log:        perly.y,v $
9  * Revision 4.1  92/08/07  18:26:16  lwall
10  * 
11  * Revision 4.0.1.5  92/06/11  21:12:50  lwall
12  * patch34: expectterm incorrectly set to indicate start of program or block
13  * 
14  * Revision 4.0.1.4  92/06/08  17:33:25  lwall
15  * patch20: one of the backdoors to expectterm was on the wrong reduction
16  * 
17  * Revision 4.0.1.3  92/06/08  15:18:16  lwall
18  * patch20: an expression may now start with a bareword
19  * patch20: relaxed requirement for semicolon at the end of a block
20  * patch20: added ... as variant on ..
21  * patch20: fixed double debug break in foreach with implicit array assignment
22  * patch20: if {block} {block} didn't work any more
23  * patch20: deleted some minor memory leaks
24  * 
25  * Revision 4.0.1.2  91/11/05  18:17:38  lwall
26  * patch11: extra comma at end of list is now allowed in more places (Hi, Felix!)
27  * patch11: once-thru blocks didn't display right in the debugger
28  * patch11: debugger got confused over nested subroutine definitions
29  * 
30  * Revision 4.0.1.1  91/06/07  11:42:34  lwall
31  * patch4: new copyright notice
32  * 
33  * Revision 4.0  91/03/20  01:38:40  lwall
34  * 4.0 baseline.
35  * 
36  */
37
38 %{
39 #include "EXTERN.h"
40 #include "perl.h"
41
42 /*SUPPRESS 530*/
43 /*SUPPRESS 593*/
44 /*SUPPRESS 595*/
45
46 %}
47
48 %start prog
49
50 %union {
51     I32 ival;
52     char *pval;
53     OP *opval;
54     GV *gvval;
55 }
56
57 %token <ival> '{' ')'
58
59 %token <opval> WORD METHOD THING PMFUNC PRIVATEREF
60 %token <pval> LABEL
61 %token <ival> FORMAT SUB PACKAGE
62 %token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE FOR
63 %token <ival> LOOPEX DOTDOT
64 %token <ival> FUNC0 FUNC1 FUNC
65 %token <ival> RELOP EQOP MULOP ADDOP
66 %token <ival> DOLSHARP DO LOCAL DELETE HASHBRACK NOAMP
67
68 %type <ival> prog decl format remember crp crb crhb
69 %type <opval> block lineseq line loop cond nexpr else
70 %type <opval> expr sexpr term scalar ary hsh arylen star amper sideff
71 %type <opval> listexpr indirob
72 %type <opval> texpr listop
73 %type <pval> label
74 %type <opval> cont
75
76 %left OROP
77 %left ANDOP
78 %nonassoc <ival> LSTOP
79 %left ','
80 %right '='
81 %right '?' ':'
82 %nonassoc DOTDOT
83 %left OROR
84 %left ANDAND
85 %left <ival> BITOROP
86 %left <ival> BITANDOP
87 %nonassoc EQOP
88 %nonassoc RELOP
89 %nonassoc <ival> UNIOP
90 %left <ival> SHIFTOP
91 %left ADDOP
92 %left MULOP
93 %left <ival> MATCHOP
94 %right '!' '~' UMINUS REFGEN
95 %right <ival> POWOP
96 %nonassoc PREINC PREDEC POSTINC POSTDEC
97 %left ARROW
98 %left '('
99
100 %% /* RULES */
101
102 prog    :       /* NULL */
103                 {
104 #if defined(YYDEBUG) && defined(DEBUGGING)
105                     yydebug = (debug & 1);
106 #endif
107                     expect = XSTATE;
108                 }
109         /*CONTINUED*/   lineseq
110                         {   if (in_eval) {
111                                 eval_root = newUNOP(OP_LEAVEEVAL, 0, $2);
112                                 eval_start = linklist(eval_root);
113                                 eval_root->op_next = 0;
114                                 peep(eval_start);
115                             }
116                             else
117                                 main_root = block_head($2, &main_start);
118                         }
119         ;
120
121 block   :       '{' remember lineseq '}'
122                         {   int nbs = needblockscope;
123                             $$ = scalarseq($3);
124                             if (copline > (line_t)$1)
125                                 copline = $1;
126                             LEAVE_SCOPE($2);
127                             if (nbs)
128                                 needblockscope = TRUE;  /* propagate outward */
129                             pad_leavemy(comppad_name_fill); }
130         ;
131
132 remember:       /* NULL */      /* in case they push a package name */
133                         { $$ = savestack_ix;
134                             comppad_name_fill = AvFILL(comppad_name);
135                             SAVEINT(min_intro_pending);
136                             SAVEINT(max_intro_pending);
137                             min_intro_pending = 0;
138                             SAVEINT(comppad_name_fill);
139                             SAVEINT(needblockscope);
140                             needblockscope = FALSE; }
141         ;
142
143 lineseq :       /* NULL */
144                         { $$ = Nullop; }
145         |       lineseq decl
146                         { $$ = $1; }
147         |       lineseq line
148                         {   $$ = append_list(OP_LINESEQ,
149                                 (LISTOP*)$1, (LISTOP*)$2); pad_reset();
150                             if ($1 && $2) needblockscope = TRUE; }
151         ;
152
153 line    :       label cond
154                         { $$ = newSTATEOP(0, $1, $2); }
155         |       loop    /* loops add their own labels */
156         |       label ';'
157                         { if ($1 != Nullch) {
158                               $$ = newSTATEOP(0, $1, newOP(OP_NULL, 0));
159                             }
160                             else {
161                               $$ = Nullop;
162                               copline = NOLINE;
163                             }
164                             expect = XSTATE; }
165         |       label sideff ';'
166                         { $$ = newSTATEOP(0, $1, $2);
167                           expect = XSTATE; }
168         ;
169
170 sideff  :       error
171                         { $$ = Nullop; }
172         |       expr
173                         { $$ = $1; }
174         |       expr IF expr
175                         { $$ = newLOGOP(OP_AND, 0, $3, $1); }
176         |       expr UNLESS expr
177                         { $$ = newLOGOP(OP_OR, 0, $3, $1); }
178         |       expr WHILE expr
179                         { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); }
180         |       expr UNTIL expr
181                         { $$ = newLOOPOP(OPf_PARENS, 1, invert(scalar($3)), $1);}
182         ;
183
184 else    :       /* NULL */
185                         { $$ = Nullop; }
186         |       ELSE block
187                         { $$ = scope($2); }
188         |       ELSIF '(' expr ')' block else
189                         { copline = $1;
190                             $$ = newCONDOP(0, $3, scope($5), $6); }
191         ;
192
193 cond    :       IF '(' expr ')' block else
194                         { copline = $1;
195                             $$ = newCONDOP(0, $3, scope($5), $6); }
196         |       UNLESS '(' expr ')' block else
197                         { copline = $1;
198                             $$ = newCONDOP(0,
199                                 invert(scalar($3)), scope($5), $6); }
200         |       IF block block else
201                         { copline = $1;
202                             $$ = newCONDOP(0, scope($2), scope($3), $4); }
203         |       UNLESS block block else
204                         { copline = $1;
205                             $$ = newCONDOP(0, invert(scalar(scope($2))),
206                                                 scope($3), $4); }
207         ;
208
209 cont    :       /* NULL */
210                         { $$ = Nullop; }
211         |       CONTINUE block
212                         { $$ = scope($2); }
213         ;
214
215 loop    :       label WHILE '(' texpr ')' block cont
216                         { copline = $2;
217                             $$ = newSTATEOP(0, $1,
218                                     newWHILEOP(0, 1, (LOOP*)Nullop,
219                                         $4, $6, $7) ); }
220         |       label UNTIL '(' expr ')' block cont
221                         { copline = $2;
222                             $$ = newSTATEOP(0, $1,
223                                     newWHILEOP(0, 1, (LOOP*)Nullop,
224                                         invert(scalar($4)), $6, $7) ); }
225         |       label WHILE block block cont
226                         { copline = $2;
227                             $$ = newSTATEOP(0, $1,
228                                     newWHILEOP(0, 1, (LOOP*)Nullop,
229                                         scope($3), $4, $5) ); }
230         |       label UNTIL block block cont
231                         { copline = $2;
232                             $$ = newSTATEOP(0, $1,
233                                     newWHILEOP(0, 1, (LOOP*)Nullop,
234                                         invert(scalar(scope($3))), $4, $5)); }
235         |       label FOR scalar '(' expr crp block cont
236                         { $$ = newFOROP(0, $1, $2, mod($3, OP_ENTERLOOP),
237                                 $5, $7, $8); }
238         |       label FOR '(' expr crp block cont
239                         { $$ = newFOROP(0, $1, $2, Nullop, $4, $6, $7); }
240         |       label FOR '(' nexpr ';' texpr ';' nexpr ')' block
241                         /* basically fake up an initialize-while lineseq */
242                         {  copline = $2;
243                             $$ = append_elem(OP_LINESEQ,
244                                     newSTATEOP(0, $1, scalar($4)),
245                                     newSTATEOP(0, $1,
246                                         newWHILEOP(0, 1, (LOOP*)Nullop,
247                                             scalar($6), $10, scalar($8)) )); }
248         |       label block cont  /* a block is a loop that happens once */
249                         { $$ = newSTATEOP(0,
250                                 $1, newWHILEOP(0, 1, (LOOP*)Nullop,
251                                         Nullop, $2, $3)); }
252         ;
253
254 nexpr   :       /* NULL */
255                         { $$ = Nullop; }
256         |       sideff
257         ;
258
259 texpr   :       /* NULL means true */
260                         { (void)scan_num("1"); $$ = yylval.opval; }
261         |       expr
262         ;
263
264 label   :       /* empty */
265                         { $$ = Nullch; }
266         |       LABEL
267         ;
268
269 decl    :       format
270                         { $$ = 0; }
271         |       subrout
272                         { $$ = 0; }
273         |       package
274                         { $$ = 0; }
275         ;
276
277 format  :       FORMAT WORD block
278                         { newFORM($1, $2, $3); }
279         |       FORMAT block
280                         { newFORM($1, Nullop, $2); }
281         ;
282
283 subrout :       SUB WORD block
284                         { newSUB($1, $2, $3); }
285         |       SUB WORD ';'
286                         { newSUB($1, $2, Nullop); expect = XSTATE; }
287         ;
288
289 package :       PACKAGE WORD ';'
290                         { package($2); }
291         |       PACKAGE ';'
292                         { package(Nullop); }
293         ;
294
295 expr    :       expr ',' sexpr
296                         { $$ = append_elem(OP_LIST, $1, $3); }
297         |       sexpr
298         ;
299
300 listop  :       LSTOP indirob listexpr
301                         { $$ = convert($1, OPf_STACKED,
302                                 prepend_elem(OP_LIST, newGVREF($2), $3) ); }
303         |       FUNC '(' indirob listexpr ')'
304                         { $$ = convert($1, OPf_STACKED,
305                                 prepend_elem(OP_LIST, newGVREF($3), $4) ); }
306         |       indirob ARROW LSTOP listexpr
307                         { $$ = convert($3, OPf_STACKED,
308                                 prepend_elem(OP_LIST, newGVREF($1), $4) ); }
309         |       indirob ARROW FUNC '(' listexpr ')'
310                         { $$ = convert($3, OPf_STACKED,
311                                 prepend_elem(OP_LIST, newGVREF($1), $5) ); }
312         |       term ARROW METHOD '(' listexpr ')'
313                         { $$ = convert(OP_ENTERSUBR, OPf_STACKED|OPf_SPECIAL,
314                                 prepend_elem(OP_LIST,
315                                     newMETHOD($1,$3), list($5))); }
316         |       METHOD indirob listexpr
317                         { $$ = convert(OP_ENTERSUBR, OPf_STACKED|OPf_SPECIAL,
318                                 prepend_elem(OP_LIST,
319                                     newMETHOD($2,$1), list($3))); }
320         |       LSTOP listexpr
321                         { $$ = convert($1, 0, $2); }
322         |       FUNC '(' listexpr ')'
323                         { $$ = convert($1, 0, $3); }
324         ;
325
326 sexpr   :       sexpr '=' sexpr
327                         { $$ = newASSIGNOP(OPf_STACKED, $1, $3); }
328         |       sexpr POWOP '=' sexpr
329                         { $$ = newBINOP($2, OPf_STACKED,
330                                 mod(scalar($1), $2), scalar($4)); }
331         |       sexpr MULOP '=' sexpr
332                         { $$ = newBINOP($2, OPf_STACKED,
333                                 mod(scalar($1), $2), scalar($4)); }
334         |       sexpr ADDOP '=' sexpr
335                         { $$ = newBINOP($2, OPf_STACKED,
336                                 mod(scalar($1), $2), scalar($4));}
337         |       sexpr SHIFTOP '=' sexpr
338                         { $$ = newBINOP($2, OPf_STACKED,
339                                 mod(scalar($1), $2), scalar($4)); }
340         |       sexpr BITANDOP '=' sexpr
341                         { $$ = newBINOP($2, OPf_STACKED,
342                                 mod(scalar($1), $2), scalar($4)); }
343         |       sexpr BITOROP '=' sexpr
344                         { $$ = newBINOP($2, OPf_STACKED,
345                                 mod(scalar($1), $2), scalar($4)); }
346         |       sexpr ANDAND '=' sexpr
347                         { $$ = newLOGOP(OP_ANDASSIGN, 0,
348                                 mod(scalar($1), OP_ANDASSIGN),
349                                 newUNOP(OP_SASSIGN, 0, scalar($4))); }
350         |       sexpr OROR '=' sexpr
351                         { $$ = newLOGOP(OP_ORASSIGN, 0,
352                                 mod(scalar($1), OP_ORASSIGN),
353                                 newUNOP(OP_SASSIGN, 0, scalar($4))); }
354
355
356         |       sexpr POWOP sexpr
357                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
358         |       sexpr MULOP sexpr
359                         {   if ($2 != OP_REPEAT)
360                                 scalar($1);
361                             $$ = newBINOP($2, 0, $1, scalar($3)); }
362         |       sexpr ADDOP sexpr
363                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
364         |       sexpr SHIFTOP sexpr
365                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
366         |       sexpr RELOP sexpr
367                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
368         |       sexpr EQOP sexpr
369                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
370         |       sexpr BITANDOP sexpr
371                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
372         |       sexpr BITOROP sexpr
373                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
374         |       sexpr DOTDOT sexpr
375                         { $$ = newRANGE($2, scalar($1), scalar($3));}
376         |       sexpr ANDAND sexpr
377                         { $$ = newLOGOP(OP_AND, 0, $1, $3); }
378         |       sexpr OROR sexpr
379                         { $$ = newLOGOP(OP_OR, 0, $1, $3); }
380         |       sexpr ANDOP sexpr
381                         { $$ = newLOGOP(OP_AND, 0, $1, $3); }
382         |       sexpr OROP sexpr
383                         { $$ = newLOGOP(OP_OR, 0, $1, $3); }
384         |       sexpr '?' sexpr ':' sexpr
385                         { $$ = newCONDOP(0, $1, $3, $5); }
386         |       sexpr MATCHOP sexpr
387                         { $$ = bind_match($2, $1, $3); }
388         |       term
389                         { $$ = $1; }
390         ;
391
392 term    :       '-' term %prec UMINUS
393                         { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); }
394         |       '+' term %prec UMINUS
395                         { $$ = $2; }
396         |       '!' term
397                         { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
398         |       '~' term
399                         { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));}
400         |       REFGEN term
401                         { $$ = newUNOP(OP_REFGEN, 0, ref($2,OP_REFGEN)); }
402         |       term POSTINC
403                         { $$ = newUNOP(OP_POSTINC, 0,
404                                         mod(scalar($1), OP_POSTINC)); }
405         |       term POSTDEC
406                         { $$ = newUNOP(OP_POSTDEC, 0,
407                                         mod(scalar($1), OP_POSTDEC)); }
408         |       PREINC term
409                         { $$ = newUNOP(OP_PREINC, 0,
410                                         mod(scalar($2), OP_PREINC)); }
411         |       PREDEC term
412                         { $$ = newUNOP(OP_PREDEC, 0,
413                                         mod(scalar($2), OP_PREDEC)); }
414         |       LOCAL sexpr     %prec UNIOP
415                         { $$ = localize($2,$1); }
416         |       '(' expr crp
417                         { $$ = sawparens($2); }
418         |       '(' ')'
419                         { $$ = sawparens(newNULLLIST()); }
420         |       '[' expr crb                            %prec '('
421                         { $$ = newANONLIST($2); }
422         |       '[' ']'                                 %prec '('
423                         { $$ = newANONLIST(Nullop); }
424         |       HASHBRACK expr crhb                     %prec '('
425                         { $$ = newANONHASH($2); }
426         |       HASHBRACK ';' '}'                               %prec '('
427                         { $$ = newANONHASH(Nullop); }
428         |       scalar  %prec '('
429                         { $$ = $1; }
430         |       star    %prec '('
431                         { $$ = $1; }
432         |       scalar '[' expr ']'     %prec '('
433                         { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); }
434         |       term ARROW '[' expr ']' %prec '('
435                         { $$ = newBINOP(OP_AELEM, 0,
436                                         ref(newAVREF($1),OP_RV2AV),
437                                         scalar($4));}
438         |       term '[' expr ']'       %prec '('
439                         { $$ = newBINOP(OP_AELEM, 0,
440                                         ref(newAVREF($1),OP_RV2AV),
441                                         scalar($3));}
442         |       hsh     %prec '('
443                         { $$ = $1; }
444         |       ary     %prec '('
445                         { $$ = $1; }
446         |       arylen  %prec '('
447                         { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
448         |       scalar '{' expr ';' '}' %prec '('
449                         { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
450                             expect = XOPERATOR; }
451         |       term ARROW '{' expr ';' '}'     %prec '('
452                         { $$ = newBINOP(OP_HELEM, 0,
453                                         ref(newHVREF($1),OP_RV2HV),
454                                         jmaybe($4));
455                             expect = XOPERATOR; }
456         |       term '{' expr ';' '}'   %prec '('
457                         { $$ = newBINOP(OP_HELEM, 0,
458                                         ref(newHVREF($1),OP_RV2HV),
459                                         jmaybe($3));
460                             expect = XOPERATOR; }
461         |       '(' expr crp '[' expr ']'       %prec '('
462                         { $$ = newSLICEOP(0, $5, $2); }
463         |       '(' ')' '[' expr ']'    %prec '('
464                         { $$ = newSLICEOP(0, $4, Nullop); }
465         |       ary '[' expr ']'        %prec '('
466                         { $$ = prepend_elem(OP_ASLICE,
467                                 newOP(OP_PUSHMARK, 0),
468                                 list(
469                                     newLISTOP(OP_ASLICE, 0,
470                                         list($3),
471                                         ref($1, OP_ASLICE)))); }
472         |       ary '{' expr ';' '}'    %prec '('
473                         { $$ = prepend_elem(OP_HSLICE,
474                                 newOP(OP_PUSHMARK, 0),
475                                 list(
476                                     newLISTOP(OP_HSLICE, 0,
477                                         list($3),
478                                         ref(oopsHV($1), OP_HSLICE))));
479                             expect = XOPERATOR; }
480         |       DELETE scalar '{' expr ';' '}'  %prec '('
481                         { $$ = newBINOP(OP_DELETE, 0, oopsHV($2), jmaybe($4));
482                             expect = XOPERATOR; }
483         |       DELETE '(' scalar '{' expr ';' '}' ')'  %prec '('
484                         { $$ = newBINOP(OP_DELETE, 0, oopsHV($3), jmaybe($5));
485                             expect = XOPERATOR; }
486         |       THING   %prec '('
487                         { $$ = $1; }
488         |       amper
489                         { $$ = newUNOP(OP_ENTERSUBR, 0,
490                                 scalar($1)); }
491         |       amper '(' ')'
492                         { $$ = newUNOP(OP_ENTERSUBR, OPf_STACKED, scalar($1)); }
493         |       amper '(' expr crp
494                         { $$ = newUNOP(OP_ENTERSUBR, OPf_STACKED,
495                             list(prepend_elem(OP_LIST, scalar($1), $3))); }
496         |       NOAMP WORD listexpr
497                         { $$ = newUNOP(OP_ENTERSUBR, OPf_STACKED,
498                             list(prepend_elem(OP_LIST,
499                                 newCVREF(scalar($2)), $3))); }
500         |       NOAMP WORD indirob listexpr
501                         { $$ = convert(OP_ENTERSUBR, OPf_STACKED|OPf_SPECIAL,
502                                 prepend_elem(OP_LIST,
503                                     newMETHOD($3,$2), list($4))); }
504         |       DO sexpr        %prec UNIOP
505                         { $$ = newUNOP(OP_DOFILE, 0, scalar($2)); }
506         |       DO block        %prec '('
507                         { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); }
508         |       DO WORD '(' ')'
509                         { $$ = newUNOP(OP_ENTERSUBR, OPf_SPECIAL|OPf_STACKED,
510                             list(prepend_elem(OP_LIST,
511                                 scalar(newCVREF(scalar($2))), Nullop))); }
512         |       DO WORD '(' expr crp
513                         { $$ = newUNOP(OP_ENTERSUBR, OPf_SPECIAL|OPf_STACKED,
514                             list(prepend_elem(OP_LIST,
515                                 scalar(newCVREF(scalar($2))),
516                                 $4))); }
517         |       DO scalar '(' ')'
518                         { $$ = newUNOP(OP_ENTERSUBR, OPf_SPECIAL|OPf_STACKED,
519                             list(prepend_elem(OP_LIST,
520                                 scalar(newCVREF(scalar($2))), Nullop)));}
521         |       DO scalar '(' expr crp
522                         { $$ = newUNOP(OP_ENTERSUBR, OPf_SPECIAL|OPf_STACKED,
523                             list(prepend_elem(OP_LIST,
524                                 scalar(newCVREF(scalar($2))),
525                                 $4))); }
526         |       LOOPEX
527                         { $$ = newOP($1, OPf_SPECIAL); needblockscope = TRUE; }
528         |       LOOPEX sexpr
529                         { $$ = newLOOPEX($1,$2); }
530         |       UNIOP
531                         { $$ = newOP($1, 0); }
532         |       UNIOP block
533                         { $$ = newUNOP($1, 0, $2); }
534         |       UNIOP sexpr
535                         { $$ = newUNOP($1, 0, $2); }
536         |       FUNC0
537                         { $$ = newOP($1, 0); }
538         |       FUNC0 '(' ')'
539                         { $$ = newOP($1, 0); }
540         |       FUNC1 '(' ')'
541                         { $$ = newOP($1, OPf_SPECIAL); }
542         |       FUNC1 '(' expr ')'
543                         { $$ = newUNOP($1, 0, $3); }
544         |       PMFUNC '(' sexpr ')'
545                         { $$ = pmruntime($1, $3, Nullop); }
546         |       PMFUNC '(' sexpr ',' sexpr ')'
547                         { $$ = pmruntime($1, $3, $5); }
548         |       WORD
549         |       listop
550         ;
551
552 listexpr:       /* NULL */
553                         { $$ = Nullop; }
554         |       expr
555                         { $$ = $1; }
556         ;
557
558 amper   :       '&' indirob
559                         { $$ = newCVREF($2); }
560         ;
561
562 scalar  :       '$' indirob
563                         { $$ = newSVREF($2); }
564         ;
565
566 ary     :       '@' indirob
567                         { $$ = newAVREF($2); }
568         ;
569
570 hsh     :       '%' indirob
571                         { $$ = newHVREF($2); }
572         ;
573
574 arylen  :       DOLSHARP indirob
575                         { $$ = newAVREF($2); }
576         ;
577
578 star    :       '*' indirob
579                         { $$ = newGVREF($2); }
580         ;
581
582 indirob :       WORD
583                         { $$ = scalar($1); }
584         |       scalar
585                         { $$ = scalar($1);  }
586         |       block
587                         { $$ = scalar(scope($1)); }
588
589         |       PRIVATEREF
590                         { $$ = $1; }
591         ;
592
593 crp     :       ',' ')'
594                         { $$ = 1; }
595         |       ')'
596                         { $$ = 0; }
597         ;
598
599 crb     :       ',' ']'
600                         { $$ = 1; }
601         |       ']'
602                         { $$ = 0; }
603         ;
604
605 crhb    :       ',' ';' '}'
606                         { $$ = 1; }
607         |       ';' '}'
608                         { $$ = 0; }
609         ;
610
611 %% /* PROGRAM */