This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 3.0 patch #31 patch #29, continued
[perl5.git] / perl.y
... / ...
CommitLineData
1/* $Header: perl.y,v 3.0.1.8 90/08/13 22:19:55 lwall Locked $
2 *
3 * Copyright (c) 1989, Larry Wall
4 *
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
7 *
8 * $Log: perl.y,v $
9 * Revision 3.0.1.8 90/08/13 22:19:55 lwall
10 * patch28: lowercase unquoted strings caused infinite loop
11 *
12 * Revision 3.0.1.7 90/08/09 04:17:44 lwall
13 * patch19: did preliminary work toward debugging packages and evals
14 * patch19: added require operator
15 * patch19: bare identifiers are now strings if no other interpretation possible
16 * patch19: null-label lines threw off line number of next statement
17 * patch19: split; didn't pass correct bufend to scanpat
18 *
19 * Revision 3.0.1.6 90/03/27 16:13:45 lwall
20 * patch16: formats didn't work inside eval
21 *
22 * Revision 3.0.1.5 90/03/12 16:55:56 lwall
23 * patch13: added list slice operator (LIST)[LIST]
24 * patch13: (LIST,) now legal
25 *
26 * Revision 3.0.1.4 90/02/28 18:03:23 lwall
27 * patch9: line numbers were bogus during certain portions of foreach evaluation
28 *
29 * Revision 3.0.1.3 89/12/21 20:13:41 lwall
30 * patch7: send() didn't allow a TO argument
31 *
32 * Revision 3.0.1.2 89/11/11 04:49:04 lwall
33 * patch2: moved yydebug to where its type doesn't matter
34 * patch2: !$foo++ was unreasonably illegal
35 * patch2: local(@foo) didn't work
36 * patch2: default args to unary operators didn't work
37 *
38 * Revision 3.0.1.1 89/10/26 23:20:41 lwall
39 * patch1: grandfathered "format stdout"
40 * patch1: operator(); is now normally equivalent to operator;
41 *
42 * Revision 3.0 89/10/18 15:22:04 lwall
43 * 3.0 baseline
44 *
45 */
46
47%{
48#include "INTERN.h"
49#include "perl.h"
50
51STAB *scrstab;
52ARG *arg4; /* rarely used arguments to make_op() */
53ARG *arg5;
54
55%}
56
57%start prog
58
59%union {
60 int ival;
61 char *cval;
62 ARG *arg;
63 CMD *cmdval;
64 struct compcmd compval;
65 STAB *stabval;
66 FCMD *formval;
67}
68
69%token <cval> WORD
70%token <ival> APPEND OPEN SSELECT LOOPEX
71%token <ival> USING FORMAT DO SHIFT PUSH POP LVALFUN
72%token <ival> WHILE UNTIL IF UNLESS ELSE ELSIF CONTINUE SPLIT FLIST
73%token <ival> FOR FILOP FILOP2 FILOP3 FILOP4 FILOP22 FILOP25
74%token <ival> FUNC0 FUNC1 FUNC2 FUNC3 HSHFUN HSHFUN3
75%token <ival> FLIST2 SUB FILETEST LOCAL DELETE
76%token <ival> RELOP EQOP MULOP ADDOP PACKAGE AMPER LFUNC4
77%token <formval> FORMLIST
78%token <stabval> REG ARYLEN ARY HSH STAR
79%token <arg> SUBST PATTERN
80%token <arg> RSTRING TRANS
81
82%type <ival> prog decl format remember
83%type <cmdval> block lineseq line loop cond sideff nexpr else
84%type <arg> expr sexpr cexpr csexpr term handle aryword hshword
85%type <arg> texpr listop bareword
86%type <cval> label
87%type <compval> compblock
88
89%nonassoc <ival> LISTOP
90%left ','
91%right '='
92%right '?' ':'
93%nonassoc DOTDOT
94%left OROR
95%left ANDAND
96%left '|' '^'
97%left '&'
98%nonassoc EQOP
99%nonassoc RELOP
100%nonassoc <ival> UNIOP
101%nonassoc FILETEST
102%left LS RS
103%left ADDOP
104%left MULOP
105%left MATCH NMATCH
106%right '!' '~' UMINUS
107%right POW
108%nonassoc INC DEC
109%left '('
110
111%% /* RULES */
112
113prog : /* NULL */
114 {
115#if defined(YYDEBUG) && defined(DEBUGGING)
116 yydebug = (debug & 1);
117#endif
118 }
119 /*CONTINUED*/ lineseq
120 { if (in_eval)
121 eval_root = block_head($2);
122 else
123 main_root = block_head($2); }
124 ;
125
126compblock: block CONTINUE block
127 { $$.comp_true = $1; $$.comp_alt = $3; }
128 | block else
129 { $$.comp_true = $1; $$.comp_alt = $2; }
130 ;
131
132else : /* NULL */
133 { $$ = Nullcmd; }
134 | ELSE block
135 { $$ = $2; }
136 | ELSIF '(' expr ')' compblock
137 { cmdline = $1;
138 $$ = make_ccmd(C_ELSIF,$3,$5); }
139 ;
140
141block : '{' remember lineseq '}'
142 { $$ = block_head($3);
143 if (savestack->ary_fill > $2)
144 restorelist($2); }
145 ;
146
147remember: /* NULL */ /* in case they push a package name */
148 { $$ = savestack->ary_fill; }
149 ;
150
151lineseq : /* NULL */
152 { $$ = Nullcmd; }
153 | lineseq line
154 { $$ = append_line($1,$2); }
155 ;
156
157line : decl
158 { $$ = Nullcmd; }
159 | label cond
160 { $$ = add_label($1,$2); }
161 | loop /* loops add their own labels */
162 | label ';'
163 { if ($1 != Nullch) {
164 $$ = add_label($1, make_acmd(C_EXPR, Nullstab,
165 Nullarg, Nullarg) );
166 }
167 else {
168 $$ = Nullcmd;
169 cmdline = NOLINE;
170 } }
171 | label sideff ';'
172 { $$ = add_label($1,$2); }
173 ;
174
175sideff : error
176 { $$ = Nullcmd; }
177 | expr
178 { $$ = make_acmd(C_EXPR, Nullstab, $1, Nullarg); }
179 | expr IF expr
180 { $$ = addcond(
181 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $3); }
182 | expr UNLESS expr
183 { $$ = addcond(invert(
184 make_acmd(C_EXPR, Nullstab, Nullarg, $1)), $3); }
185 | expr WHILE expr
186 { $$ = addloop(
187 make_acmd(C_EXPR, Nullstab, Nullarg, $1), $3); }
188 | expr UNTIL expr
189 { $$ = addloop(invert(
190 make_acmd(C_EXPR, Nullstab, Nullarg, $1)), $3); }
191 ;
192
193cond : IF '(' expr ')' compblock
194 { cmdline = $1;
195 $$ = make_icmd(C_IF,$3,$5); }
196 | UNLESS '(' expr ')' compblock
197 { cmdline = $1;
198 $$ = invert(make_icmd(C_IF,$3,$5)); }
199 | IF block compblock
200 { cmdline = $1;
201 $$ = make_ccmd(C_IF,cmd_to_arg($2),$3); }
202 | UNLESS block compblock
203 { cmdline = $1;
204 $$ = invert(make_ccmd(C_IF,cmd_to_arg($2),$3)); }
205 ;
206
207loop : label WHILE '(' texpr ')' compblock
208 { cmdline = $2;
209 $$ = wopt(add_label($1,
210 make_ccmd(C_WHILE,$4,$6) )); }
211 | label UNTIL '(' expr ')' compblock
212 { cmdline = $2;
213 $$ = wopt(add_label($1,
214 invert(make_ccmd(C_WHILE,$4,$6)) )); }
215 | label WHILE block compblock
216 { cmdline = $2;
217 $$ = wopt(add_label($1,
218 make_ccmd(C_WHILE, cmd_to_arg($3),$4) )); }
219 | label UNTIL block compblock
220 { cmdline = $2;
221 $$ = wopt(add_label($1,
222 invert(make_ccmd(C_WHILE, cmd_to_arg($3),$4)) )); }
223 | label FOR REG '(' expr ')' compblock
224 { cmdline = $2;
225 /*
226 * The following gobbledygook catches EXPRs that
227 * aren't explicit array refs and translates
228 * foreach VAR (EXPR) {
229 * into
230 * @ary = EXPR;
231 * foreach VAR (@ary) {
232 * where @ary is a hidden array made by genstab().
233 * (Note that @ary may become a local array if
234 * it is determined that it might be called
235 * recursively. See cmd_tosave().)
236 */
237 if ($5->arg_type != O_ARRAY) {
238 scrstab = aadd(genstab());
239 $$ = append_line(
240 make_acmd(C_EXPR, Nullstab,
241 l(make_op(O_ASSIGN,2,
242 listish(make_op(O_ARRAY, 1,
243 stab2arg(A_STAB,scrstab),
244 Nullarg,Nullarg )),
245 listish(make_list($5)),
246 Nullarg)),
247 Nullarg),
248 wopt(over($3,add_label($1,
249 make_ccmd(C_WHILE,
250 make_op(O_ARRAY, 1,
251 stab2arg(A_STAB,scrstab),
252 Nullarg,Nullarg ),
253 $7)))));
254 $$->c_line = $2;
255 $$->c_head->c_line = $2;
256 }
257 else {
258 $$ = wopt(over($3,add_label($1,
259 make_ccmd(C_WHILE,$5,$7) )));
260 }
261 }
262 | label FOR '(' expr ')' compblock
263 { cmdline = $2;
264 if ($4->arg_type != O_ARRAY) {
265 scrstab = aadd(genstab());
266 $$ = append_line(
267 make_acmd(C_EXPR, Nullstab,
268 l(make_op(O_ASSIGN,2,
269 listish(make_op(O_ARRAY, 1,
270 stab2arg(A_STAB,scrstab),
271 Nullarg,Nullarg )),
272 listish(make_list($4)),
273 Nullarg)),
274 Nullarg),
275 wopt(over(defstab,add_label($1,
276 make_ccmd(C_WHILE,
277 make_op(O_ARRAY, 1,
278 stab2arg(A_STAB,scrstab),
279 Nullarg,Nullarg ),
280 $6)))));
281 $$->c_line = $2;
282 $$->c_head->c_line = $2;
283 }
284 else { /* lisp, anyone? */
285 $$ = wopt(over(defstab,add_label($1,
286 make_ccmd(C_WHILE,$4,$6) )));
287 }
288 }
289 | label FOR '(' nexpr ';' texpr ';' nexpr ')' block
290 /* basically fake up an initialize-while lineseq */
291 { yyval.compval.comp_true = $10;
292 yyval.compval.comp_alt = $8;
293 cmdline = $2;
294 $$ = append_line($4,wopt(add_label($1,
295 make_ccmd(C_WHILE,$6,yyval.compval) ))); }
296 | label compblock /* a block is a loop that happens once */
297 { $$ = add_label($1,make_ccmd(C_BLOCK,Nullarg,$2)); }
298 ;
299
300nexpr : /* NULL */
301 { $$ = Nullcmd; }
302 | sideff
303 ;
304
305texpr : /* NULL means true */
306 { (void)scanstr("1"); $$ = yylval.arg; }
307 | expr
308 ;
309
310label : /* empty */
311 { $$ = Nullch; }
312 | WORD ':'
313 ;
314
315decl : format
316 { $$ = 0; }
317 | subrout
318 { $$ = 0; }
319 | package
320 { $$ = 0; }
321 ;
322
323format : FORMAT WORD '=' FORMLIST
324 { if (strEQ($2,"stdout"))
325 make_form(stabent("STDOUT",TRUE),$4);
326 else if (strEQ($2,"stderr"))
327 make_form(stabent("STDERR",TRUE),$4);
328 else
329 make_form(stabent($2,TRUE),$4);
330 Safefree($2);}
331 | FORMAT '=' FORMLIST
332 { make_form(stabent("STDOUT",TRUE),$3); }
333 ;
334
335subrout : SUB WORD block
336 { make_sub($2,$3); }
337 ;
338
339package : PACKAGE WORD ';'
340 { char tmpbuf[256];
341 STAB *tmpstab;
342
343 savehptr(&curstash);
344 saveitem(curstname);
345 str_set(curstname,$2);
346 sprintf(tmpbuf,"'_%s",$2);
347 tmpstab = hadd(stabent(tmpbuf,TRUE));
348 curstash = stab_xhash(tmpstab);
349 curpack = stab_name(tmpstab);
350 curstash->tbl_coeffsize = 0;
351 Safefree($2);
352 }
353 ;
354
355cexpr : ',' expr
356 { $$ = $2; }
357 ;
358
359expr : expr ',' sexpr
360 { $$ = make_op(O_COMMA, 2, $1, $3, Nullarg); }
361 | sexpr
362 ;
363
364csexpr : ',' sexpr
365 { $$ = $2; }
366 ;
367
368sexpr : sexpr '=' sexpr
369 { $1 = listish($1);
370 if ($1->arg_type == O_ASSIGN && $1->arg_len == 1)
371 $1->arg_type = O_ITEM; /* a local() */
372 if ($1->arg_type == O_LIST)
373 $3 = listish($3);
374 $$ = l(make_op(O_ASSIGN, 2, $1, $3, Nullarg)); }
375 | sexpr POW '=' sexpr
376 { $$ = l(make_op(O_POW, 2, $1, $4, Nullarg)); }
377 | sexpr MULOP '=' sexpr
378 { $$ = l(make_op($2, 2, $1, $4, Nullarg)); }
379 | sexpr ADDOP '=' sexpr
380 { $$ = rcatmaybe(l(make_op($2, 2, $1, $4, Nullarg)));}
381 | sexpr LS '=' sexpr
382 { $$ = l(make_op(O_LEFT_SHIFT, 2, $1, $4, Nullarg)); }
383 | sexpr RS '=' sexpr
384 { $$ = l(make_op(O_RIGHT_SHIFT, 2, $1, $4, Nullarg)); }
385 | sexpr '&' '=' sexpr
386 { $$ = l(make_op(O_BIT_AND, 2, $1, $4, Nullarg)); }
387 | sexpr '^' '=' sexpr
388 { $$ = l(make_op(O_XOR, 2, $1, $4, Nullarg)); }
389 | sexpr '|' '=' sexpr
390 { $$ = l(make_op(O_BIT_OR, 2, $1, $4, Nullarg)); }
391
392
393 | sexpr POW sexpr
394 { $$ = make_op(O_POW, 2, $1, $3, Nullarg); }
395 | sexpr MULOP sexpr
396 { $$ = make_op($2, 2, $1, $3, Nullarg); }
397 | sexpr ADDOP sexpr
398 { $$ = make_op($2, 2, $1, $3, Nullarg); }
399 | sexpr LS sexpr
400 { $$ = make_op(O_LEFT_SHIFT, 2, $1, $3, Nullarg); }
401 | sexpr RS sexpr
402 { $$ = make_op(O_RIGHT_SHIFT, 2, $1, $3, Nullarg); }
403 | sexpr RELOP sexpr
404 { $$ = make_op($2, 2, $1, $3, Nullarg); }
405 | sexpr EQOP sexpr
406 { $$ = make_op($2, 2, $1, $3, Nullarg); }
407 | sexpr '&' sexpr
408 { $$ = make_op(O_BIT_AND, 2, $1, $3, Nullarg); }
409 | sexpr '^' sexpr
410 { $$ = make_op(O_XOR, 2, $1, $3, Nullarg); }
411 | sexpr '|' sexpr
412 { $$ = make_op(O_BIT_OR, 2, $1, $3, Nullarg); }
413 | sexpr DOTDOT sexpr
414 { arg4 = Nullarg;
415 $$ = make_op(O_F_OR_R, 4, $1, $3, Nullarg); }
416 | sexpr ANDAND sexpr
417 { $$ = make_op(O_AND, 2, $1, $3, Nullarg); }
418 | sexpr OROR sexpr
419 { $$ = make_op(O_OR, 2, $1, $3, Nullarg); }
420 | sexpr '?' sexpr ':' sexpr
421 { $$ = make_op(O_COND_EXPR, 3, $1, $3, $5); }
422 | sexpr MATCH sexpr
423 { $$ = mod_match(O_MATCH, $1, $3); }
424 | sexpr NMATCH sexpr
425 { $$ = mod_match(O_NMATCH, $1, $3); }
426 | term
427 { $$ = $1; }
428 ;
429
430term : '-' term %prec UMINUS
431 { $$ = make_op(O_NEGATE, 1, $2, Nullarg, Nullarg); }
432 | '+' term %prec UMINUS
433 { $$ = $2; }
434 | '!' term
435 { $$ = make_op(O_NOT, 1, $2, Nullarg, Nullarg); }
436 | '~' term
437 { $$ = make_op(O_COMPLEMENT, 1, $2, Nullarg, Nullarg);}
438 | term INC
439 { $$ = addflags(1, AF_POST|AF_UP,
440 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg))); }
441 | term DEC
442 { $$ = addflags(1, AF_POST,
443 l(make_op(O_ITEM,1,$1,Nullarg,Nullarg))); }
444 | INC term
445 { $$ = addflags(1, AF_PRE|AF_UP,
446 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg))); }
447 | DEC term
448 { $$ = addflags(1, AF_PRE,
449 l(make_op(O_ITEM,1,$2,Nullarg,Nullarg))); }
450 | FILETEST WORD
451 { opargs[$1] = 0; /* force it special */
452 $$ = make_op($1, 1,
453 stab2arg(A_STAB,stabent($2,TRUE)),
454 Nullarg, Nullarg);
455 }
456 | FILETEST sexpr
457 { opargs[$1] = 1;
458 $$ = make_op($1, 1, $2, Nullarg, Nullarg); }
459 | FILETEST
460 { opargs[$1] = ($1 != O_FTTTY);
461 $$ = make_op($1, 1,
462 stab2arg(A_STAB,
463 $1 == O_FTTTY?stabent("STDIN",TRUE):defstab),
464 Nullarg, Nullarg); }
465 | LOCAL '(' expr ')'
466 { $$ = l(localize(make_op(O_ASSIGN, 1,
467 localize(listish(make_list($3))),
468 Nullarg,Nullarg))); }
469 | '(' expr ',' ')'
470 { $$ = make_list(hide_ary($2)); }
471 | '(' expr ')'
472 { $$ = make_list(hide_ary($2)); }
473 | '(' ')'
474 { $$ = make_list(Nullarg); }
475 | DO sexpr %prec FILETEST
476 { $$ = fixeval(
477 make_op(O_DOFILE,2,$2,Nullarg,Nullarg) );
478 allstabs = TRUE;}
479 | DO block %prec '('
480 { $$ = cmd_to_arg($2); }
481 | REG %prec '('
482 { $$ = stab2arg(A_STAB,$1); }
483 | STAR %prec '('
484 { $$ = stab2arg(A_STAR,$1); }
485 | REG '[' expr ']' %prec '('
486 { $$ = make_op(O_AELEM, 2,
487 stab2arg(A_STAB,aadd($1)), $3, Nullarg); }
488 | HSH %prec '('
489 { $$ = make_op(O_HASH, 1,
490 stab2arg(A_STAB,$1),
491 Nullarg, Nullarg); }
492 | ARY %prec '('
493 { $$ = make_op(O_ARRAY, 1,
494 stab2arg(A_STAB,$1),
495 Nullarg, Nullarg); }
496 | REG '{' expr '}' %prec '('
497 { $$ = make_op(O_HELEM, 2,
498 stab2arg(A_STAB,hadd($1)),
499 jmaybe($3),
500 Nullarg); }
501 | '(' expr ')' '[' expr ']' %prec '('
502 { $$ = make_op(O_LSLICE, 3,
503 Nullarg,
504 listish(make_list($5)),
505 listish(make_list($2))); }
506 | ARY '[' expr ']' %prec '('
507 { $$ = make_op(O_ASLICE, 2,
508 stab2arg(A_STAB,aadd($1)),
509 listish(make_list($3)),
510 Nullarg); }
511 | ARY '{' expr '}' %prec '('
512 { $$ = make_op(O_HSLICE, 2,
513 stab2arg(A_STAB,hadd($1)),
514 listish(make_list($3)),
515 Nullarg); }
516 | DELETE REG '{' expr '}' %prec '('
517 { $$ = make_op(O_DELETE, 2,
518 stab2arg(A_STAB,hadd($2)),
519 jmaybe($4),
520 Nullarg); }
521 | ARYLEN %prec '('
522 { $$ = stab2arg(A_ARYLEN,$1); }
523 | RSTRING %prec '('
524 { $$ = $1; }
525 | PATTERN %prec '('
526 { $$ = $1; }
527 | SUBST %prec '('
528 { $$ = $1; }
529 | TRANS %prec '('
530 { $$ = $1; }
531 | DO WORD '(' expr ')'
532 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
533 stab2arg(A_WORD,stabent($2,TRUE)),
534 make_list($4),
535 Nullarg); Safefree($2); }
536 | AMPER WORD '(' expr ')'
537 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
538 stab2arg(A_WORD,stabent($2,TRUE)),
539 make_list($4),
540 Nullarg); Safefree($2); }
541 | DO WORD '(' ')'
542 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
543 stab2arg(A_WORD,stabent($2,TRUE)),
544 make_list(Nullarg),
545 Nullarg); }
546 | AMPER WORD '(' ')'
547 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
548 stab2arg(A_WORD,stabent($2,TRUE)),
549 make_list(Nullarg),
550 Nullarg); }
551 | AMPER WORD
552 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
553 stab2arg(A_WORD,stabent($2,TRUE)),
554 Nullarg,
555 Nullarg); }
556 | DO REG '(' expr ')'
557 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
558 stab2arg(A_STAB,$2),
559 make_list($4),
560 Nullarg); }
561 | AMPER REG '(' expr ')'
562 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
563 stab2arg(A_STAB,$2),
564 make_list($4),
565 Nullarg); }
566 | DO REG '(' ')'
567 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
568 stab2arg(A_STAB,$2),
569 make_list(Nullarg),
570 Nullarg); }
571 | AMPER REG '(' ')'
572 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
573 stab2arg(A_STAB,$2),
574 make_list(Nullarg),
575 Nullarg); }
576 | AMPER REG
577 { $$ = make_op((perldb ? O_DBSUBR : O_SUBR), 2,
578 stab2arg(A_STAB,$2),
579 Nullarg,
580 Nullarg); }
581 | LOOPEX
582 { $$ = make_op($1,0,Nullarg,Nullarg,Nullarg); }
583 | LOOPEX WORD
584 { $$ = make_op($1,1,cval_to_arg($2),
585 Nullarg,Nullarg); }
586 | UNIOP
587 { $$ = make_op($1,0,Nullarg,Nullarg,Nullarg);
588 if ($1 == O_EVAL || $1 == O_RESET || $1 == O_REQUIRE)
589 $$ = fixeval($$); }
590 | UNIOP sexpr
591 { $$ = make_op($1,1,$2,Nullarg,Nullarg);
592 if ($1 == O_EVAL || $1 == O_RESET || $1 == O_REQUIRE)
593 $$ = fixeval($$); }
594 | SSELECT
595 { $$ = make_op(O_SELECT, 0, Nullarg, Nullarg, Nullarg);}
596 | SSELECT '(' handle ')'
597 { $$ = make_op(O_SELECT, 1, $3, Nullarg, Nullarg); }
598 | SSELECT '(' sexpr csexpr csexpr csexpr ')'
599 { arg4 = $6;
600 $$ = make_op(O_SSELECT, 4, $3, $4, $5); }
601 | OPEN WORD %prec '('
602 { $$ = make_op(O_OPEN, 2,
603 stab2arg(A_WORD,stabent($2,TRUE)),
604 stab2arg(A_STAB,stabent($2,TRUE)),
605 Nullarg); }
606 | OPEN '(' WORD ')'
607 { $$ = make_op(O_OPEN, 2,
608 stab2arg(A_WORD,stabent($3,TRUE)),
609 stab2arg(A_STAB,stabent($3,TRUE)),
610 Nullarg); }
611 | OPEN '(' handle cexpr ')'
612 { $$ = make_op(O_OPEN, 2,
613 $3,
614 $4, Nullarg); }
615 | FILOP '(' handle ')'
616 { $$ = make_op($1, 1,
617 $3,
618 Nullarg, Nullarg); }
619 | FILOP WORD
620 { $$ = make_op($1, 1,
621 stab2arg(A_WORD,stabent($2,TRUE)),
622 Nullarg, Nullarg);
623 Safefree($2); }
624 | FILOP REG
625 { $$ = make_op($1, 1,
626 stab2arg(A_STAB,$2),
627 Nullarg, Nullarg); }
628 | FILOP '(' ')'
629 { $$ = make_op($1, 1,
630 stab2arg(A_WORD,Nullstab),
631 Nullarg, Nullarg); }
632 | FILOP %prec '('
633 { $$ = make_op($1, 0,
634 Nullarg, Nullarg, Nullarg); }
635 | FILOP2 '(' handle cexpr ')'
636 { $$ = make_op($1, 2, $3, $4, Nullarg); }
637 | FILOP3 '(' handle csexpr cexpr ')'
638 { $$ = make_op($1, 3, $3, $4, make_list($5)); }
639 | FILOP22 '(' handle ',' handle ')'
640 { $$ = make_op($1, 2, $3, $5, Nullarg); }
641 | FILOP4 '(' handle csexpr csexpr cexpr ')'
642 { arg4 = $6; $$ = make_op($1, 4, $3, $4, $5); }
643 | FILOP25 '(' handle ',' handle csexpr csexpr cexpr ')'
644 { arg4 = $7; arg5 = $8;
645 $$ = make_op($1, 5, $3, $5, $6); }
646 | PUSH '(' aryword cexpr ')'
647 { $$ = make_op($1, 2,
648 $3,
649 make_list($4),
650 Nullarg); }
651 | POP aryword %prec '('
652 { $$ = make_op(O_POP, 1, $2, Nullarg, Nullarg); }
653 | POP '(' aryword ')'
654 { $$ = make_op(O_POP, 1, $3, Nullarg, Nullarg); }
655 | SHIFT aryword %prec '('
656 { $$ = make_op(O_SHIFT, 1, $2, Nullarg, Nullarg); }
657 | SHIFT '(' aryword ')'
658 { $$ = make_op(O_SHIFT, 1, $3, Nullarg, Nullarg); }
659 | SHIFT %prec '('
660 { $$ = make_op(O_SHIFT, 1,
661 stab2arg(A_STAB,
662 aadd(stabent(subline ? "_" : "ARGV", TRUE))),
663 Nullarg, Nullarg); }
664 | SPLIT %prec '('
665{static char p[]="/\\s+/";char*o=bufend;bufend=p+5;(void)scanpat(p);bufend=o;
666 $$ = make_split(defstab,yylval.arg,Nullarg); }
667 | SPLIT '(' sexpr csexpr csexpr ')'
668 { $$ = mod_match(O_MATCH, $4,
669 make_split(defstab,$3,$5));}
670 | SPLIT '(' sexpr csexpr ')'
671 { $$ = mod_match(O_MATCH, $4,
672 make_split(defstab,$3,Nullarg) ); }
673 | SPLIT '(' sexpr ')'
674 { $$ = mod_match(O_MATCH,
675 stab2arg(A_STAB,defstab),
676 make_split(defstab,$3,Nullarg) ); }
677 | FLIST2 '(' sexpr cexpr ')'
678 { $$ = make_op($1, 2,
679 $3,
680 listish(make_list($4)),
681 Nullarg); }
682 | FLIST '(' expr ')'
683 { $$ = make_op($1, 1,
684 make_list($3),
685 Nullarg,
686 Nullarg); }
687 | LVALFUN sexpr %prec '('
688 { $$ = l(make_op($1, 1, fixl($1,$2),
689 Nullarg, Nullarg)); }
690 | LVALFUN
691 { $$ = l(make_op($1, 1,
692 stab2arg(A_STAB,defstab),
693 Nullarg, Nullarg)); }
694 | FUNC0
695 { $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg); }
696 | FUNC0 '(' ')'
697 { $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg); }
698 | FUNC1 '(' ')'
699 { $$ = make_op($1, 0, Nullarg, Nullarg, Nullarg);
700 if ($1 == O_EVAL || $1 == O_RESET || $1 == O_REQUIRE)
701 $$ = fixeval($$); }
702 | FUNC1 '(' expr ')'
703 { $$ = make_op($1, 1, $3, Nullarg, Nullarg);
704 if ($1 == O_EVAL || $1 == O_RESET || $1 == O_REQUIRE)
705 $$ = fixeval($$); }
706 | FUNC2 '(' sexpr cexpr ')'
707 { $$ = make_op($1, 2, $3, $4, Nullarg);
708 if ($1 == O_INDEX && $$[2].arg_type == A_SINGLE)
709 fbmcompile($$[2].arg_ptr.arg_str,0); }
710 | FUNC3 '(' sexpr csexpr cexpr ')'
711 { $$ = make_op($1, 3, $3, $4, $5); }
712 | LFUNC4 '(' sexpr csexpr csexpr cexpr ')'
713 { arg4 = $6; $$ = make_op($1, 4, l($3), $4, $5); }
714 | HSHFUN '(' hshword ')'
715 { $$ = make_op($1, 1,
716 $3,
717 Nullarg,
718 Nullarg); }
719 | HSHFUN hshword
720 { $$ = make_op($1, 1,
721 $2,
722 Nullarg,
723 Nullarg); }
724 | HSHFUN3 '(' hshword csexpr cexpr ')'
725 { $$ = make_op($1, 3, $3, $4, $5); }
726 | bareword
727 | listop
728 ;
729
730listop : LISTOP
731 { $$ = make_op($1,2,
732 stab2arg(A_WORD,Nullstab),
733 stab2arg(A_STAB,defstab),
734 Nullarg); }
735 | LISTOP expr
736 { $$ = make_op($1,2,
737 stab2arg(A_WORD,Nullstab),
738 maybelistish($1,make_list($2)),
739 Nullarg); }
740 | LISTOP WORD
741 { $$ = make_op($1,2,
742 stab2arg(A_WORD,stabent($2,TRUE)),
743 stab2arg(A_STAB,defstab),
744 Nullarg); }
745 | LISTOP WORD expr
746 { $$ = make_op($1,2,
747 stab2arg(A_WORD,stabent($2,TRUE)),
748 maybelistish($1,make_list($3)),
749 Nullarg); Safefree($2); }
750 | LISTOP REG expr
751 { $$ = make_op($1,2,
752 stab2arg(A_STAB,$2),
753 maybelistish($1,make_list($3)),
754 Nullarg); }
755 ;
756
757handle : WORD
758 { $$ = stab2arg(A_WORD,stabent($1,TRUE)); Safefree($1);}
759 | sexpr
760 ;
761
762aryword : WORD
763 { $$ = stab2arg(A_WORD,aadd(stabent($1,TRUE)));
764 Safefree($1); }
765 | ARY
766 { $$ = stab2arg(A_STAB,$1); }
767 ;
768
769hshword : WORD
770 { $$ = stab2arg(A_WORD,hadd(stabent($1,TRUE)));
771 Safefree($1); }
772 | HSH
773 { $$ = stab2arg(A_STAB,$1); }
774 ;
775
776/*
777 * NOTE: The following entry must stay at the end of the file so that
778 * reduce/reduce conflicts resolve to it only if it's the only option.
779 */
780
781bareword: WORD
782 { char *s;
783 $$ = op_new(1);
784 $$->arg_type = O_ITEM;
785 $$[1].arg_type = A_SINGLE;
786 $$[1].arg_ptr.arg_str = str_make($1,0);
787 for (s = $1; *s && islower(*s); s++) ;
788 if (dowarn && !*s)
789 warn(
790 "\"%s\" may clash with future reserved word",
791 $1 );
792 }
793
794%% /* PROGRAM */