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 *
fliplist(np)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