17c478bd9Sstevel@tonic-gate %{
2*3ee4fc2aSCody Peter Mello /*
3*3ee4fc2aSCody Peter Mello * Copyright (C) Lucent Technologies 1997
4*3ee4fc2aSCody Peter Mello * All Rights Reserved
5*3ee4fc2aSCody Peter Mello *
6*3ee4fc2aSCody Peter Mello * Permission to use, copy, modify, and distribute this software and
7*3ee4fc2aSCody Peter Mello * its documentation for any purpose and without fee is hereby
8*3ee4fc2aSCody Peter Mello * granted, provided that the above copyright notice appear in all
9*3ee4fc2aSCody Peter Mello * copies and that both that the copyright notice and this
10*3ee4fc2aSCody Peter Mello * permission notice and warranty disclaimer appear in supporting
11*3ee4fc2aSCody Peter Mello * documentation, and that the name Lucent Technologies or any of
12*3ee4fc2aSCody Peter Mello * its entities not be used in advertising or publicity pertaining
13*3ee4fc2aSCody Peter Mello * to distribution of the software without specific, written prior
14*3ee4fc2aSCody Peter Mello * permission.
15*3ee4fc2aSCody Peter Mello *
16*3ee4fc2aSCody Peter Mello * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17*3ee4fc2aSCody Peter Mello * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
18*3ee4fc2aSCody Peter Mello * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
19*3ee4fc2aSCody Peter Mello * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20*3ee4fc2aSCody Peter Mello * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
21*3ee4fc2aSCody Peter Mello * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22*3ee4fc2aSCody Peter Mello * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
23*3ee4fc2aSCody Peter Mello * THIS SOFTWARE.
24*3ee4fc2aSCody Peter Mello */
25*3ee4fc2aSCody Peter Mello
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate * CDDL HEADER START
287c478bd9Sstevel@tonic-gate *
297c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
307c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
317c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
327c478bd9Sstevel@tonic-gate * with the License.
337c478bd9Sstevel@tonic-gate *
347c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
357c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
367c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
377c478bd9Sstevel@tonic-gate * and limitations under the License.
387c478bd9Sstevel@tonic-gate *
397c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
407c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
417c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
427c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
437c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
447c478bd9Sstevel@tonic-gate *
457c478bd9Sstevel@tonic-gate * CDDL HEADER END
467c478bd9Sstevel@tonic-gate */
477c478bd9Sstevel@tonic-gate %}
481ee2e5faSnakanon /*
491ee2e5faSnakanon * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
501ee2e5faSnakanon * Use is subject to license terms.
511ee2e5faSnakanon */
521ee2e5faSnakanon
537c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
547c478bd9Sstevel@tonic-gate /* All Rights Reserved */
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate %{
577c478bd9Sstevel@tonic-gate #include "awk.h"
58*3ee4fc2aSCody Peter Mello
59*3ee4fc2aSCody Peter Mello void checkdup(Node *list, Cell *item);
yywrap(void)601ee2e5faSnakanon int yywrap(void) { return(1); }
61*3ee4fc2aSCody Peter Mello
62*3ee4fc2aSCody Peter Mello Node *beginloc = NULL;
63*3ee4fc2aSCody Peter Mello Node *endloc = NULL;
64*3ee4fc2aSCody Peter Mello int infunc = 0; /* = 1 if in arglist or body of func */
65*3ee4fc2aSCody Peter Mello int inloop = 0; /* = 1 if in while, for, do */
66*3ee4fc2aSCody Peter Mello char *curfname = NULL; /* current function name */
67*3ee4fc2aSCody Peter Mello Node *arglist = NULL; /* list of args for current function */
681ee2e5faSnakanon static void setfname(Cell *);
691ee2e5faSnakanon static int constnode(Node *);
70*3ee4fc2aSCody Peter Mello static char *strnode(Node *);
71*3ee4fc2aSCody Peter Mello static Node *notnull(Node *);
727c478bd9Sstevel@tonic-gate %}
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate %union {
757c478bd9Sstevel@tonic-gate Node *p;
767c478bd9Sstevel@tonic-gate Cell *cp;
777c478bd9Sstevel@tonic-gate int i;
78*3ee4fc2aSCody Peter Mello char *s;
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate
817c478bd9Sstevel@tonic-gate %token <i> FIRSTTOKEN /* must be first */
827c478bd9Sstevel@tonic-gate %token <p> PROGRAM PASTAT PASTAT2 XBEGIN XEND
837c478bd9Sstevel@tonic-gate %token <i> NL ',' '{' '(' '|' ';' '/' ')' '}' '[' ']'
847c478bd9Sstevel@tonic-gate %token <i> ARRAY
857c478bd9Sstevel@tonic-gate %token <i> MATCH NOTMATCH MATCHOP
86*3ee4fc2aSCody Peter Mello %token <i> FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS EMPTYRE
877c478bd9Sstevel@tonic-gate %token <i> AND BOR APPEND EQ GE GT LE LT NE IN
88*3ee4fc2aSCody Peter Mello %token <i> ARG BLTIN BREAK CLOSE CONTINUE DELETE DO EXIT FOR FUNC
89*3ee4fc2aSCody Peter Mello %token <i> SUB GSUB IF INDEX LSUBSTR MATCHFCN NEXT NEXTFILE
907c478bd9Sstevel@tonic-gate %token <i> ADD MINUS MULT DIVIDE MOD
917c478bd9Sstevel@tonic-gate %token <i> ASSIGN ASGNOP ADDEQ SUBEQ MULTEQ DIVEQ MODEQ POWEQ
927c478bd9Sstevel@tonic-gate %token <i> PRINT PRINTF SPRINTF
937c478bd9Sstevel@tonic-gate %token <p> ELSE INTEST CONDEXPR
947c478bd9Sstevel@tonic-gate %token <i> POSTINCR PREINCR POSTDECR PREDECR
95*3ee4fc2aSCody Peter Mello %token <cp> VAR IVAR VARNF CALL NUMBER STRING
967c478bd9Sstevel@tonic-gate %token <s> REGEXPR
977c478bd9Sstevel@tonic-gate
98*3ee4fc2aSCody Peter Mello %type <p> pas pattern ppattern plist pplist patlist prarg term re
997c478bd9Sstevel@tonic-gate %type <p> pa_pat pa_stat pa_stats
1007c478bd9Sstevel@tonic-gate %type <s> reg_expr
1017c478bd9Sstevel@tonic-gate %type <p> simple_stmt opt_simple_stmt stmt stmtlist
1027c478bd9Sstevel@tonic-gate %type <p> var varname funcname varlist
103*3ee4fc2aSCody Peter Mello %type <p> for if else while
104*3ee4fc2aSCody Peter Mello %type <i> do st
105*3ee4fc2aSCody Peter Mello %type <i> pst opt_pst lbrace rbrace rparen comma nl opt_nl and bor
1067c478bd9Sstevel@tonic-gate %type <i> subop print
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate %right ASGNOP
1097c478bd9Sstevel@tonic-gate %right '?'
1107c478bd9Sstevel@tonic-gate %right ':'
1117c478bd9Sstevel@tonic-gate %left BOR
1127c478bd9Sstevel@tonic-gate %left AND
1137c478bd9Sstevel@tonic-gate %left GETLINE
1147c478bd9Sstevel@tonic-gate %nonassoc APPEND EQ GE GT LE LT NE MATCHOP IN '|'
115*3ee4fc2aSCody Peter Mello %left ARG BLTIN BREAK CALL CLOSE CONTINUE DELETE DO EXIT FOR FUNC
1167c478bd9Sstevel@tonic-gate %left GSUB IF INDEX LSUBSTR MATCHFCN NEXT NUMBER
1177c478bd9Sstevel@tonic-gate %left PRINT PRINTF RETURN SPLIT SPRINTF STRING SUB SUBSTR
1187c478bd9Sstevel@tonic-gate %left REGEXPR VAR VARNF IVAR WHILE '('
1197c478bd9Sstevel@tonic-gate %left CAT
1207c478bd9Sstevel@tonic-gate %left '+' '-'
1217c478bd9Sstevel@tonic-gate %left '*' '/' '%'
122*3ee4fc2aSCody Peter Mello %left NOT UMINUS UPLUS
1237c478bd9Sstevel@tonic-gate %right POWER
1247c478bd9Sstevel@tonic-gate %right DECR INCR
1257c478bd9Sstevel@tonic-gate %left INDIRECT
1267c478bd9Sstevel@tonic-gate %token LASTTOKEN /* must be last */
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate %%
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate program:
1317c478bd9Sstevel@tonic-gate pas { if (errorflag==0)
1327c478bd9Sstevel@tonic-gate winner = (Node *)stat3(PROGRAM, beginloc, $1, endloc); }
133*3ee4fc2aSCody Peter Mello | error { yyclearin; bracecheck(); SYNTAX("bailing out"); }
1347c478bd9Sstevel@tonic-gate ;
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate and:
1377c478bd9Sstevel@tonic-gate AND | and NL
1387c478bd9Sstevel@tonic-gate ;
1397c478bd9Sstevel@tonic-gate
1407c478bd9Sstevel@tonic-gate bor:
1417c478bd9Sstevel@tonic-gate BOR | bor NL
1427c478bd9Sstevel@tonic-gate ;
1437c478bd9Sstevel@tonic-gate
1447c478bd9Sstevel@tonic-gate comma:
1457c478bd9Sstevel@tonic-gate ',' | comma NL
1467c478bd9Sstevel@tonic-gate ;
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate do:
1497c478bd9Sstevel@tonic-gate DO | do NL
1507c478bd9Sstevel@tonic-gate ;
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate else:
1537c478bd9Sstevel@tonic-gate ELSE | else NL
1547c478bd9Sstevel@tonic-gate ;
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate for:
157*3ee4fc2aSCody Peter Mello FOR '(' opt_simple_stmt ';' opt_nl pattern ';' opt_nl opt_simple_stmt rparen {inloop++;} stmt
158*3ee4fc2aSCody Peter Mello { --inloop; $$ = stat4(FOR, $3, notnull($6), $9, $12); }
159*3ee4fc2aSCody Peter Mello | FOR '(' opt_simple_stmt ';' ';' opt_nl opt_simple_stmt rparen {inloop++;} stmt
160*3ee4fc2aSCody Peter Mello { --inloop; $$ = stat4(FOR, $3, NIL, $7, $10); }
161*3ee4fc2aSCody Peter Mello | FOR '(' varname IN varname rparen {inloop++;} stmt
162*3ee4fc2aSCody Peter Mello { --inloop; $$ = stat3(IN, $3, makearr($5), $8); }
1637c478bd9Sstevel@tonic-gate ;
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate funcname:
1667c478bd9Sstevel@tonic-gate VAR { setfname($1); }
1677c478bd9Sstevel@tonic-gate | CALL { setfname($1); }
1687c478bd9Sstevel@tonic-gate ;
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate if:
1717c478bd9Sstevel@tonic-gate IF '(' pattern rparen { $$ = notnull($3); }
1727c478bd9Sstevel@tonic-gate ;
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate lbrace:
1757c478bd9Sstevel@tonic-gate '{' | lbrace NL
1767c478bd9Sstevel@tonic-gate ;
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gate nl:
1797c478bd9Sstevel@tonic-gate NL | nl NL
1807c478bd9Sstevel@tonic-gate ;
1817c478bd9Sstevel@tonic-gate
1827c478bd9Sstevel@tonic-gate opt_nl:
1837c478bd9Sstevel@tonic-gate /* empty */ { $$ = 0; }
1847c478bd9Sstevel@tonic-gate | nl
1857c478bd9Sstevel@tonic-gate ;
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate opt_pst:
1887c478bd9Sstevel@tonic-gate /* empty */ { $$ = 0; }
1897c478bd9Sstevel@tonic-gate | pst
1907c478bd9Sstevel@tonic-gate ;
1917c478bd9Sstevel@tonic-gate
1927c478bd9Sstevel@tonic-gate
1937c478bd9Sstevel@tonic-gate opt_simple_stmt:
1947c478bd9Sstevel@tonic-gate /* empty */ { $$ = 0; }
1957c478bd9Sstevel@tonic-gate | simple_stmt
1967c478bd9Sstevel@tonic-gate ;
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate pas:
1997c478bd9Sstevel@tonic-gate opt_pst { $$ = 0; }
2007c478bd9Sstevel@tonic-gate | opt_pst pa_stats opt_pst { $$ = $2; }
2017c478bd9Sstevel@tonic-gate ;
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate pa_pat:
2047c478bd9Sstevel@tonic-gate pattern { $$ = notnull($1); }
2057c478bd9Sstevel@tonic-gate ;
2067c478bd9Sstevel@tonic-gate
2077c478bd9Sstevel@tonic-gate pa_stat:
2087c478bd9Sstevel@tonic-gate pa_pat { $$ = stat2(PASTAT, $1, stat2(PRINT, rectonode(), NIL)); }
2097c478bd9Sstevel@tonic-gate | pa_pat lbrace stmtlist '}' { $$ = stat2(PASTAT, $1, $3); }
210*3ee4fc2aSCody Peter Mello | pa_pat ',' opt_nl pa_pat { $$ = pa2stat($1, $4, stat2(PRINT, rectonode(), NIL)); }
211*3ee4fc2aSCody Peter Mello | pa_pat ',' opt_nl pa_pat lbrace stmtlist '}' { $$ = pa2stat($1, $4, $6); }
2127c478bd9Sstevel@tonic-gate | lbrace stmtlist '}' { $$ = stat2(PASTAT, NIL, $2); }
2137c478bd9Sstevel@tonic-gate | XBEGIN lbrace stmtlist '}'
2147c478bd9Sstevel@tonic-gate { beginloc = linkum(beginloc, $3); $$ = 0; }
2157c478bd9Sstevel@tonic-gate | XEND lbrace stmtlist '}'
2167c478bd9Sstevel@tonic-gate { endloc = linkum(endloc, $3); $$ = 0; }
2177c478bd9Sstevel@tonic-gate | FUNC funcname '(' varlist rparen {infunc++;} lbrace stmtlist '}'
2187c478bd9Sstevel@tonic-gate { infunc--; curfname=0; defn((Cell *)$2, $4, $8); $$ = 0; }
2197c478bd9Sstevel@tonic-gate ;
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate pa_stats:
2227c478bd9Sstevel@tonic-gate pa_stat
2237c478bd9Sstevel@tonic-gate | pa_stats opt_pst pa_stat { $$ = linkum($1, $3); }
2247c478bd9Sstevel@tonic-gate ;
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate patlist:
2277c478bd9Sstevel@tonic-gate pattern
228*3ee4fc2aSCody Peter Mello | patlist comma pattern { $$ = linkum($1, $3); }
2297c478bd9Sstevel@tonic-gate ;
2307c478bd9Sstevel@tonic-gate
2317c478bd9Sstevel@tonic-gate ppattern:
2327c478bd9Sstevel@tonic-gate var ASGNOP ppattern { $$ = op2($2, $1, $3); }
2337c478bd9Sstevel@tonic-gate | ppattern '?' ppattern ':' ppattern %prec '?'
234*3ee4fc2aSCody Peter Mello { $$ = op3(CONDEXPR, notnull($1), $3, $5); }
2357c478bd9Sstevel@tonic-gate | ppattern bor ppattern %prec BOR
2367c478bd9Sstevel@tonic-gate { $$ = op2(BOR, notnull($1), notnull($3)); }
2377c478bd9Sstevel@tonic-gate | ppattern and ppattern %prec AND
2387c478bd9Sstevel@tonic-gate { $$ = op2(AND, notnull($1), notnull($3)); }
2397c478bd9Sstevel@tonic-gate | ppattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
2407c478bd9Sstevel@tonic-gate | ppattern MATCHOP ppattern
2417c478bd9Sstevel@tonic-gate { if (constnode($3))
2427c478bd9Sstevel@tonic-gate $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
2437c478bd9Sstevel@tonic-gate else
2447c478bd9Sstevel@tonic-gate $$ = op3($2, (Node *)1, $1, $3); }
2457c478bd9Sstevel@tonic-gate | ppattern IN varname { $$ = op2(INTEST, $1, makearr($3)); }
2467c478bd9Sstevel@tonic-gate | '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); }
2477c478bd9Sstevel@tonic-gate | ppattern term %prec CAT { $$ = op2(CAT, $1, $2); }
248*3ee4fc2aSCody Peter Mello | re
2497c478bd9Sstevel@tonic-gate | term
2507c478bd9Sstevel@tonic-gate ;
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate pattern:
2537c478bd9Sstevel@tonic-gate var ASGNOP pattern { $$ = op2($2, $1, $3); }
2547c478bd9Sstevel@tonic-gate | pattern '?' pattern ':' pattern %prec '?'
255*3ee4fc2aSCody Peter Mello { $$ = op3(CONDEXPR, notnull($1), $3, $5); }
2567c478bd9Sstevel@tonic-gate | pattern bor pattern %prec BOR
2577c478bd9Sstevel@tonic-gate { $$ = op2(BOR, notnull($1), notnull($3)); }
2587c478bd9Sstevel@tonic-gate | pattern and pattern %prec AND
2597c478bd9Sstevel@tonic-gate { $$ = op2(AND, notnull($1), notnull($3)); }
2607c478bd9Sstevel@tonic-gate | pattern EQ pattern { $$ = op2($2, $1, $3); }
2617c478bd9Sstevel@tonic-gate | pattern GE pattern { $$ = op2($2, $1, $3); }
2627c478bd9Sstevel@tonic-gate | pattern GT pattern { $$ = op2($2, $1, $3); }
2637c478bd9Sstevel@tonic-gate | pattern LE pattern { $$ = op2($2, $1, $3); }
2647c478bd9Sstevel@tonic-gate | pattern LT pattern { $$ = op2($2, $1, $3); }
2657c478bd9Sstevel@tonic-gate | pattern NE pattern { $$ = op2($2, $1, $3); }
2667c478bd9Sstevel@tonic-gate | pattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
2677c478bd9Sstevel@tonic-gate | pattern MATCHOP pattern
2687c478bd9Sstevel@tonic-gate { if (constnode($3))
2697c478bd9Sstevel@tonic-gate $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
2707c478bd9Sstevel@tonic-gate else
2717c478bd9Sstevel@tonic-gate $$ = op3($2, (Node *)1, $1, $3); }
2727c478bd9Sstevel@tonic-gate | pattern IN varname { $$ = op2(INTEST, $1, makearr($3)); }
2737c478bd9Sstevel@tonic-gate | '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); }
274*3ee4fc2aSCody Peter Mello | pattern '|' GETLINE var {
275*3ee4fc2aSCody Peter Mello if (safe) SYNTAX("cmd | getline is unsafe");
276*3ee4fc2aSCody Peter Mello else $$ = op3(GETLINE, $4, itonp($2), $1); }
277*3ee4fc2aSCody Peter Mello | pattern '|' GETLINE {
278*3ee4fc2aSCody Peter Mello if (safe) SYNTAX("cmd | getline is unsafe");
279*3ee4fc2aSCody Peter Mello else $$ = op3(GETLINE, (Node*)0, itonp($2), $1); }
2807c478bd9Sstevel@tonic-gate | pattern term %prec CAT { $$ = op2(CAT, $1, $2); }
281*3ee4fc2aSCody Peter Mello | re
2827c478bd9Sstevel@tonic-gate | term
2837c478bd9Sstevel@tonic-gate ;
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate plist:
2867c478bd9Sstevel@tonic-gate pattern comma pattern { $$ = linkum($1, $3); }
2877c478bd9Sstevel@tonic-gate | plist comma pattern { $$ = linkum($1, $3); }
2887c478bd9Sstevel@tonic-gate ;
2897c478bd9Sstevel@tonic-gate
2907c478bd9Sstevel@tonic-gate pplist:
2917c478bd9Sstevel@tonic-gate ppattern
2927c478bd9Sstevel@tonic-gate | pplist comma ppattern { $$ = linkum($1, $3); }
293*3ee4fc2aSCody Peter Mello ;
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate prarg:
2967c478bd9Sstevel@tonic-gate /* empty */ { $$ = rectonode(); }
2977c478bd9Sstevel@tonic-gate | pplist
2987c478bd9Sstevel@tonic-gate | '(' plist ')' { $$ = $2; }
2997c478bd9Sstevel@tonic-gate ;
3007c478bd9Sstevel@tonic-gate
3017c478bd9Sstevel@tonic-gate print:
3027c478bd9Sstevel@tonic-gate PRINT | PRINTF
3037c478bd9Sstevel@tonic-gate ;
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate pst:
3067c478bd9Sstevel@tonic-gate NL | ';' | pst NL | pst ';'
3077c478bd9Sstevel@tonic-gate ;
3087c478bd9Sstevel@tonic-gate
3097c478bd9Sstevel@tonic-gate rbrace:
3107c478bd9Sstevel@tonic-gate '}' | rbrace NL
3117c478bd9Sstevel@tonic-gate ;
3127c478bd9Sstevel@tonic-gate
313*3ee4fc2aSCody Peter Mello re:
314*3ee4fc2aSCody Peter Mello reg_expr
315*3ee4fc2aSCody Peter Mello { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); }
316*3ee4fc2aSCody Peter Mello | NOT re { $$ = op1(NOT, notnull($2)); }
317*3ee4fc2aSCody Peter Mello ;
318*3ee4fc2aSCody Peter Mello
3197c478bd9Sstevel@tonic-gate reg_expr:
3207c478bd9Sstevel@tonic-gate '/' {startreg();} REGEXPR '/' { $$ = $3; }
3217c478bd9Sstevel@tonic-gate ;
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate rparen:
3247c478bd9Sstevel@tonic-gate ')' | rparen NL
3257c478bd9Sstevel@tonic-gate ;
3267c478bd9Sstevel@tonic-gate
3277c478bd9Sstevel@tonic-gate simple_stmt:
328*3ee4fc2aSCody Peter Mello print prarg '|' term {
329*3ee4fc2aSCody Peter Mello if (safe) SYNTAX("print | is unsafe");
330*3ee4fc2aSCody Peter Mello else $$ = stat3($1, $2, itonp($3), $4); }
331*3ee4fc2aSCody Peter Mello | print prarg APPEND term {
332*3ee4fc2aSCody Peter Mello if (safe) SYNTAX("print >> is unsafe");
333*3ee4fc2aSCody Peter Mello else $$ = stat3($1, $2, itonp($3), $4); }
334*3ee4fc2aSCody Peter Mello | print prarg GT term {
335*3ee4fc2aSCody Peter Mello if (safe) SYNTAX("print > is unsafe");
336*3ee4fc2aSCody Peter Mello else $$ = stat3($1, $2, itonp($3), $4); }
3377c478bd9Sstevel@tonic-gate | print prarg { $$ = stat3($1, $2, NIL, NIL); }
3387c478bd9Sstevel@tonic-gate | DELETE varname '[' patlist ']' { $$ = stat2(DELETE, makearr($2), $4); }
339*3ee4fc2aSCody Peter Mello | DELETE varname { $$ = stat2(DELETE, makearr($2), 0); }
3407c478bd9Sstevel@tonic-gate | pattern { $$ = exptostat($1); }
341*3ee4fc2aSCody Peter Mello | error { yyclearin; SYNTAX("illegal statement"); }
3427c478bd9Sstevel@tonic-gate ;
3437c478bd9Sstevel@tonic-gate
3447c478bd9Sstevel@tonic-gate st:
345*3ee4fc2aSCody Peter Mello nl
346*3ee4fc2aSCody Peter Mello | ';' opt_nl
3477c478bd9Sstevel@tonic-gate ;
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate stmt:
350*3ee4fc2aSCody Peter Mello BREAK st { if (!inloop) SYNTAX("break illegal outside of loops");
351*3ee4fc2aSCody Peter Mello $$ = stat1(BREAK, NIL); }
352*3ee4fc2aSCody Peter Mello | CONTINUE st { if (!inloop) SYNTAX("continue illegal outside of loops");
353*3ee4fc2aSCody Peter Mello $$ = stat1(CONTINUE, NIL); }
354*3ee4fc2aSCody Peter Mello | do {inloop++;} stmt {--inloop;} WHILE '(' pattern ')' st
355*3ee4fc2aSCody Peter Mello { $$ = stat2(DO, $3, notnull($7)); }
3567c478bd9Sstevel@tonic-gate | EXIT pattern st { $$ = stat1(EXIT, $2); }
3577c478bd9Sstevel@tonic-gate | EXIT st { $$ = stat1(EXIT, NIL); }
3587c478bd9Sstevel@tonic-gate | for
3597c478bd9Sstevel@tonic-gate | if stmt else stmt { $$ = stat3(IF, $1, $2, $4); }
3607c478bd9Sstevel@tonic-gate | if stmt { $$ = stat3(IF, $1, $2, NIL); }
3617c478bd9Sstevel@tonic-gate | lbrace stmtlist rbrace { $$ = $2; }
3627c478bd9Sstevel@tonic-gate | NEXT st { if (infunc)
363*3ee4fc2aSCody Peter Mello SYNTAX("next is illegal inside a function");
3647c478bd9Sstevel@tonic-gate $$ = stat1(NEXT, NIL); }
365*3ee4fc2aSCody Peter Mello | NEXTFILE st { if (infunc)
366*3ee4fc2aSCody Peter Mello SYNTAX("nextfile is illegal inside a function");
367*3ee4fc2aSCody Peter Mello $$ = stat1(NEXTFILE, NIL); }
3687c478bd9Sstevel@tonic-gate | RETURN pattern st { $$ = stat1(RETURN, $2); }
3697c478bd9Sstevel@tonic-gate | RETURN st { $$ = stat1(RETURN, NIL); }
3707c478bd9Sstevel@tonic-gate | simple_stmt st
371*3ee4fc2aSCody Peter Mello | while {inloop++;} stmt { --inloop; $$ = stat2(WHILE, $1, $3); }
3727c478bd9Sstevel@tonic-gate | ';' opt_nl { $$ = 0; }
3737c478bd9Sstevel@tonic-gate ;
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate stmtlist:
3767c478bd9Sstevel@tonic-gate stmt
3777c478bd9Sstevel@tonic-gate | stmtlist stmt { $$ = linkum($1, $2); }
3787c478bd9Sstevel@tonic-gate ;
3797c478bd9Sstevel@tonic-gate
3807c478bd9Sstevel@tonic-gate subop:
3817c478bd9Sstevel@tonic-gate SUB | GSUB
3827c478bd9Sstevel@tonic-gate ;
3837c478bd9Sstevel@tonic-gate
3847c478bd9Sstevel@tonic-gate term:
385*3ee4fc2aSCody Peter Mello term '/' ASGNOP term { $$ = op2(DIVEQ, $1, $4); }
386*3ee4fc2aSCody Peter Mello | term '+' term { $$ = op2(ADD, $1, $3); }
3877c478bd9Sstevel@tonic-gate | term '-' term { $$ = op2(MINUS, $1, $3); }
3887c478bd9Sstevel@tonic-gate | term '*' term { $$ = op2(MULT, $1, $3); }
3897c478bd9Sstevel@tonic-gate | term '/' term { $$ = op2(DIVIDE, $1, $3); }
3907c478bd9Sstevel@tonic-gate | term '%' term { $$ = op2(MOD, $1, $3); }
3917c478bd9Sstevel@tonic-gate | term POWER term { $$ = op2(POWER, $1, $3); }
3927c478bd9Sstevel@tonic-gate | '-' term %prec UMINUS { $$ = op1(UMINUS, $2); }
393*3ee4fc2aSCody Peter Mello | '+' term %prec UMINUS { $$ = op1(UPLUS, $2); }
394*3ee4fc2aSCody Peter Mello | NOT term %prec UMINUS { $$ = op1(NOT, notnull($2)); }
395*3ee4fc2aSCody Peter Mello | BLTIN '(' ')' { $$ = op2(BLTIN, itonp($1), rectonode()); }
396*3ee4fc2aSCody Peter Mello | BLTIN '(' patlist ')' { $$ = op2(BLTIN, itonp($1), $3); }
397*3ee4fc2aSCody Peter Mello | BLTIN { $$ = op2(BLTIN, itonp($1), rectonode()); }
398*3ee4fc2aSCody Peter Mello | CALL '(' ')' { $$ = op2(CALL, celltonode($1,CVAR), NIL); }
399*3ee4fc2aSCody Peter Mello | CALL '(' patlist ')' { $$ = op2(CALL, celltonode($1,CVAR), $3); }
400*3ee4fc2aSCody Peter Mello | CLOSE term { $$ = op1(CLOSE, $2); }
4017c478bd9Sstevel@tonic-gate | DECR var { $$ = op1(PREDECR, $2); }
4027c478bd9Sstevel@tonic-gate | INCR var { $$ = op1(PREINCR, $2); }
4037c478bd9Sstevel@tonic-gate | var DECR { $$ = op1(POSTDECR, $1); }
4047c478bd9Sstevel@tonic-gate | var INCR { $$ = op1(POSTINCR, $1); }
405*3ee4fc2aSCody Peter Mello | GETLINE var LT term { $$ = op3(GETLINE, $2, itonp($3), $4); }
406*3ee4fc2aSCody Peter Mello | GETLINE LT term { $$ = op3(GETLINE, NIL, itonp($2), $3); }
4077c478bd9Sstevel@tonic-gate | GETLINE var { $$ = op3(GETLINE, $2, NIL, NIL); }
4087c478bd9Sstevel@tonic-gate | GETLINE { $$ = op3(GETLINE, NIL, NIL, NIL); }
4097c478bd9Sstevel@tonic-gate | INDEX '(' pattern comma pattern ')'
4107c478bd9Sstevel@tonic-gate { $$ = op2(INDEX, $3, $5); }
4117c478bd9Sstevel@tonic-gate | INDEX '(' pattern comma reg_expr ')'
412*3ee4fc2aSCody Peter Mello { SYNTAX("index() doesn't permit regular expressions");
4137c478bd9Sstevel@tonic-gate $$ = op2(INDEX, $3, (Node*)$5); }
4147c478bd9Sstevel@tonic-gate | '(' pattern ')' { $$ = $2; }
4157c478bd9Sstevel@tonic-gate | MATCHFCN '(' pattern comma reg_expr ')'
4167c478bd9Sstevel@tonic-gate { $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa($5, 1)); }
4177c478bd9Sstevel@tonic-gate | MATCHFCN '(' pattern comma pattern ')'
4187c478bd9Sstevel@tonic-gate { if (constnode($5))
4197c478bd9Sstevel@tonic-gate $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa(strnode($5), 1));
4207c478bd9Sstevel@tonic-gate else
4217c478bd9Sstevel@tonic-gate $$ = op3(MATCHFCN, (Node *)1, $3, $5); }
422*3ee4fc2aSCody Peter Mello | NUMBER { $$ = celltonode($1, CCON); }
4237c478bd9Sstevel@tonic-gate | SPLIT '(' pattern comma varname comma pattern ')' /* string */
4247c478bd9Sstevel@tonic-gate { $$ = op4(SPLIT, $3, makearr($5), $7, (Node*)STRING); }
4257c478bd9Sstevel@tonic-gate | SPLIT '(' pattern comma varname comma reg_expr ')' /* const /regexp/ */
4267c478bd9Sstevel@tonic-gate { $$ = op4(SPLIT, $3, makearr($5), (Node*)makedfa($7, 1), (Node *)REGEXPR); }
4277c478bd9Sstevel@tonic-gate | SPLIT '(' pattern comma varname ')'
4287c478bd9Sstevel@tonic-gate { $$ = op4(SPLIT, $3, makearr($5), NIL, (Node*)STRING); } /* default */
4297c478bd9Sstevel@tonic-gate | SPRINTF '(' patlist ')' { $$ = op1($1, $3); }
430*3ee4fc2aSCody Peter Mello | STRING { $$ = celltonode($1, CCON); }
4317c478bd9Sstevel@tonic-gate | subop '(' reg_expr comma pattern ')'
4327c478bd9Sstevel@tonic-gate { $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, rectonode()); }
4337c478bd9Sstevel@tonic-gate | subop '(' pattern comma pattern ')'
4347c478bd9Sstevel@tonic-gate { if (constnode($3))
4357c478bd9Sstevel@tonic-gate $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, rectonode());
4367c478bd9Sstevel@tonic-gate else
4377c478bd9Sstevel@tonic-gate $$ = op4($1, (Node *)1, $3, $5, rectonode()); }
4387c478bd9Sstevel@tonic-gate | subop '(' reg_expr comma pattern comma var ')'
4397c478bd9Sstevel@tonic-gate { $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, $7); }
4407c478bd9Sstevel@tonic-gate | subop '(' pattern comma pattern comma var ')'
4417c478bd9Sstevel@tonic-gate { if (constnode($3))
4427c478bd9Sstevel@tonic-gate $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, $7);
4437c478bd9Sstevel@tonic-gate else
4447c478bd9Sstevel@tonic-gate $$ = op4($1, (Node *)1, $3, $5, $7); }
4457c478bd9Sstevel@tonic-gate | SUBSTR '(' pattern comma pattern comma pattern ')'
4467c478bd9Sstevel@tonic-gate { $$ = op3(SUBSTR, $3, $5, $7); }
4477c478bd9Sstevel@tonic-gate | SUBSTR '(' pattern comma pattern ')'
4487c478bd9Sstevel@tonic-gate { $$ = op3(SUBSTR, $3, $5, NIL); }
4497c478bd9Sstevel@tonic-gate | var
4507c478bd9Sstevel@tonic-gate ;
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate var:
4537c478bd9Sstevel@tonic-gate varname
4547c478bd9Sstevel@tonic-gate | varname '[' patlist ']' { $$ = op2(ARRAY, makearr($1), $3); }
455*3ee4fc2aSCody Peter Mello | IVAR { $$ = op1(INDIRECT, celltonode($1, CVAR)); }
456*3ee4fc2aSCody Peter Mello | INDIRECT term { $$ = op1(INDIRECT, $2); }
457*3ee4fc2aSCody Peter Mello ;
4587c478bd9Sstevel@tonic-gate
4597c478bd9Sstevel@tonic-gate varlist:
4607c478bd9Sstevel@tonic-gate /* nothing */ { arglist = $$ = 0; }
461*3ee4fc2aSCody Peter Mello | VAR { arglist = $$ = celltonode($1,CVAR); }
462*3ee4fc2aSCody Peter Mello | varlist comma VAR {
463*3ee4fc2aSCody Peter Mello checkdup($1, $3);
464*3ee4fc2aSCody Peter Mello arglist = $$ = linkum($1,celltonode($3,CVAR)); }
4657c478bd9Sstevel@tonic-gate ;
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate varname:
468*3ee4fc2aSCody Peter Mello VAR { $$ = celltonode($1, CVAR); }
469*3ee4fc2aSCody Peter Mello | ARG { $$ = op1(ARG, itonp($1)); }
4707c478bd9Sstevel@tonic-gate | VARNF { $$ = op1(VARNF, (Node *) $1); }
4717c478bd9Sstevel@tonic-gate ;
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate
4747c478bd9Sstevel@tonic-gate while:
4757c478bd9Sstevel@tonic-gate WHILE '(' pattern rparen { $$ = notnull($3); }
4767c478bd9Sstevel@tonic-gate ;
4777c478bd9Sstevel@tonic-gate
4787c478bd9Sstevel@tonic-gate %%
4797c478bd9Sstevel@tonic-gate
4801ee2e5faSnakanon static void
4811ee2e5faSnakanon setfname(Cell *p)
4827c478bd9Sstevel@tonic-gate {
4837c478bd9Sstevel@tonic-gate if (isarr(p))
484*3ee4fc2aSCody Peter Mello SYNTAX("%s is an array, not a function", p->nval);
485*3ee4fc2aSCody Peter Mello else if (isfcn(p))
486*3ee4fc2aSCody Peter Mello SYNTAX("you can't define function %s more than once", p->nval);
4877c478bd9Sstevel@tonic-gate curfname = p->nval;
488*3ee4fc2aSCody Peter Mello p->tval |= FCN;
4897c478bd9Sstevel@tonic-gate }
4907c478bd9Sstevel@tonic-gate
4911ee2e5faSnakanon static int
4921ee2e5faSnakanon constnode(Node *p)
4937c478bd9Sstevel@tonic-gate {
494*3ee4fc2aSCody Peter Mello return isvalue(p) && ((Cell *) (p->narg[0]))->csub == CCON;
4957c478bd9Sstevel@tonic-gate }
4967c478bd9Sstevel@tonic-gate
497*3ee4fc2aSCody Peter Mello static char *
4981ee2e5faSnakanon strnode(Node *p)
4997c478bd9Sstevel@tonic-gate {
5007c478bd9Sstevel@tonic-gate return ((Cell *)(p->narg[0]))->sval;
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate
5031ee2e5faSnakanon static Node *
5041ee2e5faSnakanon notnull(Node *n)
5057c478bd9Sstevel@tonic-gate {
5067c478bd9Sstevel@tonic-gate switch (n->nobj) {
5077c478bd9Sstevel@tonic-gate case LE: case LT: case EQ: case NE: case GT: case GE:
5087c478bd9Sstevel@tonic-gate case BOR: case AND: case NOT:
5097c478bd9Sstevel@tonic-gate return n;
5107c478bd9Sstevel@tonic-gate default:
5117c478bd9Sstevel@tonic-gate return op2(NE, n, nullnode);
5127c478bd9Sstevel@tonic-gate }
5137c478bd9Sstevel@tonic-gate }
514*3ee4fc2aSCody Peter Mello
515*3ee4fc2aSCody Peter Mello void
516*3ee4fc2aSCody Peter Mello checkdup(Node *vl, Cell *cp) /* check if name already in list */
517*3ee4fc2aSCody Peter Mello {
518*3ee4fc2aSCody Peter Mello char *s = cp->nval;
519*3ee4fc2aSCody Peter Mello for (; vl; vl = vl->nnext) {
520*3ee4fc2aSCody Peter Mello if (strcmp(s, ((Cell *)(vl->narg[0]))->nval) == 0) {
521*3ee4fc2aSCody Peter Mello SYNTAX("duplicate argument %s", s);
522*3ee4fc2aSCody Peter Mello break;
523*3ee4fc2aSCody Peter Mello }
524*3ee4fc2aSCody Peter Mello }
525*3ee4fc2aSCody Peter Mello }
526