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