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]
25 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 /* All Rights Reserved */
33 #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.10 */
38 int yywrap
(void) { return
(1); }
42 Node
*beginloc
= 0, *endloc
= 0;
43 int infunc
= 0; /* = 1 if in arglist or body of func */
45 Node
*arglist
= 0; /* list of args for current function */
46 static void setfname
(Cell
*);
47 static int constnode
(Node
*);
48 static uchar
*strnode
(Node
*);
49 static Node
*notnull
();
59 %token
<i
> FIRSTTOKEN
/* must be first */
60 %token
<p
> PROGRAM PASTAT PASTAT2 XBEGIN XEND
61 %token
<i
> NL
',' '{' '(' '|' ';' '/' ')' '}' '[' ']'
63 %token
<i
> MATCH NOTMATCH MATCHOP
64 %token
<i
> FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS
65 %token
<i
> AND BOR APPEND EQ GE GT LE LT NE IN
66 %token
<i
> ARG BLTIN BREAK CLOSE CONTINUE DELETE DO EXIT FOR FUNC
67 %token
<i
> SUB GSUB IF INDEX LSUBSTR MATCHFCN NEXT
68 %token
<i
> ADD MINUS MULT DIVIDE MOD
69 %token
<i
> ASSIGN ASGNOP ADDEQ SUBEQ MULTEQ DIVEQ MODEQ POWEQ
70 %token
<i
> PRINT PRINTF SPRINTF
71 %token
<p
> ELSE INTEST CONDEXPR
72 %token
<i
> POSTINCR PREINCR POSTDECR PREDECR
73 %token
<cp
> VAR IVAR VARNF CALL NUMBER STRING FIELD
76 %type
<p
> pas pattern ppattern plist pplist patlist prarg term
77 %type
<p
> pa_pat pa_stat pa_stats
79 %type
<p
> simple_stmt opt_simple_stmt stmt stmtlist
80 %type
<p
> var varname funcname varlist
81 %type
<p
> for if while
82 %type
<i
> pst opt_pst lbrace rparen comma nl opt_nl and bor
91 %nonassoc APPEND EQ GE GT LE LT NE MATCHOP IN
'|'
92 %left ARG BLTIN BREAK CALL CLOSE CONTINUE DELETE DO EXIT FOR FIELD FUNC
93 %left GSUB IF INDEX LSUBSTR MATCHFCN NEXT NUMBER
94 %left PRINT PRINTF RETURN SPLIT SPRINTF STRING SUB SUBSTR
95 %left REGEXPR VAR VARNF IVAR WHILE
'('
103 %token LASTTOKEN
/* must be last */
108 pas
{ if
(errorflag
==0)
109 winner
= (Node
*)stat3
(PROGRAM
, beginloc
, $1, endloc
); }
110 |
error { yyclearin; bracecheck
(); ERROR
"bailing out" SYNTAX
; }
134 FOR
'(' opt_simple_stmt
';' pattern
';' opt_simple_stmt rparen stmt
135 { $$
= stat4
(FOR
, $3, notnull
($5), $7, $9); }
136 | FOR
'(' opt_simple_stmt
';' ';' opt_simple_stmt rparen stmt
137 { $$
= stat4
(FOR
, $3, NIL
, $6, $8); }
138 | FOR
'(' varname IN varname rparen stmt
139 { $$
= stat3
(IN
, $3, makearr
($5), $7); }
143 VAR
{ setfname
($1); }
144 | CALL
{ setfname
($1); }
148 IF
'(' pattern rparen
{ $$
= notnull
($3); }
160 /* empty */ { $$
= 0; }
165 /* empty */ { $$
= 0; }
171 /* empty */ { $$
= 0; }
177 | opt_pst pa_stats opt_pst
{ $$
= $2; }
181 pattern
{ $$
= notnull
($1); }
185 pa_pat
{ $$
= stat2
(PASTAT
, $1, stat2
(PRINT
, rectonode
(), NIL
)); }
186 | pa_pat lbrace stmtlist
'}' { $$
= stat2
(PASTAT
, $1, $3); }
187 | pa_pat
',' pa_pat
{ $$
= pa2stat
($1, $3, stat2
(PRINT
, rectonode
(), NIL
)); }
188 | pa_pat
',' pa_pat lbrace stmtlist
'}' { $$
= pa2stat
($1, $3, $5); }
189 | lbrace stmtlist
'}' { $$
= stat2
(PASTAT
, NIL
, $2); }
190 | XBEGIN lbrace stmtlist
'}'
191 { beginloc
= linkum
(beginloc
, $3); $$
= 0; }
192 | XEND lbrace stmtlist
'}'
193 { endloc
= linkum
(endloc
, $3); $$
= 0; }
194 | FUNC funcname
'(' varlist rparen
{infunc
++;} lbrace stmtlist
'}'
195 { infunc
--; curfname
=0; defn
((Cell
*)$2, $4, $8); $$
= 0; }
200 | pa_stats opt_pst pa_stat
{ $$
= linkum
($1, $3); }
205 | patlist comma pattern
{ $$
= linkum
($1, $3); }
209 var ASGNOP ppattern
{ $$
= op2
($2, $1, $3); }
210 | ppattern
'?' ppattern
':' ppattern %prec
'?'
211 { $$
= op3
(CONDEXPR
, notnull
($1), $3, $5); }
212 | ppattern bor ppattern %prec BOR
213 { $$
= op2
(BOR
, notnull
($1), notnull
($3)); }
214 | ppattern and ppattern %prec AND
215 { $$
= op2
(AND
, notnull
($1), notnull
($3)); }
217 { $$
= op1
(NOT
, notnull
($2)); }
218 | ppattern MATCHOP reg_expr
{ $$
= op3
($2, NIL
, $1, (Node
*)makedfa
($3, 0)); }
219 | ppattern MATCHOP ppattern
221 $$
= op3
($2, NIL
, $1, (Node
*)makedfa
(strnode
($3), 0));
223 $$
= op3
($2, (Node
*)1, $1, $3); }
224 | ppattern IN varname
{ $$
= op2
(INTEST
, $1, makearr
($3)); }
225 |
'(' plist
')' IN varname
{ $$
= op2
(INTEST
, $2, makearr
($5)); }
226 | ppattern term %prec CAT
{ $$
= op2
(CAT
, $1, $2); }
228 { $$
= op3
(MATCH
, NIL
, rectonode
(), (Node
*)makedfa
($1, 0)); }
233 var ASGNOP pattern
{ $$
= op2
($2, $1, $3); }
234 | pattern
'?' pattern
':' pattern %prec
'?'
235 { $$
= op3
(CONDEXPR
, notnull
($1), $3, $5); }
236 | pattern bor pattern %prec BOR
237 { $$
= op2
(BOR
, notnull
($1), notnull
($3)); }
238 | pattern and pattern %prec AND
239 { $$
= op2
(AND
, notnull
($1), notnull
($3)); }
241 { $$
= op1
(NOT
, op2
(NE
,$2,valtonode
(lookup
((uchar
*)"$zero&null",symtab
),CCON
))); }
242 | pattern EQ pattern
{ $$
= op2
($2, $1, $3); }
243 | pattern GE pattern
{ $$
= op2
($2, $1, $3); }
244 | pattern GT pattern
{ $$
= op2
($2, $1, $3); }
245 | pattern LE pattern
{ $$
= op2
($2, $1, $3); }
246 | pattern LT pattern
{ $$
= op2
($2, $1, $3); }
247 | pattern NE pattern
{ $$
= op2
($2, $1, $3); }
248 | pattern MATCHOP reg_expr
{ $$
= op3
($2, NIL
, $1, (Node
*)makedfa
($3, 0)); }
249 | pattern MATCHOP pattern
251 $$
= op3
($2, NIL
, $1, (Node
*)makedfa
(strnode
($3), 0));
253 $$
= op3
($2, (Node
*)1, $1, $3); }
254 | pattern IN varname
{ $$
= op2
(INTEST
, $1, makearr
($3)); }
255 |
'(' plist
')' IN varname
{ $$
= op2
(INTEST
, $2, makearr
($5)); }
256 | pattern
'|' GETLINE var
{ $$
= op3
(GETLINE
, $4, (Node
*)$2, $1); }
257 | pattern
'|' GETLINE
{ $$
= op3
(GETLINE
, (Node
*)0, (Node
*)$2, $1); }
258 | pattern term %prec CAT
{ $$
= op2
(CAT
, $1, $2); }
260 { $$
= op3
(MATCH
, NIL
, rectonode
(), (Node
*)makedfa
($1, 0)); }
265 pattern comma pattern
{ $$
= linkum
($1, $3); }
266 | plist comma pattern
{ $$
= linkum
($1, $3); }
271 | pplist comma ppattern
{ $$
= linkum
($1, $3); }
274 /* empty */ { $$
= rectonode
(); }
276 |
'(' plist
')' { $$
= $2; }
284 NL |
';' | pst NL | pst
';'
292 '/' {startreg
();} REGEXPR
'/' { $$
= $3; }
300 print prarg
'|' term
{ $$
= stat3
($1, $2, (Node
*) $3, $4); }
301 | print prarg APPEND term
{ $$
= stat3
($1, $2, (Node
*) $3, $4); }
302 | print prarg GT term
{ $$
= stat3
($1, $2, (Node
*) $3, $4); }
303 | print prarg
{ $$
= stat3
($1, $2, NIL
, NIL
); }
304 | DELETE varname
'[' patlist
']' { $$
= stat2
(DELETE
, makearr
($2), $4); }
305 | DELETE varname
{ yyclearin; ERROR
"you can only delete array[element]" SYNTAX
; $$
= stat1
(DELETE
, $2); }
306 | pattern
{ $$
= exptostat
($1); }
307 |
error { yyclearin; ERROR
"illegal statement" SYNTAX
; }
315 BREAK st
{ $$
= stat1
(BREAK
, NIL
); }
316 | CLOSE pattern st
{ $$
= stat1
(CLOSE
, $2); }
317 | CONTINUE st
{ $$
= stat1
(CONTINUE
, NIL
); }
318 | do stmt WHILE
'(' pattern
')' st
319 { $$
= stat2
(DO
, $2, notnull
($5)); }
320 | EXIT pattern st
{ $$
= stat1
(EXIT
, $2); }
321 | EXIT st
{ $$
= stat1
(EXIT
, NIL
); }
323 | if stmt else stmt
{ $$
= stat3
(IF
, $1, $2, $4); }
324 | if stmt
{ $$
= stat3
(IF
, $1, $2, NIL
); }
325 | lbrace stmtlist rbrace
{ $$
= $2; }
326 | NEXT st
{ if
(infunc
)
327 ERROR
"next is illegal inside a function" SYNTAX
;
328 $$
= stat1
(NEXT
, NIL
); }
329 | RETURN pattern st
{ $$
= stat1
(RETURN
, $2); }
330 | RETURN st
{ $$
= stat1
(RETURN
, NIL
); }
332 | while stmt
{ $$
= stat2
(WHILE
, $1, $2); }
333 |
';' opt_nl
{ $$
= 0; }
338 | stmtlist stmt
{ $$
= linkum
($1, $2); }
346 term
'+' term
{ $$
= op2
(ADD
, $1, $3); }
347 | term
'-' term
{ $$
= op2
(MINUS
, $1, $3); }
348 | term
'*' term
{ $$
= op2
(MULT
, $1, $3); }
349 | term
'/' term
{ $$
= op2
(DIVIDE
, $1, $3); }
350 | term
'%' term
{ $$
= op2
(MOD
, $1, $3); }
351 | term POWER term
{ $$
= op2
(POWER
, $1, $3); }
352 |
'-' term %prec UMINUS
{ $$
= op1
(UMINUS
, $2); }
353 |
'+' term %prec UMINUS
{ $$
= $2; }
354 | BLTIN
'(' ')' { $$
= op2
(BLTIN
, (Node
*) $1, rectonode
()); }
355 | BLTIN
'(' patlist
')' { $$
= op2
(BLTIN
, (Node
*) $1, $3); }
356 | BLTIN
{ $$
= op2
(BLTIN
, (Node
*) $1, rectonode
()); }
357 | CALL
'(' ')' { $$
= op2
(CALL
, valtonode
($1,CVAR
), NIL
); }
358 | CALL
'(' patlist
')' { $$
= op2
(CALL
, valtonode
($1,CVAR
), $3); }
359 | DECR var
{ $$
= op1
(PREDECR
, $2); }
360 | INCR var
{ $$
= op1
(PREINCR
, $2); }
361 | var DECR
{ $$
= op1
(POSTDECR
, $1); }
362 | var INCR
{ $$
= op1
(POSTINCR
, $1); }
363 | GETLINE var LT term
{ $$
= op3
(GETLINE
, $2, (Node
*)$3, $4); }
364 | GETLINE LT term
{ $$
= op3
(GETLINE
, NIL
, (Node
*)$2, $3); }
365 | GETLINE var
{ $$
= op3
(GETLINE
, $2, NIL
, NIL
); }
366 | GETLINE
{ $$
= op3
(GETLINE
, NIL
, NIL
, NIL
); }
367 | INDEX
'(' pattern comma pattern
')'
368 { $$
= op2
(INDEX
, $3, $5); }
369 | INDEX
'(' pattern comma reg_expr
')'
370 { ERROR
"index() doesn't permit regular expressions" SYNTAX
;
371 $$
= op2
(INDEX
, $3, (Node
*)$5); }
372 |
'(' pattern
')' { $$
= $2; }
373 | MATCHFCN
'(' pattern comma reg_expr
')'
374 { $$
= op3
(MATCHFCN
, NIL
, $3, (Node
*)makedfa
($5, 1)); }
375 | MATCHFCN
'(' pattern comma pattern
')'
377 $$
= op3
(MATCHFCN
, NIL
, $3, (Node
*)makedfa
(strnode
($5), 1));
379 $$
= op3
(MATCHFCN
, (Node
*)1, $3, $5); }
380 | NUMBER
{ $$
= valtonode
($1, CCON
); }
381 | SPLIT
'(' pattern comma varname comma pattern
')' /* string */
382 { $$
= op4
(SPLIT
, $3, makearr
($5), $7, (Node
*)STRING
); }
383 | SPLIT
'(' pattern comma varname comma reg_expr
')' /* const /regexp/ */
384 { $$
= op4
(SPLIT
, $3, makearr
($5), (Node
*)makedfa
($7, 1), (Node
*)REGEXPR
); }
385 | SPLIT
'(' pattern comma varname
')'
386 { $$
= op4
(SPLIT
, $3, makearr
($5), NIL
, (Node
*)STRING
); } /* default */
387 | SPRINTF
'(' patlist
')' { $$
= op1
($1, $3); }
388 | STRING
{ $$
= valtonode
($1, CCON
); }
389 | subop
'(' reg_expr comma pattern
')'
390 { $$
= op4
($1, NIL
, (Node
*)makedfa
($3, 1), $5, rectonode
()); }
391 | subop
'(' pattern comma pattern
')'
393 $$
= op4
($1, NIL
, (Node
*)makedfa
(strnode
($3), 1), $5, rectonode
());
395 $$
= op4
($1, (Node
*)1, $3, $5, rectonode
()); }
396 | subop
'(' reg_expr comma pattern comma var
')'
397 { $$
= op4
($1, NIL
, (Node
*)makedfa
($3, 1), $5, $7); }
398 | subop
'(' pattern comma pattern comma var
')'
400 $$
= op4
($1, NIL
, (Node
*)makedfa
(strnode
($3), 1), $5, $7);
402 $$
= op4
($1, (Node
*)1, $3, $5, $7); }
403 | SUBSTR
'(' pattern comma pattern comma pattern
')'
404 { $$
= op3
(SUBSTR
, $3, $5, $7); }
405 | SUBSTR
'(' pattern comma pattern
')'
406 { $$
= op3
(SUBSTR
, $3, $5, NIL
); }
412 | varname
'[' patlist
']' { $$
= op2
(ARRAY
, makearr
($1), $3); }
413 | FIELD
{ $$
= valtonode
($1, CFLD
); }
414 | IVAR
{ $$
= op1
(INDIRECT
, valtonode
($1, CVAR
)); }
415 | INDIRECT term
{ $$
= op1
(INDIRECT
, $2); }
419 /* nothing */ { arglist
= $$
= 0; }
420 | VAR
{ arglist
= $$
= valtonode
($1,CVAR
); }
421 | varlist comma VAR
{ arglist
= $$
= linkum
($1,valtonode
($3,CVAR
)); }
425 VAR
{ $$
= valtonode
($1, CVAR
); }
426 | ARG
{ $$
= op1
(ARG
, (Node
*) $1); }
427 | VARNF
{ $$
= op1
(VARNF
, (Node
*) $1); }
432 WHILE
'(' pattern rparen
{ $$
= notnull
($3); }
441 ERROR
"%s is an array, not a function", p
->nval SYNTAX
;
443 ERROR
"you can't define function %s more than once", p
->nval SYNTAX
;
451 return p
->ntype
== NVALUE
&& ((Cell
*) (p
->narg
[0]))->csub
== CCON
;
457 return
((Cell
*)(p
->narg
[0]))->sval
;
464 case LE
: case LT
: case EQ
: case NE
: case GT
: case GE
:
465 case BOR
: case AND
: case NOT
:
468 return op2
(NE
, n
, nullnode
);