perl 5.0 alpha 9
[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 HINT
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 needblockscope = hints & HINT_BLOCK_SCOPE;
123                             $$ = scalarseq($3);
124                             if (copline > (line_t)$1)
125                                 copline = $1;
126                             LEAVE_SCOPE($2);
127                             if (needblockscope)
128                                 hints |= HINT_BLOCK_SCOPE; /* propagate out */
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(hints);
140                             hints &= ~HINT_BLOCK_SCOPE; }
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) hints |= HINT_BLOCK_SCOPE; }
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                             $$ = newSTATEOP(0, 0,
191                                 newCONDOP(0, $3, scope($5), $6)); }
192         ;
193
194 cond    :       IF '(' expr ')' block else
195                         { copline = $1;
196                             $$ = newCONDOP(0, $3, scope($5), $6); }
197         |       UNLESS '(' expr ')' block else
198                         { copline = $1;
199                             $$ = newCONDOP(0,
200                                 invert(scalar($3)), scope($5), $6); }
201         |       IF block block else
202                         { copline = $1;
203                             $$ = newCONDOP(0, scope($2), scope($3), $4); }
204         |       UNLESS block block else
205                         { copline = $1;
206                             $$ = newCONDOP(0, invert(scalar(scope($2))),
207                                                 scope($3), $4); }
208         ;
209
210 cont    :       /* NULL */
211                         { $$ = Nullop; }
212         |       CONTINUE block
213                         { $$ = scope($2); }
214         ;
215
216 loop    :       label WHILE '(' texpr ')' block cont
217                         { copline = $2;
218                             $$ = newSTATEOP(0, $1,
219                                     newWHILEOP(0, 1, (LOOP*)Nullop,
220                                         $4, $6, $7) ); }
221         |       label UNTIL '(' expr ')' block cont
222                         { copline = $2;
223                             $$ = newSTATEOP(0, $1,
224                                     newWHILEOP(0, 1, (LOOP*)Nullop,
225                                         invert(scalar($4)), $6, $7) ); }
226         |       label WHILE block block cont
227                         { copline = $2;
228                             $$ = newSTATEOP(0, $1,
229                                     newWHILEOP(0, 1, (LOOP*)Nullop,
230                                         scope($3), $4, $5) ); }
231         |       label UNTIL block block cont
232                         { copline = $2;
233                             $$ = newSTATEOP(0, $1,
234                                     newWHILEOP(0, 1, (LOOP*)Nullop,
235                                         invert(scalar(scope($3))), $4, $5)); }
236         |       label FOR scalar '(' expr crp block cont
237                         { $$ = newFOROP(0, $1, $2, mod($3, OP_ENTERLOOP),
238                                 $5, $7, $8); }
239         |       label FOR '(' expr crp block cont
240                         { $$ = newFOROP(0, $1, $2, Nullop, $4, $6, $7); }
241         |       label FOR '(' nexpr ';' texpr ';' nexpr ')' block
242                         /* basically fake up an initialize-while lineseq */
243                         {  copline = $2;
244                             $$ = append_elem(OP_LINESEQ,
245                                     newSTATEOP(0, $1, scalar($4)),
246                                     newSTATEOP(0, $1,
247                                         newWHILEOP(0, 1, (LOOP*)Nullop,
248                                             scalar($6), $10, scalar($8)) )); }
249         |       label block cont  /* a block is a loop that happens once */
250                         { $$ = newSTATEOP(0,
251                                 $1, newWHILEOP(0, 1, (LOOP*)Nullop,
252                                         Nullop, $2, $3)); }
253         ;
254
255 nexpr   :       /* NULL */
256                         { $$ = Nullop; }
257         |       sideff
258         ;
259
260 texpr   :       /* NULL means true */
261                         { (void)scan_num("1"); $$ = yylval.opval; }
262         |       expr
263         ;
264
265 label   :       /* empty */
266                         { $$ = Nullch; }
267         |       LABEL
268         ;
269
270 decl    :       format
271                         { $$ = 0; }
272         |       subrout
273                         { $$ = 0; }
274         |       package
275                         { $$ = 0; }
276         |       hint
277                         { $$ = 0; }
278         ;
279
280 format  :       FORMAT WORD block
281                         { newFORM($1, $2, $3); }
282         |       FORMAT block
283                         { newFORM($1, Nullop, $2); }
284         ;
285
286 subrout :       SUB WORD block
287                         { newSUB($1, $2, $3); }
288         |       SUB WORD ';'
289                         { newSUB($1, $2, Nullop); expect = XSTATE; }
290         ;
291
292 package :       PACKAGE WORD ';'
293                         { package($2); }
294         |       PACKAGE ';'
295                         { package(Nullop); }
296         ;
297
298 hint    :       HINT WORD ';'
299                         { hint($1, $2, Nullop); }
300         |       HINT WORD expr ';'
301                         { hint($1, $2, list(force_list($3))); }
302         ;
303
304 expr    :       expr ',' sexpr
305                         { $$ = append_elem(OP_LIST, $1, $3); }
306         |       sexpr
307         ;
308
309 listop  :       LSTOP indirob listexpr
310                         { $$ = convert($1, OPf_STACKED,
311                                 prepend_elem(OP_LIST, newGVREF($2), $3) ); }
312         |       FUNC '(' indirob listexpr ')'
313                         { $$ = convert($1, OPf_STACKED,
314                                 prepend_elem(OP_LIST, newGVREF($3), $4) ); }
315         |       indirob ARROW LSTOP listexpr
316                         { $$ = convert($3, OPf_STACKED,
317                                 prepend_elem(OP_LIST, newGVREF($1), $4) ); }
318         |       indirob ARROW FUNC '(' listexpr ')'
319                         { $$ = convert($3, OPf_STACKED,
320                                 prepend_elem(OP_LIST, newGVREF($1), $5) ); }
321         |       term ARROW METHOD '(' listexpr ')'
322                         { $$ = convert(OP_ENTERSUBR, OPf_STACKED|OPf_SPECIAL,
323                                 prepend_elem(OP_LIST,
324                                     newMETHOD($1,$3), list($5))); }
325         |       METHOD indirob listexpr
326                         { $$ = convert(OP_ENTERSUBR, OPf_STACKED|OPf_SPECIAL,
327                                 prepend_elem(OP_LIST,
328                                     newMETHOD($2,$1), list($3))); }
329         |       LSTOP listexpr
330                         { $$ = convert($1, 0, $2); }
331         |       FUNC '(' listexpr ')'
332                         { $$ = convert($1, 0, $3); }
333         ;
334
335 sexpr   :       sexpr '=' sexpr
336                         { $$ = newASSIGNOP(OPf_STACKED, $1, $3); }
337         |       sexpr POWOP '=' sexpr
338                         { $$ = newBINOP($2, OPf_STACKED,
339                                 mod(scalar($1), $2), scalar($4)); }
340         |       sexpr MULOP '=' sexpr
341                         { $$ = newBINOP($2, OPf_STACKED,
342                                 mod(scalar($1), $2), scalar($4)); }
343         |       sexpr ADDOP '=' sexpr
344                         { $$ = newBINOP($2, OPf_STACKED,
345                                 mod(scalar($1), $2), scalar($4));}
346         |       sexpr SHIFTOP '=' sexpr
347                         { $$ = newBINOP($2, OPf_STACKED,
348                                 mod(scalar($1), $2), scalar($4)); }
349         |       sexpr BITANDOP '=' sexpr
350                         { $$ = newBINOP($2, OPf_STACKED,
351                                 mod(scalar($1), $2), scalar($4)); }
352         |       sexpr BITOROP '=' sexpr
353                         { $$ = newBINOP($2, OPf_STACKED,
354                                 mod(scalar($1), $2), scalar($4)); }
355         |       sexpr ANDAND '=' sexpr
356                         { $$ = newLOGOP(OP_ANDASSIGN, 0,
357                                 mod(scalar($1), OP_ANDASSIGN),
358                                 newUNOP(OP_SASSIGN, 0, scalar($4))); }
359         |       sexpr OROR '=' sexpr
360                         { $$ = newLOGOP(OP_ORASSIGN, 0,
361                                 mod(scalar($1), OP_ORASSIGN),
362                                 newUNOP(OP_SASSIGN, 0, scalar($4))); }
363
364
365         |       sexpr POWOP sexpr
366                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
367         |       sexpr MULOP sexpr
368                         {   if ($2 != OP_REPEAT)
369                                 scalar($1);
370                             $$ = newBINOP($2, 0, $1, scalar($3)); }
371         |       sexpr ADDOP sexpr
372                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
373         |       sexpr SHIFTOP sexpr
374                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
375         |       sexpr RELOP sexpr
376                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
377         |       sexpr EQOP sexpr
378                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
379         |       sexpr BITANDOP sexpr
380                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
381         |       sexpr BITOROP sexpr
382                         { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
383         |       sexpr DOTDOT sexpr
384                         { $$ = newRANGE($2, scalar($1), scalar($3));}
385         |       sexpr ANDAND sexpr
386                         { $$ = newLOGOP(OP_AND, 0, $1, $3); }
387         |       sexpr OROR sexpr
388                         { $$ = newLOGOP(OP_OR, 0, $1, $3); }
389         |       sexpr ANDOP sexpr
390                         { $$ = newLOGOP(OP_AND, 0, $1, $3); }
391         |       sexpr OROP sexpr
392                         { $$ = newLOGOP(OP_OR, 0, $1, $3); }
393         |       sexpr '?' sexpr ':' sexpr
394                         { $$ = newCONDOP(0, $1, $3, $5); }
395         |       sexpr MATCHOP sexpr
396                         { $$ = bind_match($2, $1, $3); }
397         |       term
398                         { $$ = $1; }
399         ;
400
401 term    :       '-' term %prec UMINUS
402                         { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); }
403         |       '+' term %prec UMINUS
404                         { $$ = $2; }
405         |       '!' term
406                         { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
407         |       '~' term
408                         { $$ = newUNOP(OP_COMPLEMENT, 0, scalar($2));}
409         |       REFGEN term
410                         { $$ = newUNOP(OP_REFGEN, 0, ref($2,OP_REFGEN)); }
411         |       term POSTINC
412                         { $$ = newUNOP(OP_POSTINC, 0,
413                                         mod(scalar($1), OP_POSTINC)); }
414         |       term POSTDEC
415                         { $$ = newUNOP(OP_POSTDEC, 0,
416                                         mod(scalar($1), OP_POSTDEC)); }
417         |       PREINC term
418                         { $$ = newUNOP(OP_PREINC, 0,
419                                         mod(scalar($2), OP_PREINC)); }
420         |       PREDEC term
421                         { $$ = newUNOP(OP_PREDEC, 0,
422                                         mod(scalar($2), OP_PREDEC)); }
423         |       LOCAL sexpr     %prec UNIOP
424                         { $$ = localize($2,$1); }
425         |       '(' expr crp
426                         { $$ = sawparens($2); }
427         |       '(' ')'
428                         { $$ = sawparens(newNULLLIST()); }
429         |       '[' expr crb                            %prec '('
430                         { $$ = newANONLIST($2); }
431         |       '[' ']'                                 %prec '('
432                         { $$ = newANONLIST(Nullop); }
433         |       HASHBRACK expr crhb                     %prec '('
434                         { $$ = newANONHASH($2); }
435         |       HASHBRACK ';' '}'                               %prec '('
436                         { $$ = newANONHASH(Nullop); }
437         |       scalar  %prec '('
438                         { $$ = $1; }
439         |       star    %prec '('
440                         { $$ = $1; }
441         |       scalar '[' expr ']'     %prec '('
442                         { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3)); }
443         |       term ARROW '[' expr ']' %prec '('
444                         { $$ = newBINOP(OP_AELEM, 0,
445                                         ref(newAVREF($1),OP_RV2AV),
446                                         scalar($4));}
447         |       term '[' expr ']'       %prec '('
448                         { $$ = newBINOP(OP_AELEM, 0,
449                                         ref(newAVREF($1),OP_RV2AV),
450                                         scalar($3));}
451         |       hsh     %prec '('
452                         { $$ = $1; }
453         |       ary     %prec '('
454                         { $$ = $1; }
455         |       arylen  %prec '('
456                         { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
457         |       scalar '{' expr ';' '}' %prec '('
458                         { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
459                             expect = XOPERATOR; }
460         |       term ARROW '{' expr ';' '}'     %prec '('
461                         { $$ = newBINOP(OP_HELEM, 0,
462                                         ref(newHVREF($1),OP_RV2HV),
463                                         jmaybe($4));
464                             expect = XOPERATOR; }
465         |       term '{' expr ';' '}'   %prec '('
466                         { $$ = newBINOP(OP_HELEM, 0,
467                                         ref(newHVREF($1),OP_RV2HV),
468                                         jmaybe($3));
469                             expect = XOPERATOR; }
470         |       '(' expr crp '[' expr ']'       %prec '('
471                         { $$ = newSLICEOP(0, $5, $2); }
472         |       '(' ')' '[' expr ']'    %prec '('
473                         { $$ = newSLICEOP(0, $4, Nullop); }
474         |       ary '[' expr ']'        %prec '('
475                         { $$ = prepend_elem(OP_ASLICE,
476                                 newOP(OP_PUSHMARK, 0),
477                                 list(
478                                     newLISTOP(OP_ASLICE, 0,
479                                         list($3),
480                                         ref($1, OP_ASLICE)))); }
481         |       ary '{' expr ';' '}'    %prec '('
482                         { $$ = prepend_elem(OP_HSLICE,
483                                 newOP(OP_PUSHMARK, 0),
484                                 list(
485                                     newLISTOP(OP_HSLICE, 0,
486                                         list($3),
487                                         ref(oopsHV($1), OP_HSLICE))));
488                             expect = XOPERATOR; }
489         |       DELETE scalar '{' expr ';' '}'  %prec '('
490                         { $$ = newBINOP(OP_DELETE, 0, oopsHV($2), jmaybe($4));
491                             expect = XOPERATOR; }
492         |       DELETE '(' scalar '{' expr ';' '}' ')'  %prec '('
493                         { $$ = newBINOP(OP_DELETE, 0, oopsHV($3), jmaybe($5));
494                             expect = XOPERATOR; }
495         |       THING   %prec '('
496                         { $$ = $1; }
497         |       amper
498                         { $$ = newUNOP(OP_ENTERSUBR, 0,
499                                 scalar($1)); }
500         |       amper '(' ')'
501                         { $$ = newUNOP(OP_ENTERSUBR, OPf_STACKED, scalar($1)); }
502         |       amper '(' expr crp
503                         { $$ = newUNOP(OP_ENTERSUBR, OPf_STACKED,
504                             list(prepend_elem(OP_LIST, scalar($1), $3))); }
505         |       NOAMP WORD listexpr
506                         { $$ = newUNOP(OP_ENTERSUBR, OPf_STACKED,
507                             list(prepend_elem(OP_LIST,
508                                 newCVREF(scalar($2)), $3))); }
509         |       NOAMP WORD indirob listexpr
510                         { $$ = convert(OP_ENTERSUBR, OPf_STACKED|OPf_SPECIAL,
511                                 prepend_elem(OP_LIST,
512                                     newMETHOD($3,$2), list($4))); }
513         |       DO sexpr        %prec UNIOP
514                         { $$ = newUNOP(OP_DOFILE, 0, scalar($2)); }
515         |       DO block        %prec '('
516                         { $$ = newUNOP(OP_NULL, OPf_SPECIAL, scope($2)); }
517         |       DO WORD '(' ')'
518                         { $$ = newUNOP(OP_ENTERSUBR, OPf_SPECIAL|OPf_STACKED,
519                             list(prepend_elem(OP_LIST,
520                                 scalar(newCVREF(scalar($2))), Nullop))); }
521         |       DO WORD '(' expr crp
522                         { $$ = newUNOP(OP_ENTERSUBR, OPf_SPECIAL|OPf_STACKED,
523                             list(prepend_elem(OP_LIST,
524                                 scalar(newCVREF(scalar($2))),
525                                 $4))); }
526         |       DO scalar '(' ')'
527                         { $$ = newUNOP(OP_ENTERSUBR, OPf_SPECIAL|OPf_STACKED,
528                             list(prepend_elem(OP_LIST,
529                                 scalar(newCVREF(scalar($2))), Nullop)));}
530         |       DO scalar '(' expr crp
531                         { $$ = newUNOP(OP_ENTERSUBR, OPf_SPECIAL|OPf_STACKED,
532                             list(prepend_elem(OP_LIST,
533                                 scalar(newCVREF(scalar($2))),
534                                 $4))); }
535         |       LOOPEX
536                         { $$ = newOP($1, OPf_SPECIAL);
537                             hints |= HINT_BLOCK_SCOPE; }
538         |       LOOPEX sexpr
539                         { $$ = newLOOPEX($1,$2); }
540         |       UNIOP
541                         { $$ = newOP($1, 0); }
542         |       UNIOP block
543                         { $$ = newUNOP($1, 0, $2); }
544         |       UNIOP sexpr
545                         { $$ = newUNOP($1, 0, $2); }
546         |       FUNC0
547                         { $$ = newOP($1, 0); }
548         |       FUNC0 '(' ')'
549                         { $$ = newOP($1, 0); }
550         |       FUNC1 '(' ')'
551                         { $$ = newOP($1, OPf_SPECIAL); }
552         |       FUNC1 '(' expr ')'
553                         { $$ = newUNOP($1, 0, $3); }
554         |       PMFUNC '(' sexpr ')'
555                         { $$ = pmruntime($1, $3, Nullop); }
556         |       PMFUNC '(' sexpr ',' sexpr ')'
557                         { $$ = pmruntime($1, $3, $5); }
558         |       WORD
559         |       listop
560         ;
561
562 listexpr:       /* NULL */
563                         { $$ = Nullop; }
564         |       expr
565                         { $$ = $1; }
566         ;
567
568 amper   :       '&' indirob
569                         { $$ = newCVREF($2); }
570         ;
571
572 scalar  :       '$' indirob
573                         { $$ = newSVREF($2); }
574         ;
575
576 ary     :       '@' indirob
577                         { $$ = newAVREF($2); }
578         ;
579
580 hsh     :       '%' indirob
581                         { $$ = newHVREF($2); }
582         ;
583
584 arylen  :       DOLSHARP indirob
585                         { $$ = newAVREF($2); }
586         ;
587
588 star    :       '*' indirob
589                         { $$ = newGVREF($2); }
590         ;
591
592 indirob :       WORD
593                         { $$ = scalar($1); }
594         |       scalar
595                         { $$ = scalar($1);  }
596         |       block
597                         { $$ = scalar(scope($1)); }
598
599         |       PRIVATEREF
600                         { $$ = $1; }
601         ;
602
603 crp     :       ',' ')'
604                         { $$ = 1; }
605         |       ')'
606                         { $$ = 0; }
607         ;
608
609 crb     :       ',' ']'
610                         { $$ = 1; }
611         |       ']'
612                         { $$ = 0; }
613         ;
614
615 crhb    :       ',' ';' '}'
616                         { $$ = 1; }
617         |       ';' '}'
618                         { $$ = 0; }
619         ;
620
621 %% /* PROGRAM */