Mercurial > illumos > onarm
comparison usr/src/cmd/awk/awk.g.y @ 0:c9caec207d52 b86
Initial porting based on b86
author | Koji Uno <koji.uno@sun.com> |
---|---|
date | Tue, 02 Jun 2009 18:56:50 +0900 |
parents | |
children | 1a15d5aaf794 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c9caec207d52 |
---|---|
1 %{ | |
2 /* | |
3 * CDDL HEADER START | |
4 * | |
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 | |
8 * with the License. | |
9 * | |
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. | |
14 * | |
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] | |
20 * | |
21 * CDDL HEADER END | |
22 */ | |
23 %} | |
24 /* | |
25 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. | |
26 * Use is subject to license terms. | |
27 */ | |
28 | |
29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ | |
30 /* All Rights Reserved */ | |
31 | |
32 %{ | |
33 #ident "@(#)awk.g.y 1.8 05/07/27 SMI" /* SVr4.0 2.10 */ | |
34 %} | |
35 | |
36 %{ | |
37 #include "awk.h" | |
38 int yywrap(void) { return(1); } | |
39 #ifndef DEBUG | |
40 # define PUTS(x) | |
41 #endif | |
42 Node *beginloc = 0, *endloc = 0; | |
43 int infunc = 0; /* = 1 if in arglist or body of func */ | |
44 uchar *curfname = 0; | |
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(); | |
50 %} | |
51 | |
52 %union { | |
53 Node *p; | |
54 Cell *cp; | |
55 int i; | |
56 uchar *s; | |
57 } | |
58 | |
59 %token <i> FIRSTTOKEN /* must be first */ | |
60 %token <p> PROGRAM PASTAT PASTAT2 XBEGIN XEND | |
61 %token <i> NL ',' '{' '(' '|' ';' '/' ')' '}' '[' ']' | |
62 %token <i> ARRAY | |
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 | |
74 %token <s> REGEXPR | |
75 | |
76 %type <p> pas pattern ppattern plist pplist patlist prarg term | |
77 %type <p> pa_pat pa_stat pa_stats | |
78 %type <s> reg_expr | |
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 | |
83 %type <i> subop print | |
84 | |
85 %right ASGNOP | |
86 %right '?' | |
87 %right ':' | |
88 %left BOR | |
89 %left AND | |
90 %left GETLINE | |
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 '(' | |
96 %left CAT | |
97 %left '+' '-' | |
98 %left '*' '/' '%' | |
99 %left NOT UMINUS | |
100 %right POWER | |
101 %right DECR INCR | |
102 %left INDIRECT | |
103 %token LASTTOKEN /* must be last */ | |
104 | |
105 %% | |
106 | |
107 program: | |
108 pas { if (errorflag==0) | |
109 winner = (Node *)stat3(PROGRAM, beginloc, $1, endloc); } | |
110 | error { yyclearin; bracecheck(); ERROR "bailing out" SYNTAX; } | |
111 ; | |
112 | |
113 and: | |
114 AND | and NL | |
115 ; | |
116 | |
117 bor: | |
118 BOR | bor NL | |
119 ; | |
120 | |
121 comma: | |
122 ',' | comma NL | |
123 ; | |
124 | |
125 do: | |
126 DO | do NL | |
127 ; | |
128 | |
129 else: | |
130 ELSE | else NL | |
131 ; | |
132 | |
133 for: | |
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); } | |
140 ; | |
141 | |
142 funcname: | |
143 VAR { setfname($1); } | |
144 | CALL { setfname($1); } | |
145 ; | |
146 | |
147 if: | |
148 IF '(' pattern rparen { $$ = notnull($3); } | |
149 ; | |
150 | |
151 lbrace: | |
152 '{' | lbrace NL | |
153 ; | |
154 | |
155 nl: | |
156 NL | nl NL | |
157 ; | |
158 | |
159 opt_nl: | |
160 /* empty */ { $$ = 0; } | |
161 | nl | |
162 ; | |
163 | |
164 opt_pst: | |
165 /* empty */ { $$ = 0; } | |
166 | pst | |
167 ; | |
168 | |
169 | |
170 opt_simple_stmt: | |
171 /* empty */ { $$ = 0; } | |
172 | simple_stmt | |
173 ; | |
174 | |
175 pas: | |
176 opt_pst { $$ = 0; } | |
177 | opt_pst pa_stats opt_pst { $$ = $2; } | |
178 ; | |
179 | |
180 pa_pat: | |
181 pattern { $$ = notnull($1); } | |
182 ; | |
183 | |
184 pa_stat: | |
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; } | |
196 ; | |
197 | |
198 pa_stats: | |
199 pa_stat | |
200 | pa_stats opt_pst pa_stat { $$ = linkum($1, $3); } | |
201 ; | |
202 | |
203 patlist: | |
204 pattern | |
205 | patlist comma pattern { $$ = linkum($1, $3); } | |
206 ; | |
207 | |
208 ppattern: | |
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)); } | |
216 | NOT ppattern | |
217 { $$ = op1(NOT, notnull($2)); } | |
218 | ppattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); } | |
219 | ppattern MATCHOP ppattern | |
220 { if (constnode($3)) | |
221 $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0)); | |
222 else | |
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); } | |
227 | reg_expr | |
228 { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); } | |
229 | term | |
230 ; | |
231 | |
232 pattern: | |
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)); } | |
240 | NOT pattern | |
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 | |
250 { if (constnode($3)) | |
251 $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0)); | |
252 else | |
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); } | |
259 | reg_expr | |
260 { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); } | |
261 | term | |
262 ; | |
263 | |
264 plist: | |
265 pattern comma pattern { $$ = linkum($1, $3); } | |
266 | plist comma pattern { $$ = linkum($1, $3); } | |
267 ; | |
268 | |
269 pplist: | |
270 ppattern | |
271 | pplist comma ppattern { $$ = linkum($1, $3); } | |
272 | |
273 prarg: | |
274 /* empty */ { $$ = rectonode(); } | |
275 | pplist | |
276 | '(' plist ')' { $$ = $2; } | |
277 ; | |
278 | |
279 print: | |
280 PRINT | PRINTF | |
281 ; | |
282 | |
283 pst: | |
284 NL | ';' | pst NL | pst ';' | |
285 ; | |
286 | |
287 rbrace: | |
288 '}' | rbrace NL | |
289 ; | |
290 | |
291 reg_expr: | |
292 '/' {startreg();} REGEXPR '/' { $$ = $3; } | |
293 ; | |
294 | |
295 rparen: | |
296 ')' | rparen NL | |
297 ; | |
298 | |
299 simple_stmt: | |
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; } | |
308 ; | |
309 | |
310 st: | |
311 nl | ';' opt_nl | |
312 ; | |
313 | |
314 stmt: | |
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); } | |
322 | for | |
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); } | |
331 | simple_stmt st | |
332 | while stmt { $$ = stat2(WHILE, $1, $2); } | |
333 | ';' opt_nl { $$ = 0; } | |
334 ; | |
335 | |
336 stmtlist: | |
337 stmt | |
338 | stmtlist stmt { $$ = linkum($1, $2); } | |
339 ; | |
340 | |
341 subop: | |
342 SUB | GSUB | |
343 ; | |
344 | |
345 term: | |
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 ')' | |
376 { if (constnode($5)) | |
377 $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa(strnode($5), 1)); | |
378 else | |
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 ')' | |
392 { if (constnode($3)) | |
393 $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, rectonode()); | |
394 else | |
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 ')' | |
399 { if (constnode($3)) | |
400 $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, $7); | |
401 else | |
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); } | |
407 | var | |
408 ; | |
409 | |
410 var: | |
411 varname | |
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); } | |
416 ; | |
417 | |
418 varlist: | |
419 /* nothing */ { arglist = $$ = 0; } | |
420 | VAR { arglist = $$ = valtonode($1,CVAR); } | |
421 | varlist comma VAR { arglist = $$ = linkum($1,valtonode($3,CVAR)); } | |
422 ; | |
423 | |
424 varname: | |
425 VAR { $$ = valtonode($1, CVAR); } | |
426 | ARG { $$ = op1(ARG, (Node *) $1); } | |
427 | VARNF { $$ = op1(VARNF, (Node *) $1); } | |
428 ; | |
429 | |
430 | |
431 while: | |
432 WHILE '(' pattern rparen { $$ = notnull($3); } | |
433 ; | |
434 | |
435 %% | |
436 | |
437 static void | |
438 setfname(Cell *p) | |
439 { | |
440 if (isarr(p)) | |
441 ERROR "%s is an array, not a function", p->nval SYNTAX; | |
442 else if (isfunc(p)) | |
443 ERROR "you can't define function %s more than once", p->nval SYNTAX; | |
444 curfname = p->nval; | |
445 } | |
446 | |
447 | |
448 static int | |
449 constnode(Node *p) | |
450 { | |
451 return p->ntype == NVALUE && ((Cell *) (p->narg[0]))->csub == CCON; | |
452 } | |
453 | |
454 static uchar * | |
455 strnode(Node *p) | |
456 { | |
457 return ((Cell *)(p->narg[0]))->sval; | |
458 } | |
459 | |
460 static Node * | |
461 notnull(Node *n) | |
462 { | |
463 switch (n->nobj) { | |
464 case LE: case LT: case EQ: case NE: case GT: case GE: | |
465 case BOR: case AND: case NOT: | |
466 return n; | |
467 default: | |
468 return op2(NE, n, nullnode); | |
469 } | |
470 } |