1*7c478bd9Sstevel@tonic-gate %{ 2*7c478bd9Sstevel@tonic-gate /* 3*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 4*7c478bd9Sstevel@tonic-gate * 5*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 6*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 7*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 8*7c478bd9Sstevel@tonic-gate * with the License. 9*7c478bd9Sstevel@tonic-gate * 10*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 12*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 13*7c478bd9Sstevel@tonic-gate * and limitations under the License. 14*7c478bd9Sstevel@tonic-gate * 15*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 16*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 18*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 19*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 20*7c478bd9Sstevel@tonic-gate * 21*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 22*7c478bd9Sstevel@tonic-gate */ 23*7c478bd9Sstevel@tonic-gate %} 24*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 25*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate %{ 29*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.10 */ 30*7c478bd9Sstevel@tonic-gate %} 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate %{ 33*7c478bd9Sstevel@tonic-gate #include "awk.h" 34*7c478bd9Sstevel@tonic-gate yywrap() { return(1); } 35*7c478bd9Sstevel@tonic-gate #ifndef DEBUG 36*7c478bd9Sstevel@tonic-gate # define PUTS(x) 37*7c478bd9Sstevel@tonic-gate #endif 38*7c478bd9Sstevel@tonic-gate Node *beginloc = 0, *endloc = 0; 39*7c478bd9Sstevel@tonic-gate int infunc = 0; /* = 1 if in arglist or body of func */ 40*7c478bd9Sstevel@tonic-gate uchar *curfname = 0; 41*7c478bd9Sstevel@tonic-gate Node *arglist = 0; /* list of args for current function */ 42*7c478bd9Sstevel@tonic-gate uchar *strnode(); 43*7c478bd9Sstevel@tonic-gate Node *notnull(); 44*7c478bd9Sstevel@tonic-gate %} 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate %union { 47*7c478bd9Sstevel@tonic-gate Node *p; 48*7c478bd9Sstevel@tonic-gate Cell *cp; 49*7c478bd9Sstevel@tonic-gate int i; 50*7c478bd9Sstevel@tonic-gate uchar *s; 51*7c478bd9Sstevel@tonic-gate } 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate %token <i> FIRSTTOKEN /* must be first */ 54*7c478bd9Sstevel@tonic-gate %token <p> PROGRAM PASTAT PASTAT2 XBEGIN XEND 55*7c478bd9Sstevel@tonic-gate %token <i> NL ',' '{' '(' '|' ';' '/' ')' '}' '[' ']' 56*7c478bd9Sstevel@tonic-gate %token <i> ARRAY 57*7c478bd9Sstevel@tonic-gate %token <i> MATCH NOTMATCH MATCHOP 58*7c478bd9Sstevel@tonic-gate %token <i> FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS 59*7c478bd9Sstevel@tonic-gate %token <i> AND BOR APPEND EQ GE GT LE LT NE IN 60*7c478bd9Sstevel@tonic-gate %token <i> ARG BLTIN BREAK CLOSE CONTINUE DELETE DO EXIT FOR FUNC 61*7c478bd9Sstevel@tonic-gate %token <i> SUB GSUB IF INDEX LSUBSTR MATCHFCN NEXT 62*7c478bd9Sstevel@tonic-gate %token <i> ADD MINUS MULT DIVIDE MOD 63*7c478bd9Sstevel@tonic-gate %token <i> ASSIGN ASGNOP ADDEQ SUBEQ MULTEQ DIVEQ MODEQ POWEQ 64*7c478bd9Sstevel@tonic-gate %token <i> PRINT PRINTF SPRINTF 65*7c478bd9Sstevel@tonic-gate %token <p> ELSE INTEST CONDEXPR 66*7c478bd9Sstevel@tonic-gate %token <i> POSTINCR PREINCR POSTDECR PREDECR 67*7c478bd9Sstevel@tonic-gate %token <cp> VAR IVAR VARNF CALL NUMBER STRING FIELD 68*7c478bd9Sstevel@tonic-gate %token <s> REGEXPR 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate %type <p> pas pattern ppattern plist pplist patlist prarg term 71*7c478bd9Sstevel@tonic-gate %type <p> pa_pat pa_stat pa_stats 72*7c478bd9Sstevel@tonic-gate %type <s> reg_expr 73*7c478bd9Sstevel@tonic-gate %type <p> simple_stmt opt_simple_stmt stmt stmtlist 74*7c478bd9Sstevel@tonic-gate %type <p> var varname funcname varlist 75*7c478bd9Sstevel@tonic-gate %type <p> for if while 76*7c478bd9Sstevel@tonic-gate %type <i> pst opt_pst lbrace rparen comma nl opt_nl and bor 77*7c478bd9Sstevel@tonic-gate %type <i> subop print 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate %right ASGNOP 80*7c478bd9Sstevel@tonic-gate %right '?' 81*7c478bd9Sstevel@tonic-gate %right ':' 82*7c478bd9Sstevel@tonic-gate %left BOR 83*7c478bd9Sstevel@tonic-gate %left AND 84*7c478bd9Sstevel@tonic-gate %left GETLINE 85*7c478bd9Sstevel@tonic-gate %nonassoc APPEND EQ GE GT LE LT NE MATCHOP IN '|' 86*7c478bd9Sstevel@tonic-gate %left ARG BLTIN BREAK CALL CLOSE CONTINUE DELETE DO EXIT FOR FIELD FUNC 87*7c478bd9Sstevel@tonic-gate %left GSUB IF INDEX LSUBSTR MATCHFCN NEXT NUMBER 88*7c478bd9Sstevel@tonic-gate %left PRINT PRINTF RETURN SPLIT SPRINTF STRING SUB SUBSTR 89*7c478bd9Sstevel@tonic-gate %left REGEXPR VAR VARNF IVAR WHILE '(' 90*7c478bd9Sstevel@tonic-gate %left CAT 91*7c478bd9Sstevel@tonic-gate %left '+' '-' 92*7c478bd9Sstevel@tonic-gate %left '*' '/' '%' 93*7c478bd9Sstevel@tonic-gate %left NOT UMINUS 94*7c478bd9Sstevel@tonic-gate %right POWER 95*7c478bd9Sstevel@tonic-gate %right DECR INCR 96*7c478bd9Sstevel@tonic-gate %left INDIRECT 97*7c478bd9Sstevel@tonic-gate %token LASTTOKEN /* must be last */ 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate %% 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate program: 102*7c478bd9Sstevel@tonic-gate pas { if (errorflag==0) 103*7c478bd9Sstevel@tonic-gate winner = (Node *)stat3(PROGRAM, beginloc, $1, endloc); } 104*7c478bd9Sstevel@tonic-gate | error { yyclearin; bracecheck(); ERROR "bailing out" SYNTAX; } 105*7c478bd9Sstevel@tonic-gate ; 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate and: 108*7c478bd9Sstevel@tonic-gate AND | and NL 109*7c478bd9Sstevel@tonic-gate ; 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate bor: 112*7c478bd9Sstevel@tonic-gate BOR | bor NL 113*7c478bd9Sstevel@tonic-gate ; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate comma: 116*7c478bd9Sstevel@tonic-gate ',' | comma NL 117*7c478bd9Sstevel@tonic-gate ; 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate do: 120*7c478bd9Sstevel@tonic-gate DO | do NL 121*7c478bd9Sstevel@tonic-gate ; 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate else: 124*7c478bd9Sstevel@tonic-gate ELSE | else NL 125*7c478bd9Sstevel@tonic-gate ; 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate for: 128*7c478bd9Sstevel@tonic-gate FOR '(' opt_simple_stmt ';' pattern ';' opt_simple_stmt rparen stmt 129*7c478bd9Sstevel@tonic-gate { $$ = stat4(FOR, $3, notnull($5), $7, $9); } 130*7c478bd9Sstevel@tonic-gate | FOR '(' opt_simple_stmt ';' ';' opt_simple_stmt rparen stmt 131*7c478bd9Sstevel@tonic-gate { $$ = stat4(FOR, $3, NIL, $6, $8); } 132*7c478bd9Sstevel@tonic-gate | FOR '(' varname IN varname rparen stmt 133*7c478bd9Sstevel@tonic-gate { $$ = stat3(IN, $3, makearr($5), $7); } 134*7c478bd9Sstevel@tonic-gate ; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate funcname: 137*7c478bd9Sstevel@tonic-gate VAR { setfname($1); } 138*7c478bd9Sstevel@tonic-gate | CALL { setfname($1); } 139*7c478bd9Sstevel@tonic-gate ; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate if: 142*7c478bd9Sstevel@tonic-gate IF '(' pattern rparen { $$ = notnull($3); } 143*7c478bd9Sstevel@tonic-gate ; 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate lbrace: 146*7c478bd9Sstevel@tonic-gate '{' | lbrace NL 147*7c478bd9Sstevel@tonic-gate ; 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate nl: 150*7c478bd9Sstevel@tonic-gate NL | nl NL 151*7c478bd9Sstevel@tonic-gate ; 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate opt_nl: 154*7c478bd9Sstevel@tonic-gate /* empty */ { $$ = 0; } 155*7c478bd9Sstevel@tonic-gate | nl 156*7c478bd9Sstevel@tonic-gate ; 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate opt_pst: 159*7c478bd9Sstevel@tonic-gate /* empty */ { $$ = 0; } 160*7c478bd9Sstevel@tonic-gate | pst 161*7c478bd9Sstevel@tonic-gate ; 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate opt_simple_stmt: 165*7c478bd9Sstevel@tonic-gate /* empty */ { $$ = 0; } 166*7c478bd9Sstevel@tonic-gate | simple_stmt 167*7c478bd9Sstevel@tonic-gate ; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate pas: 170*7c478bd9Sstevel@tonic-gate opt_pst { $$ = 0; } 171*7c478bd9Sstevel@tonic-gate | opt_pst pa_stats opt_pst { $$ = $2; } 172*7c478bd9Sstevel@tonic-gate ; 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate pa_pat: 175*7c478bd9Sstevel@tonic-gate pattern { $$ = notnull($1); } 176*7c478bd9Sstevel@tonic-gate ; 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate pa_stat: 179*7c478bd9Sstevel@tonic-gate pa_pat { $$ = stat2(PASTAT, $1, stat2(PRINT, rectonode(), NIL)); } 180*7c478bd9Sstevel@tonic-gate | pa_pat lbrace stmtlist '}' { $$ = stat2(PASTAT, $1, $3); } 181*7c478bd9Sstevel@tonic-gate | pa_pat ',' pa_pat { $$ = pa2stat($1, $3, stat2(PRINT, rectonode(), NIL)); } 182*7c478bd9Sstevel@tonic-gate | pa_pat ',' pa_pat lbrace stmtlist '}' { $$ = pa2stat($1, $3, $5); } 183*7c478bd9Sstevel@tonic-gate | lbrace stmtlist '}' { $$ = stat2(PASTAT, NIL, $2); } 184*7c478bd9Sstevel@tonic-gate | XBEGIN lbrace stmtlist '}' 185*7c478bd9Sstevel@tonic-gate { beginloc = linkum(beginloc, $3); $$ = 0; } 186*7c478bd9Sstevel@tonic-gate | XEND lbrace stmtlist '}' 187*7c478bd9Sstevel@tonic-gate { endloc = linkum(endloc, $3); $$ = 0; } 188*7c478bd9Sstevel@tonic-gate | FUNC funcname '(' varlist rparen {infunc++;} lbrace stmtlist '}' 189*7c478bd9Sstevel@tonic-gate { infunc--; curfname=0; defn((Cell *)$2, $4, $8); $$ = 0; } 190*7c478bd9Sstevel@tonic-gate ; 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate pa_stats: 193*7c478bd9Sstevel@tonic-gate pa_stat 194*7c478bd9Sstevel@tonic-gate | pa_stats opt_pst pa_stat { $$ = linkum($1, $3); } 195*7c478bd9Sstevel@tonic-gate ; 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate patlist: 198*7c478bd9Sstevel@tonic-gate pattern 199*7c478bd9Sstevel@tonic-gate | patlist comma pattern { $$ = linkum($1, $3); } 200*7c478bd9Sstevel@tonic-gate ; 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate ppattern: 203*7c478bd9Sstevel@tonic-gate var ASGNOP ppattern { $$ = op2($2, $1, $3); } 204*7c478bd9Sstevel@tonic-gate | ppattern '?' ppattern ':' ppattern %prec '?' 205*7c478bd9Sstevel@tonic-gate { $$ = op3(CONDEXPR, notnull($1), $3, $5); } 206*7c478bd9Sstevel@tonic-gate | ppattern bor ppattern %prec BOR 207*7c478bd9Sstevel@tonic-gate { $$ = op2(BOR, notnull($1), notnull($3)); } 208*7c478bd9Sstevel@tonic-gate | ppattern and ppattern %prec AND 209*7c478bd9Sstevel@tonic-gate { $$ = op2(AND, notnull($1), notnull($3)); } 210*7c478bd9Sstevel@tonic-gate | NOT ppattern 211*7c478bd9Sstevel@tonic-gate { $$ = op1(NOT, notnull($2)); } 212*7c478bd9Sstevel@tonic-gate | ppattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); } 213*7c478bd9Sstevel@tonic-gate | ppattern MATCHOP ppattern 214*7c478bd9Sstevel@tonic-gate { if (constnode($3)) 215*7c478bd9Sstevel@tonic-gate $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0)); 216*7c478bd9Sstevel@tonic-gate else 217*7c478bd9Sstevel@tonic-gate $$ = op3($2, (Node *)1, $1, $3); } 218*7c478bd9Sstevel@tonic-gate | ppattern IN varname { $$ = op2(INTEST, $1, makearr($3)); } 219*7c478bd9Sstevel@tonic-gate | '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); } 220*7c478bd9Sstevel@tonic-gate | ppattern term %prec CAT { $$ = op2(CAT, $1, $2); } 221*7c478bd9Sstevel@tonic-gate | reg_expr 222*7c478bd9Sstevel@tonic-gate { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); } 223*7c478bd9Sstevel@tonic-gate | term 224*7c478bd9Sstevel@tonic-gate ; 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate pattern: 227*7c478bd9Sstevel@tonic-gate var ASGNOP pattern { $$ = op2($2, $1, $3); } 228*7c478bd9Sstevel@tonic-gate | pattern '?' pattern ':' pattern %prec '?' 229*7c478bd9Sstevel@tonic-gate { $$ = op3(CONDEXPR, notnull($1), $3, $5); } 230*7c478bd9Sstevel@tonic-gate | pattern bor pattern %prec BOR 231*7c478bd9Sstevel@tonic-gate { $$ = op2(BOR, notnull($1), notnull($3)); } 232*7c478bd9Sstevel@tonic-gate | pattern and pattern %prec AND 233*7c478bd9Sstevel@tonic-gate { $$ = op2(AND, notnull($1), notnull($3)); } 234*7c478bd9Sstevel@tonic-gate | NOT pattern 235*7c478bd9Sstevel@tonic-gate { $$ = op1(NOT, op2(NE,$2,valtonode(lookup("$zero&null",symtab),CCON))); } 236*7c478bd9Sstevel@tonic-gate | pattern EQ pattern { $$ = op2($2, $1, $3); } 237*7c478bd9Sstevel@tonic-gate | pattern GE pattern { $$ = op2($2, $1, $3); } 238*7c478bd9Sstevel@tonic-gate | pattern GT pattern { $$ = op2($2, $1, $3); } 239*7c478bd9Sstevel@tonic-gate | pattern LE pattern { $$ = op2($2, $1, $3); } 240*7c478bd9Sstevel@tonic-gate | pattern LT pattern { $$ = op2($2, $1, $3); } 241*7c478bd9Sstevel@tonic-gate | pattern NE pattern { $$ = op2($2, $1, $3); } 242*7c478bd9Sstevel@tonic-gate | pattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); } 243*7c478bd9Sstevel@tonic-gate | pattern MATCHOP pattern 244*7c478bd9Sstevel@tonic-gate { if (constnode($3)) 245*7c478bd9Sstevel@tonic-gate $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0)); 246*7c478bd9Sstevel@tonic-gate else 247*7c478bd9Sstevel@tonic-gate $$ = op3($2, (Node *)1, $1, $3); } 248*7c478bd9Sstevel@tonic-gate | pattern IN varname { $$ = op2(INTEST, $1, makearr($3)); } 249*7c478bd9Sstevel@tonic-gate | '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); } 250*7c478bd9Sstevel@tonic-gate | pattern '|' GETLINE var { $$ = op3(GETLINE, $4, (Node*)$2, $1); } 251*7c478bd9Sstevel@tonic-gate | pattern '|' GETLINE { $$ = op3(GETLINE, (Node*)0, (Node*)$2, $1); } 252*7c478bd9Sstevel@tonic-gate | pattern term %prec CAT { $$ = op2(CAT, $1, $2); } 253*7c478bd9Sstevel@tonic-gate | reg_expr 254*7c478bd9Sstevel@tonic-gate { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); } 255*7c478bd9Sstevel@tonic-gate | term 256*7c478bd9Sstevel@tonic-gate ; 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate plist: 259*7c478bd9Sstevel@tonic-gate pattern comma pattern { $$ = linkum($1, $3); } 260*7c478bd9Sstevel@tonic-gate | plist comma pattern { $$ = linkum($1, $3); } 261*7c478bd9Sstevel@tonic-gate ; 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate pplist: 264*7c478bd9Sstevel@tonic-gate ppattern 265*7c478bd9Sstevel@tonic-gate | pplist comma ppattern { $$ = linkum($1, $3); } 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate prarg: 268*7c478bd9Sstevel@tonic-gate /* empty */ { $$ = rectonode(); } 269*7c478bd9Sstevel@tonic-gate | pplist 270*7c478bd9Sstevel@tonic-gate | '(' plist ')' { $$ = $2; } 271*7c478bd9Sstevel@tonic-gate ; 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate print: 274*7c478bd9Sstevel@tonic-gate PRINT | PRINTF 275*7c478bd9Sstevel@tonic-gate ; 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate pst: 278*7c478bd9Sstevel@tonic-gate NL | ';' | pst NL | pst ';' 279*7c478bd9Sstevel@tonic-gate ; 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate rbrace: 282*7c478bd9Sstevel@tonic-gate '}' | rbrace NL 283*7c478bd9Sstevel@tonic-gate ; 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate reg_expr: 286*7c478bd9Sstevel@tonic-gate '/' {startreg();} REGEXPR '/' { $$ = $3; } 287*7c478bd9Sstevel@tonic-gate ; 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate rparen: 290*7c478bd9Sstevel@tonic-gate ')' | rparen NL 291*7c478bd9Sstevel@tonic-gate ; 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate simple_stmt: 294*7c478bd9Sstevel@tonic-gate print prarg '|' term { $$ = stat3($1, $2, (Node *) $3, $4); } 295*7c478bd9Sstevel@tonic-gate | print prarg APPEND term { $$ = stat3($1, $2, (Node *) $3, $4); } 296*7c478bd9Sstevel@tonic-gate | print prarg GT term { $$ = stat3($1, $2, (Node *) $3, $4); } 297*7c478bd9Sstevel@tonic-gate | print prarg { $$ = stat3($1, $2, NIL, NIL); } 298*7c478bd9Sstevel@tonic-gate | DELETE varname '[' patlist ']' { $$ = stat2(DELETE, makearr($2), $4); } 299*7c478bd9Sstevel@tonic-gate | DELETE varname { yyclearin; ERROR "you can only delete array[element]" SYNTAX; $$ = stat1(DELETE, $2); } 300*7c478bd9Sstevel@tonic-gate | pattern { $$ = exptostat($1); } 301*7c478bd9Sstevel@tonic-gate | error { yyclearin; ERROR "illegal statement" SYNTAX; } 302*7c478bd9Sstevel@tonic-gate ; 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate st: 305*7c478bd9Sstevel@tonic-gate nl | ';' opt_nl 306*7c478bd9Sstevel@tonic-gate ; 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate stmt: 309*7c478bd9Sstevel@tonic-gate BREAK st { $$ = stat1(BREAK, NIL); } 310*7c478bd9Sstevel@tonic-gate | CLOSE pattern st { $$ = stat1(CLOSE, $2); } 311*7c478bd9Sstevel@tonic-gate | CONTINUE st { $$ = stat1(CONTINUE, NIL); } 312*7c478bd9Sstevel@tonic-gate | do stmt WHILE '(' pattern ')' st 313*7c478bd9Sstevel@tonic-gate { $$ = stat2(DO, $2, notnull($5)); } 314*7c478bd9Sstevel@tonic-gate | EXIT pattern st { $$ = stat1(EXIT, $2); } 315*7c478bd9Sstevel@tonic-gate | EXIT st { $$ = stat1(EXIT, NIL); } 316*7c478bd9Sstevel@tonic-gate | for 317*7c478bd9Sstevel@tonic-gate | if stmt else stmt { $$ = stat3(IF, $1, $2, $4); } 318*7c478bd9Sstevel@tonic-gate | if stmt { $$ = stat3(IF, $1, $2, NIL); } 319*7c478bd9Sstevel@tonic-gate | lbrace stmtlist rbrace { $$ = $2; } 320*7c478bd9Sstevel@tonic-gate | NEXT st { if (infunc) 321*7c478bd9Sstevel@tonic-gate ERROR "next is illegal inside a function" SYNTAX; 322*7c478bd9Sstevel@tonic-gate $$ = stat1(NEXT, NIL); } 323*7c478bd9Sstevel@tonic-gate | RETURN pattern st { $$ = stat1(RETURN, $2); } 324*7c478bd9Sstevel@tonic-gate | RETURN st { $$ = stat1(RETURN, NIL); } 325*7c478bd9Sstevel@tonic-gate | simple_stmt st 326*7c478bd9Sstevel@tonic-gate | while stmt { $$ = stat2(WHILE, $1, $2); } 327*7c478bd9Sstevel@tonic-gate | ';' opt_nl { $$ = 0; } 328*7c478bd9Sstevel@tonic-gate ; 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate stmtlist: 331*7c478bd9Sstevel@tonic-gate stmt 332*7c478bd9Sstevel@tonic-gate | stmtlist stmt { $$ = linkum($1, $2); } 333*7c478bd9Sstevel@tonic-gate ; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate subop: 336*7c478bd9Sstevel@tonic-gate SUB | GSUB 337*7c478bd9Sstevel@tonic-gate ; 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate term: 340*7c478bd9Sstevel@tonic-gate term '+' term { $$ = op2(ADD, $1, $3); } 341*7c478bd9Sstevel@tonic-gate | term '-' term { $$ = op2(MINUS, $1, $3); } 342*7c478bd9Sstevel@tonic-gate | term '*' term { $$ = op2(MULT, $1, $3); } 343*7c478bd9Sstevel@tonic-gate | term '/' term { $$ = op2(DIVIDE, $1, $3); } 344*7c478bd9Sstevel@tonic-gate | term '%' term { $$ = op2(MOD, $1, $3); } 345*7c478bd9Sstevel@tonic-gate | term POWER term { $$ = op2(POWER, $1, $3); } 346*7c478bd9Sstevel@tonic-gate | '-' term %prec UMINUS { $$ = op1(UMINUS, $2); } 347*7c478bd9Sstevel@tonic-gate | '+' term %prec UMINUS { $$ = $2; } 348*7c478bd9Sstevel@tonic-gate | BLTIN '(' ')' { $$ = op2(BLTIN, (Node *) $1, rectonode()); } 349*7c478bd9Sstevel@tonic-gate | BLTIN '(' patlist ')' { $$ = op2(BLTIN, (Node *) $1, $3); } 350*7c478bd9Sstevel@tonic-gate | BLTIN { $$ = op2(BLTIN, (Node *) $1, rectonode()); } 351*7c478bd9Sstevel@tonic-gate | CALL '(' ')' { $$ = op2(CALL, valtonode($1,CVAR), NIL); } 352*7c478bd9Sstevel@tonic-gate | CALL '(' patlist ')' { $$ = op2(CALL, valtonode($1,CVAR), $3); } 353*7c478bd9Sstevel@tonic-gate | DECR var { $$ = op1(PREDECR, $2); } 354*7c478bd9Sstevel@tonic-gate | INCR var { $$ = op1(PREINCR, $2); } 355*7c478bd9Sstevel@tonic-gate | var DECR { $$ = op1(POSTDECR, $1); } 356*7c478bd9Sstevel@tonic-gate | var INCR { $$ = op1(POSTINCR, $1); } 357*7c478bd9Sstevel@tonic-gate | GETLINE var LT term { $$ = op3(GETLINE, $2, (Node *)$3, $4); } 358*7c478bd9Sstevel@tonic-gate | GETLINE LT term { $$ = op3(GETLINE, NIL, (Node *)$2, $3); } 359*7c478bd9Sstevel@tonic-gate | GETLINE var { $$ = op3(GETLINE, $2, NIL, NIL); } 360*7c478bd9Sstevel@tonic-gate | GETLINE { $$ = op3(GETLINE, NIL, NIL, NIL); } 361*7c478bd9Sstevel@tonic-gate | INDEX '(' pattern comma pattern ')' 362*7c478bd9Sstevel@tonic-gate { $$ = op2(INDEX, $3, $5); } 363*7c478bd9Sstevel@tonic-gate | INDEX '(' pattern comma reg_expr ')' 364*7c478bd9Sstevel@tonic-gate { ERROR "index() doesn't permit regular expressions" SYNTAX; 365*7c478bd9Sstevel@tonic-gate $$ = op2(INDEX, $3, (Node*)$5); } 366*7c478bd9Sstevel@tonic-gate | '(' pattern ')' { $$ = $2; } 367*7c478bd9Sstevel@tonic-gate | MATCHFCN '(' pattern comma reg_expr ')' 368*7c478bd9Sstevel@tonic-gate { $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa($5, 1)); } 369*7c478bd9Sstevel@tonic-gate | MATCHFCN '(' pattern comma pattern ')' 370*7c478bd9Sstevel@tonic-gate { if (constnode($5)) 371*7c478bd9Sstevel@tonic-gate $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa(strnode($5), 1)); 372*7c478bd9Sstevel@tonic-gate else 373*7c478bd9Sstevel@tonic-gate $$ = op3(MATCHFCN, (Node *)1, $3, $5); } 374*7c478bd9Sstevel@tonic-gate | NUMBER { $$ = valtonode($1, CCON); } 375*7c478bd9Sstevel@tonic-gate | SPLIT '(' pattern comma varname comma pattern ')' /* string */ 376*7c478bd9Sstevel@tonic-gate { $$ = op4(SPLIT, $3, makearr($5), $7, (Node*)STRING); } 377*7c478bd9Sstevel@tonic-gate | SPLIT '(' pattern comma varname comma reg_expr ')' /* const /regexp/ */ 378*7c478bd9Sstevel@tonic-gate { $$ = op4(SPLIT, $3, makearr($5), (Node*)makedfa($7, 1), (Node *)REGEXPR); } 379*7c478bd9Sstevel@tonic-gate | SPLIT '(' pattern comma varname ')' 380*7c478bd9Sstevel@tonic-gate { $$ = op4(SPLIT, $3, makearr($5), NIL, (Node*)STRING); } /* default */ 381*7c478bd9Sstevel@tonic-gate | SPRINTF '(' patlist ')' { $$ = op1($1, $3); } 382*7c478bd9Sstevel@tonic-gate | STRING { $$ = valtonode($1, CCON); } 383*7c478bd9Sstevel@tonic-gate | subop '(' reg_expr comma pattern ')' 384*7c478bd9Sstevel@tonic-gate { $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, rectonode()); } 385*7c478bd9Sstevel@tonic-gate | subop '(' pattern comma pattern ')' 386*7c478bd9Sstevel@tonic-gate { if (constnode($3)) 387*7c478bd9Sstevel@tonic-gate $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, rectonode()); 388*7c478bd9Sstevel@tonic-gate else 389*7c478bd9Sstevel@tonic-gate $$ = op4($1, (Node *)1, $3, $5, rectonode()); } 390*7c478bd9Sstevel@tonic-gate | subop '(' reg_expr comma pattern comma var ')' 391*7c478bd9Sstevel@tonic-gate { $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, $7); } 392*7c478bd9Sstevel@tonic-gate | subop '(' pattern comma pattern comma var ')' 393*7c478bd9Sstevel@tonic-gate { if (constnode($3)) 394*7c478bd9Sstevel@tonic-gate $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, $7); 395*7c478bd9Sstevel@tonic-gate else 396*7c478bd9Sstevel@tonic-gate $$ = op4($1, (Node *)1, $3, $5, $7); } 397*7c478bd9Sstevel@tonic-gate | SUBSTR '(' pattern comma pattern comma pattern ')' 398*7c478bd9Sstevel@tonic-gate { $$ = op3(SUBSTR, $3, $5, $7); } 399*7c478bd9Sstevel@tonic-gate | SUBSTR '(' pattern comma pattern ')' 400*7c478bd9Sstevel@tonic-gate { $$ = op3(SUBSTR, $3, $5, NIL); } 401*7c478bd9Sstevel@tonic-gate | var 402*7c478bd9Sstevel@tonic-gate ; 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate var: 405*7c478bd9Sstevel@tonic-gate varname 406*7c478bd9Sstevel@tonic-gate | varname '[' patlist ']' { $$ = op2(ARRAY, makearr($1), $3); } 407*7c478bd9Sstevel@tonic-gate | FIELD { $$ = valtonode($1, CFLD); } 408*7c478bd9Sstevel@tonic-gate | IVAR { $$ = op1(INDIRECT, valtonode($1, CVAR)); } 409*7c478bd9Sstevel@tonic-gate | INDIRECT term { $$ = op1(INDIRECT, $2); } 410*7c478bd9Sstevel@tonic-gate ; 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate varlist: 413*7c478bd9Sstevel@tonic-gate /* nothing */ { arglist = $$ = 0; } 414*7c478bd9Sstevel@tonic-gate | VAR { arglist = $$ = valtonode($1,CVAR); } 415*7c478bd9Sstevel@tonic-gate | varlist comma VAR { arglist = $$ = linkum($1,valtonode($3,CVAR)); } 416*7c478bd9Sstevel@tonic-gate ; 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate varname: 419*7c478bd9Sstevel@tonic-gate VAR { $$ = valtonode($1, CVAR); } 420*7c478bd9Sstevel@tonic-gate | ARG { $$ = op1(ARG, (Node *) $1); } 421*7c478bd9Sstevel@tonic-gate | VARNF { $$ = op1(VARNF, (Node *) $1); } 422*7c478bd9Sstevel@tonic-gate ; 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate while: 426*7c478bd9Sstevel@tonic-gate WHILE '(' pattern rparen { $$ = notnull($3); } 427*7c478bd9Sstevel@tonic-gate ; 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate %% 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate setfname(p) 432*7c478bd9Sstevel@tonic-gate Cell *p; 433*7c478bd9Sstevel@tonic-gate { 434*7c478bd9Sstevel@tonic-gate if (isarr(p)) 435*7c478bd9Sstevel@tonic-gate ERROR "%s is an array, not a function", p->nval SYNTAX; 436*7c478bd9Sstevel@tonic-gate else if (isfunc(p)) 437*7c478bd9Sstevel@tonic-gate ERROR "you can't define function %s more than once", p->nval SYNTAX; 438*7c478bd9Sstevel@tonic-gate curfname = p->nval; 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate constnode(p) 442*7c478bd9Sstevel@tonic-gate Node *p; 443*7c478bd9Sstevel@tonic-gate { 444*7c478bd9Sstevel@tonic-gate return p->ntype == NVALUE && ((Cell *) (p->narg[0]))->csub == CCON; 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate uchar *strnode(p) 448*7c478bd9Sstevel@tonic-gate Node *p; 449*7c478bd9Sstevel@tonic-gate { 450*7c478bd9Sstevel@tonic-gate return ((Cell *)(p->narg[0]))->sval; 451*7c478bd9Sstevel@tonic-gate } 452*7c478bd9Sstevel@tonic-gate 453*7c478bd9Sstevel@tonic-gate Node *notnull(n) 454*7c478bd9Sstevel@tonic-gate Node *n; 455*7c478bd9Sstevel@tonic-gate { 456*7c478bd9Sstevel@tonic-gate switch (n->nobj) { 457*7c478bd9Sstevel@tonic-gate case LE: case LT: case EQ: case NE: case GT: case GE: 458*7c478bd9Sstevel@tonic-gate case BOR: case AND: case NOT: 459*7c478bd9Sstevel@tonic-gate return n; 460*7c478bd9Sstevel@tonic-gate default: 461*7c478bd9Sstevel@tonic-gate return op2(NE, n, nullnode); 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate } 464