5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License, Version 1.0 only
7 * (the "License"). You may not use this file except in compliance
10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 * or http://www.opensolaris.org/os/licensing.
12 * See the License for the specific language governing permissions
13 * and limitations under the License.
15 * When distributing Covered Code, include this CDDL HEADER in each
16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 * If applicable, add the following below this CDDL HEADER, with the
18 * fields enclosed by brackets "[]" replaced with your own identifying
19 * information: Portions Copyright [yyyy] [name of copyright owner]
26 * Copyright (c) 1995 by Sun Microsystems, Inc.
28 * Copyright 1986, 1992 by Mortice Kern Systems Inc. All rights reserved.
30 * This Software is unpublished, valuable, confidential property of
31 * Mortice Kern Systems Inc. Use is authorized only in accordance
32 * with the terms and conditions of the source licence agreement
33 * protecting this Software. Any unauthorized use or disclosure of
34 * this Software is strictly prohibited and will result in the
35 * termination of the licence agreement.
37 * NOTE: this grammar correctly produces NO shift/reduce conflicts from YACC.
42 * Do not use any character constants as tokens, so the resulting C file
43 * is codeset independent.
46 #ident "%Z%%M% %I% %E% SMI"
48 static NODE
* fliplist ANSI
((NODE
*np
));
56 * Do not use any character constants as tokens, so the resulting C file
57 * is codeset independent.
59 * Declare terminal symbols before their operator
60 * precedences to get them in a contiguous block
61 * for giant switches in action() and exprreduce().
63 /* Tokens from exprreduce() */
64 %token
<node
> PARM ARRAY UFUNC FIELD IN INDEX CONCAT
65 %token
<node
> NOT AND OR EXP QUEST
66 %token
<node
> EQ NE GE LE GT LT
67 %token
<node
> ADD SUB MUL DIV REM INC DEC PRE_INC PRE_DEC
68 %token
<node
> GETLINE CALLFUNC RE TILDE NRE
70 /* Tokens shared by exprreduce() and action() */
73 /* Tokens from action() */
74 %token
<node
> PRINT PRINTF
75 %token
<node
> EXIT RETURN BREAK CONTINUE NEXT
76 %token
<node
> DELETE WHILE DO FOR FORIN IF
79 * Terminal symbols not used in action() and exprrreduce()
82 %token
<node
> CONSTANT VAR FUNC
83 %token
<node
> DEFFUNC BEGIN END CLOSE ELSE PACT
88 * Tokens not used in grammar
94 * Tokens representing character constants
95 * TILDE, '~', taken care of above
106 EXCLAMATION
/* '!' */
117 * Priorities of operators
121 %right BAR PIPE WRITE APPEND
122 %right ASG AADD ASUB AMUL ADIV AREM AEXP
129 %left EQ NE LANGLE RANGLE GE LE
132 %left STAR SLASH PERCENT
137 %left DOLLAR LSQUARE RSQUARE
140 %type
<node
> prog rule pattern expr rvalue lvalue fexpr varlist varlist2
141 %type
<node
> statement statlist fileout exprlist eexprlist simplepattern
142 %type
<node
> getline optvar var
150 yytree
= fliplist
(yytree
);
160 yytree
= node
(COMMA
, $1, yytree
); else
166 rule: pattern LBRACE statlist RBRACE
= {
167 $$
= node
(PACT
, $1, $3);
170 | LBRACE statlist RBRACE
= {
172 $$
= node
(PACT
, NNULL
, $2);
175 $$
= node
(PACT
, $1, node
(PRINT
, NNULL
, NNULL
));
179 { $2->n_type
= UFUNC
; funparm
= 1; }
180 LPAREN varlist RPAREN
182 LBRACE statlist
{ uexit
($5); } RBRACE
= {
183 $2->n_ufunc
= node
(DEFFUNC
, $5, fliplist
($9));
187 awkerr
((char *) gettext
("function \"%S\" redefined"), $2->n_name
);
197 | expr COMMA expr
= {
199 $$
= node
(COMMA
, $1, $3);
205 $$
= node
(BEGIN
, NNULL
, NNULL
);
210 $$
= node
(END
, NNULL
, NNULL
);
227 | exprlist COMMA expr
= {
228 $$
= node
(COMMA
, $1, $3);
241 | var COMMA varlist2
= {
242 $$
= node
(COMMA
, $1, $3);
254 * Normal expression (includes regular expression)
258 $$
= node
(ADD
, $1, $3);
260 | expr HYPHEN expr
= {
261 $$
= node
(SUB
, $1, $3);
264 $$
= node
(MUL
, $1, $3);
266 | expr SLASH expr
= {
267 $$
= node
(DIV
, $1, $3);
269 | expr PERCENT expr
= {
270 $$
= node
(REM
, $1, $3);
273 $$
= node
(EXP
, $1, $3);
276 $$
= node
(AND
, $1, $3);
279 $$
= node
(OR
, $1, $3);
281 | expr QUEST expr COLON expr
= {
282 $$
= node
(QUEST
, $1, node
(COLON
, $3, $5));
284 | lvalue ASG expr
= {
285 $$
= node
(ASG
, $1, $3);
287 | lvalue AADD expr
= {
288 $$
= node
(AADD
, $1, $3);
290 | lvalue ASUB expr
= {
291 $$
= node
(ASUB
, $1, $3);
293 | lvalue AMUL expr
= {
294 $$
= node
(AMUL
, $1, $3);
296 | lvalue ADIV expr
= {
297 $$
= node
(ADIV
, $1, $3);
299 | lvalue AREM expr
= {
300 $$
= node
(AREM
, $1, $3);
302 | lvalue AEXP expr
= {
303 $$
= node
(AEXP
, $1, $3);
306 $$
= node
(INC
, $1, NNULL
);
309 $$
= node
(DEC
, $1, NNULL
);
312 $$
= node
(EQ
, $1, $3);
315 $$
= node
(NE
, $1, $3);
317 | expr RANGLE expr
= {
318 $$
= node
(GT
, $1, $3);
320 | expr LANGLE expr
= {
321 $$
= node
(LT
, $1, $3);
324 $$
= node
(GE
, $1, $3);
327 $$
= node
(LE
, $1, $3);
329 | expr TILDE expr
= {
330 $$
= node
(TILDE
, $1, $3);
333 $$
= node
(NRE
, $1, $3);
336 $$
= node
(IN
, $3, $1);
338 | LPAREN exprlist RPAREN IN var
= {
339 $$
= node
(IN
, $5, $2);
343 | expr CONCAT expr
= {
344 $$
= node
(CONCAT
, $1, $3);
350 $$
= node
(FIELD
, $2, NNULL
);
353 * Prevents conflict with FOR LPAREN var IN var RPAREN production
356 | var LSQUARE exprlist RSQUARE
= {
357 $$
= node
(INDEX
, $1, $3);
369 | LPAREN expr RPAREN term
= {
372 | EXCLAMATION expr
= {
373 $$
= node
(NOT
, $2, NNULL
);
375 | HYPHEN expr %prec UMINUS
= {
376 $$
= node
(SUB
, const0
, $2);
378 | PLUSC expr %prec UPLUS
= {
382 $$
= node
(PRE_DEC
, $2, NNULL
);
385 $$
= node
(PRE_INC
, $2, NNULL
);
388 $$
= node
(CALLFUNC
, $1, NNULL
);
390 | FUNC LPAREN eexprlist RPAREN term
= {
391 $$
= node
(CALLFUNC
, $1, $3);
393 | UFUNC LPAREN eexprlist RPAREN term
= {
394 $$
= node
(CALLUFUNC
, $1, $3);
396 | VAR LPAREN eexprlist RPAREN term
= {
397 $$
= node
(CALLUFUNC
, $1, $3);
399 | SLASH
{redelim
='/';} URE SLASH %prec URE
= {
405 FOR LPAREN fexpr SEMI fexpr SEMI fexpr RPAREN statement
= {
406 $$
= node
(FOR
, node
(COMMA
, $3, node
(COMMA
, $5, $7)), $9);
408 | FOR LPAREN var IN var RPAREN statement
= {
412 * attempt to optimize statements for the form
413 * for (i in x) delete x[i]
419 && np
->n_type
== DELETE
420 && (np
= np
->n_left
)->n_type
== INDEX
422 && np
->n_right
== $3)
423 $$
= node
(DELETE
, $5, NNULL
);
425 $$
= node
(FORIN
, node
(IN
, $3, $5), $7);
427 | WHILE LPAREN expr RPAREN statement
= {
428 $$
= node
(WHILE
, $3, $5);
430 | DO statement WHILE LPAREN expr RPAREN
= {
431 $$
= node
(DO
, $5, $2);
433 | IF LPAREN expr RPAREN statement ELSE statement
= {
434 $$
= node
(IF
, $3, node
(ELSE
, $5, $7));
436 | IF LPAREN expr RPAREN statement %prec ELSE
= {
437 $$
= node
(IF
, $3, node
(ELSE
, $5, NNULL
));
440 $$
= node
(CONTINUE
, NNULL
, NNULL
);
443 $$
= node
(BREAK
, NNULL
, NNULL
);
446 $$
= node
(NEXT
, NNULL
, NNULL
);
448 | DELETE lvalue SEMI
= {
449 $$
= node
(DELETE
, $2, NNULL
);
451 | RETURN fexpr SEMI
= {
452 $$
= node
(RETURN
, $2, NNULL
);
454 | EXIT fexpr SEMI
= {
455 $$
= node
(EXIT
, $2, NNULL
);
457 | PRINT eexprlist fileout SEMI
= {
458 $$
= node
(PRINT
, $2, $3);
460 | PRINT LPAREN exprlist RPAREN fileout SEMI
= {
461 $$
= node
(PRINT
, $3, $5);
463 | PRINTF exprlist fileout SEMI
= {
464 $$
= node
(PRINTF
, $2, $3);
466 | PRINTF LPAREN exprlist RPAREN fileout SEMI
= {
467 $$
= node
(PRINTF
, $3, $5);
475 | LBRACE statlist RBRACE
= {
483 | statlist statement
= {
486 else if
($2 == NNULL
)
489 $$
= node
(COMMA
, $1, $2);
495 $$
= node
(WRITE
, $2, NNULL
);
498 $$
= node
(APPEND
, $2, NNULL
);
501 $$
= node
(PIPE
, $2, NNULL
);
509 GETLINE optvar %prec WRITE
= {
510 $$
= node
(GETLINE
, $2, NNULL
);
512 | expr BAR GETLINE optvar
= {
513 $$
= node
(GETLINE
, $4, node
(PIPESYM
, $1, NNULL
));
515 | GETLINE optvar LANGLE expr
= {
516 $$
= node
(GETLINE
, $2, node
(LT
, $4, NNULL
));
532 * Flip a left-recursively generated list
533 * so that it can easily be traversed from left
534 * to right without recursion.
542 if
(np
!=NNULL
&& !isleaf
(np
->n_flags
)
544 && (type
= np
->n_type
)!=FUNC
&& type
!=UFUNC
547 np
->n_right
= fliplist
(np
->n_right
);
548 if
((type
=np
->n_type
)==COMMA
) {
551 while
((lp
= np
->n_left
)!=NNULL
&& lp
->n_type
==COMMA
) {
554 lp
->n_right
= fliplist
(lp
->n_right
);
555 for
(spp
= &lp
->n_right
;
556 *spp
!= NNULL
&& (*spp
)->n_type
==COMMA
;
557 spp
= &(*spp
)->n_right
)
564 if
(np
->n_left
!= NULL
&&
565 (type
= np
->n_left
->n_type
)!= FUNC
&& type
!=UFUNC
)
566 np
->n_left
= fliplist
(np
->n_left
);