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 * awk -- YACC grammar 25*7c478bd9Sstevel@tonic-gate * 26*7c478bd9Sstevel@tonic-gate * Copyright (c) 1995 by Sun Microsystems, Inc. 27*7c478bd9Sstevel@tonic-gate * 28*7c478bd9Sstevel@tonic-gate * Copyright 1986, 1992 by Mortice Kern Systems Inc. All rights reserved. 29*7c478bd9Sstevel@tonic-gate * 30*7c478bd9Sstevel@tonic-gate * This Software is unpublished, valuable, confidential property of 31*7c478bd9Sstevel@tonic-gate * Mortice Kern Systems Inc. Use is authorized only in accordance 32*7c478bd9Sstevel@tonic-gate * with the terms and conditions of the source licence agreement 33*7c478bd9Sstevel@tonic-gate * protecting this Software. Any unauthorized use or disclosure of 34*7c478bd9Sstevel@tonic-gate * this Software is strictly prohibited and will result in the 35*7c478bd9Sstevel@tonic-gate * termination of the licence agreement. 36*7c478bd9Sstevel@tonic-gate * 37*7c478bd9Sstevel@tonic-gate * NOTE: this grammar correctly produces NO shift/reduce conflicts from YACC. 38*7c478bd9Sstevel@tonic-gate * 39*7c478bd9Sstevel@tonic-gate */ 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate /* 42*7c478bd9Sstevel@tonic-gate * Do not use any character constants as tokens, so the resulting C file 43*7c478bd9Sstevel@tonic-gate * is codeset independent. 44*7c478bd9Sstevel@tonic-gate */ 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" 47*7c478bd9Sstevel@tonic-gate #include "awk.h" 48*7c478bd9Sstevel@tonic-gate static NODE * fliplist ANSI((NODE *np)); 49*7c478bd9Sstevel@tonic-gate %} 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate %union { 52*7c478bd9Sstevel@tonic-gate NODE *node; 53*7c478bd9Sstevel@tonic-gate }; 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* 56*7c478bd9Sstevel@tonic-gate * Do not use any character constants as tokens, so the resulting C file 57*7c478bd9Sstevel@tonic-gate * is codeset independent. 58*7c478bd9Sstevel@tonic-gate * 59*7c478bd9Sstevel@tonic-gate * Declare terminal symbols before their operator 60*7c478bd9Sstevel@tonic-gate * precedences to get them in a contiguous block 61*7c478bd9Sstevel@tonic-gate * for giant switches in action() and exprreduce(). 62*7c478bd9Sstevel@tonic-gate */ 63*7c478bd9Sstevel@tonic-gate /* Tokens from exprreduce() */ 64*7c478bd9Sstevel@tonic-gate %token <node> PARM ARRAY UFUNC FIELD IN INDEX CONCAT 65*7c478bd9Sstevel@tonic-gate %token <node> NOT AND OR EXP QUEST 66*7c478bd9Sstevel@tonic-gate %token <node> EQ NE GE LE GT LT 67*7c478bd9Sstevel@tonic-gate %token <node> ADD SUB MUL DIV REM INC DEC PRE_INC PRE_DEC 68*7c478bd9Sstevel@tonic-gate %token <node> GETLINE CALLFUNC RE TILDE NRE 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate /* Tokens shared by exprreduce() and action() */ 71*7c478bd9Sstevel@tonic-gate %token ASG 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate /* Tokens from action() */ 74*7c478bd9Sstevel@tonic-gate %token <node> PRINT PRINTF 75*7c478bd9Sstevel@tonic-gate %token <node> EXIT RETURN BREAK CONTINUE NEXT 76*7c478bd9Sstevel@tonic-gate %token <node> DELETE WHILE DO FOR FORIN IF 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate /* 79*7c478bd9Sstevel@tonic-gate * Terminal symbols not used in action() and exprrreduce() 80*7c478bd9Sstevel@tonic-gate * switch statements. 81*7c478bd9Sstevel@tonic-gate */ 82*7c478bd9Sstevel@tonic-gate %token <node> CONSTANT VAR FUNC 83*7c478bd9Sstevel@tonic-gate %token <node> DEFFUNC BEGIN END CLOSE ELSE PACT 84*7c478bd9Sstevel@tonic-gate %right ELSE 85*7c478bd9Sstevel@tonic-gate %token DOT CALLUFUNC 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate /* 88*7c478bd9Sstevel@tonic-gate * Tokens not used in grammar 89*7c478bd9Sstevel@tonic-gate */ 90*7c478bd9Sstevel@tonic-gate %token KEYWORD SVAR 91*7c478bd9Sstevel@tonic-gate %token PIPESYM 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate /* 94*7c478bd9Sstevel@tonic-gate * Tokens representing character constants 95*7c478bd9Sstevel@tonic-gate * TILDE, '~', taken care of above 96*7c478bd9Sstevel@tonic-gate */ 97*7c478bd9Sstevel@tonic-gate %token BAR /* '|' */ 98*7c478bd9Sstevel@tonic-gate CARAT /* '^' */ 99*7c478bd9Sstevel@tonic-gate LANGLE /* '<' */ 100*7c478bd9Sstevel@tonic-gate RANGLE /* '>' */ 101*7c478bd9Sstevel@tonic-gate PLUSC /* '+' */ 102*7c478bd9Sstevel@tonic-gate HYPHEN /* '-' */ 103*7c478bd9Sstevel@tonic-gate STAR /* '*' */ 104*7c478bd9Sstevel@tonic-gate SLASH /* '/' */ 105*7c478bd9Sstevel@tonic-gate PERCENT /* '%' */ 106*7c478bd9Sstevel@tonic-gate EXCLAMATION /* '!' */ 107*7c478bd9Sstevel@tonic-gate DOLLAR /* '$' */ 108*7c478bd9Sstevel@tonic-gate LSQUARE /* '[' */ 109*7c478bd9Sstevel@tonic-gate RSQUARE /* ']' */ 110*7c478bd9Sstevel@tonic-gate LPAREN /* '(' */ 111*7c478bd9Sstevel@tonic-gate RPAREN /* ')' */ 112*7c478bd9Sstevel@tonic-gate SEMI /* ';' */ 113*7c478bd9Sstevel@tonic-gate LBRACE /* '{' */ 114*7c478bd9Sstevel@tonic-gate RBRACE /* '}' */ 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate /* 117*7c478bd9Sstevel@tonic-gate * Priorities of operators 118*7c478bd9Sstevel@tonic-gate * Lowest to highest 119*7c478bd9Sstevel@tonic-gate */ 120*7c478bd9Sstevel@tonic-gate %left COMMA 121*7c478bd9Sstevel@tonic-gate %right BAR PIPE WRITE APPEND 122*7c478bd9Sstevel@tonic-gate %right ASG AADD ASUB AMUL ADIV AREM AEXP 123*7c478bd9Sstevel@tonic-gate %right QUEST COLON 124*7c478bd9Sstevel@tonic-gate %left OR 125*7c478bd9Sstevel@tonic-gate %left AND 126*7c478bd9Sstevel@tonic-gate %left IN 127*7c478bd9Sstevel@tonic-gate %left CARAT 128*7c478bd9Sstevel@tonic-gate %left TILDE NRE 129*7c478bd9Sstevel@tonic-gate %left EQ NE LANGLE RANGLE GE LE 130*7c478bd9Sstevel@tonic-gate %left CONCAT 131*7c478bd9Sstevel@tonic-gate %left PLUSC HYPHEN 132*7c478bd9Sstevel@tonic-gate %left STAR SLASH PERCENT 133*7c478bd9Sstevel@tonic-gate %right UPLUS UMINUS 134*7c478bd9Sstevel@tonic-gate %right EXCLAMATION 135*7c478bd9Sstevel@tonic-gate %right EXP 136*7c478bd9Sstevel@tonic-gate %right INC DEC URE 137*7c478bd9Sstevel@tonic-gate %left DOLLAR LSQUARE RSQUARE 138*7c478bd9Sstevel@tonic-gate %left LPAREN RPAREN 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate %type <node> prog rule pattern expr rvalue lvalue fexpr varlist varlist2 141*7c478bd9Sstevel@tonic-gate %type <node> statement statlist fileout exprlist eexprlist simplepattern 142*7c478bd9Sstevel@tonic-gate %type <node> getline optvar var 143*7c478bd9Sstevel@tonic-gate %type <node> dummy 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate %start dummy 146*7c478bd9Sstevel@tonic-gate %% 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate dummy: 149*7c478bd9Sstevel@tonic-gate prog = { 150*7c478bd9Sstevel@tonic-gate yytree = fliplist(yytree); 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate ; 153*7c478bd9Sstevel@tonic-gate prog: 154*7c478bd9Sstevel@tonic-gate rule = { 155*7c478bd9Sstevel@tonic-gate yytree = $1; 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate | rule SEMI prog = { 158*7c478bd9Sstevel@tonic-gate if ($1 != NNULL) { 159*7c478bd9Sstevel@tonic-gate if (yytree != NNULL) 160*7c478bd9Sstevel@tonic-gate yytree = node(COMMA, $1, yytree); else 161*7c478bd9Sstevel@tonic-gate yytree = $1; 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate ; 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate rule: pattern LBRACE statlist RBRACE = { 167*7c478bd9Sstevel@tonic-gate $$ = node(PACT, $1, $3); 168*7c478bd9Sstevel@tonic-gate doing_begin = 0; 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate | LBRACE statlist RBRACE = { 171*7c478bd9Sstevel@tonic-gate npattern++; 172*7c478bd9Sstevel@tonic-gate $$ = node(PACT, NNULL, $2); 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate | pattern = { 175*7c478bd9Sstevel@tonic-gate $$ = node(PACT, $1, node(PRINT, NNULL, NNULL)); 176*7c478bd9Sstevel@tonic-gate doing_begin = 0; 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate | DEFFUNC VAR 179*7c478bd9Sstevel@tonic-gate { $2->n_type = UFUNC; funparm = 1; } 180*7c478bd9Sstevel@tonic-gate LPAREN varlist RPAREN 181*7c478bd9Sstevel@tonic-gate { funparm = 0; } 182*7c478bd9Sstevel@tonic-gate LBRACE statlist { uexit($5); } RBRACE = { 183*7c478bd9Sstevel@tonic-gate $2->n_ufunc = node(DEFFUNC, $5, fliplist($9)); 184*7c478bd9Sstevel@tonic-gate $$ = NNULL; 185*7c478bd9Sstevel@tonic-gate } 186*7c478bd9Sstevel@tonic-gate | DEFFUNC UFUNC = { 187*7c478bd9Sstevel@tonic-gate awkerr((char *) gettext("function \"%S\" redefined"), $2->n_name); 188*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate | = { 191*7c478bd9Sstevel@tonic-gate $$ = NNULL; 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate ; 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate pattern: 196*7c478bd9Sstevel@tonic-gate simplepattern 197*7c478bd9Sstevel@tonic-gate | expr COMMA expr = { 198*7c478bd9Sstevel@tonic-gate ++npattern; 199*7c478bd9Sstevel@tonic-gate $$ = node(COMMA, $1, $3); 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate ; 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate simplepattern: 204*7c478bd9Sstevel@tonic-gate BEGIN = { 205*7c478bd9Sstevel@tonic-gate $$ = node(BEGIN, NNULL, NNULL); 206*7c478bd9Sstevel@tonic-gate doing_begin++; 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate | END = { 209*7c478bd9Sstevel@tonic-gate ++npattern; 210*7c478bd9Sstevel@tonic-gate $$ = node(END, NNULL, NNULL); 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate | expr = { 213*7c478bd9Sstevel@tonic-gate ++npattern; 214*7c478bd9Sstevel@tonic-gate $$ = $1; 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate ; 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate eexprlist: 219*7c478bd9Sstevel@tonic-gate exprlist 220*7c478bd9Sstevel@tonic-gate | = { 221*7c478bd9Sstevel@tonic-gate $$ = NNULL; 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate ; 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate exprlist: 226*7c478bd9Sstevel@tonic-gate expr %prec COMMA 227*7c478bd9Sstevel@tonic-gate | exprlist COMMA expr = { 228*7c478bd9Sstevel@tonic-gate $$ = node(COMMA, $1, $3); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate ; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate varlist: 233*7c478bd9Sstevel@tonic-gate = { 234*7c478bd9Sstevel@tonic-gate $$ = NNULL; 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate | varlist2 237*7c478bd9Sstevel@tonic-gate ; 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate varlist2: 240*7c478bd9Sstevel@tonic-gate var 241*7c478bd9Sstevel@tonic-gate | var COMMA varlist2 = { 242*7c478bd9Sstevel@tonic-gate $$ = node(COMMA, $1, $3); 243*7c478bd9Sstevel@tonic-gate } 244*7c478bd9Sstevel@tonic-gate ; 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate fexpr: 247*7c478bd9Sstevel@tonic-gate expr 248*7c478bd9Sstevel@tonic-gate | = { 249*7c478bd9Sstevel@tonic-gate $$ = NNULL; 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate ; 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate /* 254*7c478bd9Sstevel@tonic-gate * Normal expression (includes regular expression) 255*7c478bd9Sstevel@tonic-gate */ 256*7c478bd9Sstevel@tonic-gate expr: 257*7c478bd9Sstevel@tonic-gate expr PLUSC expr = { 258*7c478bd9Sstevel@tonic-gate $$ = node(ADD, $1, $3); 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate | expr HYPHEN expr = { 261*7c478bd9Sstevel@tonic-gate $$ = node(SUB, $1, $3); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate | expr STAR expr = { 264*7c478bd9Sstevel@tonic-gate $$ = node(MUL, $1, $3); 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate | expr SLASH expr = { 267*7c478bd9Sstevel@tonic-gate $$ = node(DIV, $1, $3); 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate | expr PERCENT expr = { 270*7c478bd9Sstevel@tonic-gate $$ = node(REM, $1, $3); 271*7c478bd9Sstevel@tonic-gate } 272*7c478bd9Sstevel@tonic-gate | expr EXP expr = { 273*7c478bd9Sstevel@tonic-gate $$ = node(EXP, $1, $3); 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate | expr AND expr = { 276*7c478bd9Sstevel@tonic-gate $$ = node(AND, $1, $3); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate | expr OR expr = { 279*7c478bd9Sstevel@tonic-gate $$ = node(OR, $1, $3); 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate | expr QUEST expr COLON expr = { 282*7c478bd9Sstevel@tonic-gate $$ = node(QUEST, $1, node(COLON, $3, $5)); 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate | lvalue ASG expr = { 285*7c478bd9Sstevel@tonic-gate $$ = node(ASG, $1, $3); 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate | lvalue AADD expr = { 288*7c478bd9Sstevel@tonic-gate $$ = node(AADD, $1, $3); 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate | lvalue ASUB expr = { 291*7c478bd9Sstevel@tonic-gate $$ = node(ASUB, $1, $3); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate | lvalue AMUL expr = { 294*7c478bd9Sstevel@tonic-gate $$ = node(AMUL, $1, $3); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate | lvalue ADIV expr = { 297*7c478bd9Sstevel@tonic-gate $$ = node(ADIV, $1, $3); 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate | lvalue AREM expr = { 300*7c478bd9Sstevel@tonic-gate $$ = node(AREM, $1, $3); 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate | lvalue AEXP expr = { 303*7c478bd9Sstevel@tonic-gate $$ = node(AEXP, $1, $3); 304*7c478bd9Sstevel@tonic-gate } 305*7c478bd9Sstevel@tonic-gate | lvalue INC = { 306*7c478bd9Sstevel@tonic-gate $$ = node(INC, $1, NNULL); 307*7c478bd9Sstevel@tonic-gate } 308*7c478bd9Sstevel@tonic-gate | lvalue DEC = { 309*7c478bd9Sstevel@tonic-gate $$ = node(DEC, $1, NNULL); 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate | expr EQ expr = { 312*7c478bd9Sstevel@tonic-gate $$ = node(EQ, $1, $3); 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate | expr NE expr = { 315*7c478bd9Sstevel@tonic-gate $$ = node(NE, $1, $3); 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate | expr RANGLE expr = { 318*7c478bd9Sstevel@tonic-gate $$ = node(GT, $1, $3); 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate | expr LANGLE expr = { 321*7c478bd9Sstevel@tonic-gate $$ = node(LT, $1, $3); 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate | expr GE expr = { 324*7c478bd9Sstevel@tonic-gate $$ = node(GE, $1, $3); 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate | expr LE expr = { 327*7c478bd9Sstevel@tonic-gate $$ = node(LE, $1, $3); 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate | expr TILDE expr = { 330*7c478bd9Sstevel@tonic-gate $$ = node(TILDE, $1, $3); 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate | expr NRE expr = { 333*7c478bd9Sstevel@tonic-gate $$ = node(NRE, $1, $3); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate | expr IN var = { 336*7c478bd9Sstevel@tonic-gate $$ = node(IN, $3, $1); 337*7c478bd9Sstevel@tonic-gate } 338*7c478bd9Sstevel@tonic-gate | LPAREN exprlist RPAREN IN var = { 339*7c478bd9Sstevel@tonic-gate $$ = node(IN, $5, $2); 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate | getline 342*7c478bd9Sstevel@tonic-gate | rvalue 343*7c478bd9Sstevel@tonic-gate | expr CONCAT expr = { 344*7c478bd9Sstevel@tonic-gate $$ = node(CONCAT, $1, $3); 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate ; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate lvalue: 349*7c478bd9Sstevel@tonic-gate DOLLAR rvalue = { 350*7c478bd9Sstevel@tonic-gate $$ = node(FIELD, $2, NNULL); 351*7c478bd9Sstevel@tonic-gate } 352*7c478bd9Sstevel@tonic-gate /* 353*7c478bd9Sstevel@tonic-gate * Prevents conflict with FOR LPAREN var IN var RPAREN production 354*7c478bd9Sstevel@tonic-gate */ 355*7c478bd9Sstevel@tonic-gate | var %prec COMMA 356*7c478bd9Sstevel@tonic-gate | var LSQUARE exprlist RSQUARE = { 357*7c478bd9Sstevel@tonic-gate $$ = node(INDEX, $1, $3); 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate ; 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate var: 362*7c478bd9Sstevel@tonic-gate VAR 363*7c478bd9Sstevel@tonic-gate | PARM 364*7c478bd9Sstevel@tonic-gate ; 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate rvalue: 367*7c478bd9Sstevel@tonic-gate lvalue %prec COMMA 368*7c478bd9Sstevel@tonic-gate | CONSTANT 369*7c478bd9Sstevel@tonic-gate | LPAREN expr RPAREN term = { 370*7c478bd9Sstevel@tonic-gate $$ = $2; 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate | EXCLAMATION expr = { 373*7c478bd9Sstevel@tonic-gate $$ = node(NOT, $2, NNULL); 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate | HYPHEN expr %prec UMINUS = { 376*7c478bd9Sstevel@tonic-gate $$ = node(SUB, const0, $2); 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate | PLUSC expr %prec UPLUS = { 379*7c478bd9Sstevel@tonic-gate $$ = $2; 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate | DEC lvalue = { 382*7c478bd9Sstevel@tonic-gate $$ = node(PRE_DEC, $2, NNULL); 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate | INC lvalue = { 385*7c478bd9Sstevel@tonic-gate $$ = node(PRE_INC, $2, NNULL); 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate | FUNC = { 388*7c478bd9Sstevel@tonic-gate $$ = node(CALLFUNC, $1, NNULL); 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate | FUNC LPAREN eexprlist RPAREN term = { 391*7c478bd9Sstevel@tonic-gate $$ = node(CALLFUNC, $1, $3); 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate | UFUNC LPAREN eexprlist RPAREN term = { 394*7c478bd9Sstevel@tonic-gate $$ = node(CALLUFUNC, $1, $3); 395*7c478bd9Sstevel@tonic-gate } 396*7c478bd9Sstevel@tonic-gate | VAR LPAREN eexprlist RPAREN term = { 397*7c478bd9Sstevel@tonic-gate $$ = node(CALLUFUNC, $1, $3); 398*7c478bd9Sstevel@tonic-gate } 399*7c478bd9Sstevel@tonic-gate | SLASH {redelim='/';} URE SLASH %prec URE = { 400*7c478bd9Sstevel@tonic-gate $$ = $<node>3; 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate ; 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate statement: 405*7c478bd9Sstevel@tonic-gate FOR LPAREN fexpr SEMI fexpr SEMI fexpr RPAREN statement = { 406*7c478bd9Sstevel@tonic-gate $$ = node(FOR, node(COMMA, $3, node(COMMA, $5, $7)), $9); 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate | FOR LPAREN var IN var RPAREN statement = { 409*7c478bd9Sstevel@tonic-gate register NODE *np; 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate /* 412*7c478bd9Sstevel@tonic-gate * attempt to optimize statements for the form 413*7c478bd9Sstevel@tonic-gate * for (i in x) delete x[i] 414*7c478bd9Sstevel@tonic-gate * to 415*7c478bd9Sstevel@tonic-gate * delete x 416*7c478bd9Sstevel@tonic-gate */ 417*7c478bd9Sstevel@tonic-gate np = $7; 418*7c478bd9Sstevel@tonic-gate if (np != NNULL 419*7c478bd9Sstevel@tonic-gate && np->n_type == DELETE 420*7c478bd9Sstevel@tonic-gate && (np = np->n_left)->n_type == INDEX 421*7c478bd9Sstevel@tonic-gate && np->n_left == $5 422*7c478bd9Sstevel@tonic-gate && np->n_right == $3) 423*7c478bd9Sstevel@tonic-gate $$ = node(DELETE, $5, NNULL); 424*7c478bd9Sstevel@tonic-gate else 425*7c478bd9Sstevel@tonic-gate $$ = node(FORIN, node(IN, $3, $5), $7); 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate | WHILE LPAREN expr RPAREN statement = { 428*7c478bd9Sstevel@tonic-gate $$ = node(WHILE, $3, $5); 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate | DO statement WHILE LPAREN expr RPAREN = { 431*7c478bd9Sstevel@tonic-gate $$ = node(DO, $5, $2); 432*7c478bd9Sstevel@tonic-gate } 433*7c478bd9Sstevel@tonic-gate | IF LPAREN expr RPAREN statement ELSE statement = { 434*7c478bd9Sstevel@tonic-gate $$ = node(IF, $3, node(ELSE, $5, $7)); 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate | IF LPAREN expr RPAREN statement %prec ELSE = { 437*7c478bd9Sstevel@tonic-gate $$ = node(IF, $3, node(ELSE, $5, NNULL)); 438*7c478bd9Sstevel@tonic-gate } 439*7c478bd9Sstevel@tonic-gate | CONTINUE SEMI = { 440*7c478bd9Sstevel@tonic-gate $$ = node(CONTINUE, NNULL, NNULL); 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate | BREAK SEMI = { 443*7c478bd9Sstevel@tonic-gate $$ = node(BREAK, NNULL, NNULL); 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate | NEXT SEMI = { 446*7c478bd9Sstevel@tonic-gate $$ = node(NEXT, NNULL, NNULL); 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate | DELETE lvalue SEMI = { 449*7c478bd9Sstevel@tonic-gate $$ = node(DELETE, $2, NNULL); 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate | RETURN fexpr SEMI = { 452*7c478bd9Sstevel@tonic-gate $$ = node(RETURN, $2, NNULL); 453*7c478bd9Sstevel@tonic-gate } 454*7c478bd9Sstevel@tonic-gate | EXIT fexpr SEMI = { 455*7c478bd9Sstevel@tonic-gate $$ = node(EXIT, $2, NNULL); 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate | PRINT eexprlist fileout SEMI = { 458*7c478bd9Sstevel@tonic-gate $$ = node(PRINT, $2, $3); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate | PRINT LPAREN exprlist RPAREN fileout SEMI = { 461*7c478bd9Sstevel@tonic-gate $$ = node(PRINT, $3, $5); 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate | PRINTF exprlist fileout SEMI = { 464*7c478bd9Sstevel@tonic-gate $$ = node(PRINTF, $2, $3); 465*7c478bd9Sstevel@tonic-gate } 466*7c478bd9Sstevel@tonic-gate | PRINTF LPAREN exprlist RPAREN fileout SEMI = { 467*7c478bd9Sstevel@tonic-gate $$ = node(PRINTF, $3, $5); 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate | expr SEMI = { 470*7c478bd9Sstevel@tonic-gate $$ = $1; 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate | SEMI = { 473*7c478bd9Sstevel@tonic-gate $$ = NNULL; 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate | LBRACE statlist RBRACE = { 476*7c478bd9Sstevel@tonic-gate $$ = $2; 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate ; 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate statlist: 482*7c478bd9Sstevel@tonic-gate statement 483*7c478bd9Sstevel@tonic-gate | statlist statement = { 484*7c478bd9Sstevel@tonic-gate if ($1 == NNULL) 485*7c478bd9Sstevel@tonic-gate $$ = $2; 486*7c478bd9Sstevel@tonic-gate else if ($2 == NNULL) 487*7c478bd9Sstevel@tonic-gate $$ = $1; 488*7c478bd9Sstevel@tonic-gate else 489*7c478bd9Sstevel@tonic-gate $$ = node(COMMA, $1, $2); 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate ; 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate fileout: 494*7c478bd9Sstevel@tonic-gate WRITE expr = { 495*7c478bd9Sstevel@tonic-gate $$ = node(WRITE, $2, NNULL); 496*7c478bd9Sstevel@tonic-gate } 497*7c478bd9Sstevel@tonic-gate | APPEND expr = { 498*7c478bd9Sstevel@tonic-gate $$ = node(APPEND, $2, NNULL); 499*7c478bd9Sstevel@tonic-gate } 500*7c478bd9Sstevel@tonic-gate | PIPE expr = { 501*7c478bd9Sstevel@tonic-gate $$ = node(PIPE, $2, NNULL); 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate | = { 504*7c478bd9Sstevel@tonic-gate $$ = NNULL; 505*7c478bd9Sstevel@tonic-gate } 506*7c478bd9Sstevel@tonic-gate ; 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate getline: 509*7c478bd9Sstevel@tonic-gate GETLINE optvar %prec WRITE = { 510*7c478bd9Sstevel@tonic-gate $$ = node(GETLINE, $2, NNULL); 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate | expr BAR GETLINE optvar = { 513*7c478bd9Sstevel@tonic-gate $$ = node(GETLINE, $4, node(PIPESYM, $1, NNULL)); 514*7c478bd9Sstevel@tonic-gate } 515*7c478bd9Sstevel@tonic-gate | GETLINE optvar LANGLE expr = { 516*7c478bd9Sstevel@tonic-gate $$ = node(GETLINE, $2, node(LT, $4, NNULL)); 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate ; 519*7c478bd9Sstevel@tonic-gate 520*7c478bd9Sstevel@tonic-gate optvar: 521*7c478bd9Sstevel@tonic-gate lvalue 522*7c478bd9Sstevel@tonic-gate | = { 523*7c478bd9Sstevel@tonic-gate $$ = NNULL; 524*7c478bd9Sstevel@tonic-gate } 525*7c478bd9Sstevel@tonic-gate ; 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate term: 528*7c478bd9Sstevel@tonic-gate {catterm = 1;} 529*7c478bd9Sstevel@tonic-gate ; 530*7c478bd9Sstevel@tonic-gate %% 531*7c478bd9Sstevel@tonic-gate /* 532*7c478bd9Sstevel@tonic-gate * Flip a left-recursively generated list 533*7c478bd9Sstevel@tonic-gate * so that it can easily be traversed from left 534*7c478bd9Sstevel@tonic-gate * to right without recursion. 535*7c478bd9Sstevel@tonic-gate */ 536*7c478bd9Sstevel@tonic-gate static NODE * 537*7c478bd9Sstevel@tonic-gate fliplist(np) 538*7c478bd9Sstevel@tonic-gate register NODE *np; 539*7c478bd9Sstevel@tonic-gate { 540*7c478bd9Sstevel@tonic-gate int type; 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate if (np!=NNULL && !isleaf(np->n_flags) 543*7c478bd9Sstevel@tonic-gate #if 0 544*7c478bd9Sstevel@tonic-gate && (type = np->n_type)!=FUNC && type!=UFUNC 545*7c478bd9Sstevel@tonic-gate #endif 546*7c478bd9Sstevel@tonic-gate ) { 547*7c478bd9Sstevel@tonic-gate np->n_right = fliplist(np->n_right); 548*7c478bd9Sstevel@tonic-gate if ((type=np->n_type)==COMMA) { 549*7c478bd9Sstevel@tonic-gate register NODE *lp; 550*7c478bd9Sstevel@tonic-gate 551*7c478bd9Sstevel@tonic-gate while ((lp = np->n_left)!=NNULL && lp->n_type==COMMA) { 552*7c478bd9Sstevel@tonic-gate register NODE* *spp; 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate lp->n_right = fliplist(lp->n_right); 555*7c478bd9Sstevel@tonic-gate for (spp = &lp->n_right; 556*7c478bd9Sstevel@tonic-gate *spp != NNULL && (*spp)->n_type==COMMA; 557*7c478bd9Sstevel@tonic-gate spp = &(*spp)->n_right) 558*7c478bd9Sstevel@tonic-gate ; 559*7c478bd9Sstevel@tonic-gate np->n_left = *spp; 560*7c478bd9Sstevel@tonic-gate *spp = np; 561*7c478bd9Sstevel@tonic-gate np = lp; 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate if (np->n_left != NULL && 565*7c478bd9Sstevel@tonic-gate (type = np->n_left->n_type)!= FUNC && type!=UFUNC) 566*7c478bd9Sstevel@tonic-gate np->n_left = fliplist(np->n_left); 567*7c478bd9Sstevel@tonic-gate } 568*7c478bd9Sstevel@tonic-gate return (np); 569*7c478bd9Sstevel@tonic-gate } 570