Print this page
3731 Update nawk to version 20121220
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/awk/awk.g.y
+++ new/usr/src/cmd/awk/awk.g.y
1 1 %{
2 2 /*
3 3 * CDDL HEADER START
4 4 *
5 5 * The contents of this file are subject to the terms of the
6 6 * Common Development and Distribution License, Version 1.0 only
7 7 * (the "License"). You may not use this file except in compliance
8 8 * with the License.
9 9 *
10 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 11 * or http://www.opensolaris.org/os/licensing.
12 12 * See the License for the specific language governing permissions
13 13 * and limitations under the License.
14 14 *
15 15 * When distributing Covered Code, include this CDDL HEADER in each
16 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 17 * If applicable, add the following below this CDDL HEADER, with the
18 18 * fields enclosed by brackets "[]" replaced with your own identifying
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
19 19 * information: Portions Copyright [yyyy] [name of copyright owner]
20 20 *
21 21 * CDDL HEADER END
22 22 */
23 23 %}
24 24 /*
25 25 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
26 26 * Use is subject to license terms.
27 27 */
28 28
29 -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 -/* All Rights Reserved */
29 +/*
30 + * Copyright (C) Lucent Technologies 1997
31 + * All Rights Reserved
32 + *
33 + * Permission to use, copy, modify, and distribute this software and
34 + * its documentation for any purpose and without fee is hereby
35 + * granted, provided that the above copyright notice appear in all
36 + * copies and that both that the copyright notice and this
37 + * permission notice and warranty disclaimer appear in supporting
38 + * documentation, and that the name Lucent Technologies or any of
39 + * its entities not be used in advertising or publicity pertaining
40 + * to distribution of the software without specific, written prior
41 + * permission.
42 + *
43 + * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
44 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
45 + * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
46 + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
47 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
48 + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
49 + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
50 + * THIS SOFTWARE.
51 + */
31 52
32 53 %{
33 -#ident "%Z%%M% %I% %E% SMI" /* SVr4.0 2.10 */
34 54 %}
35 55
36 56 %{
37 57 #include "awk.h"
38 58 int yywrap(void) { return(1); }
39 -#ifndef DEBUG
40 -# define PUTS(x)
41 -#endif
42 -Node *beginloc = 0, *endloc = 0;
59 +
60 +Node *beginloc = 0;
61 +Node *endloc = 0;
43 62 int infunc = 0; /* = 1 if in arglist or body of func */
44 -uchar *curfname = 0;
63 +int inloop = 0; /* = 1 if in while, for, do */
64 +uchar *curfname = 0; /* current function name */
45 65 Node *arglist = 0; /* list of args for current function */
46 66 static void setfname(Cell *);
47 67 static int constnode(Node *);
48 68 static uchar *strnode(Node *);
49 69 static Node *notnull();
50 70 %}
51 71
52 72 %union {
53 73 Node *p;
54 74 Cell *cp;
55 75 int i;
56 76 uchar *s;
57 77 }
58 78
59 79 %token <i> FIRSTTOKEN /* must be first */
60 80 %token <p> PROGRAM PASTAT PASTAT2 XBEGIN XEND
61 81 %token <i> NL ',' '{' '(' '|' ';' '/' ')' '}' '[' ']'
62 82 %token <i> ARRAY
63 83 %token <i> MATCH NOTMATCH MATCHOP
64 -%token <i> FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS
84 +%token <i> FINAL DOT ALL CCL NCCL CHAR OR STAR QUEST PLUS EMPTYRE
65 85 %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
86 +%token <i> ARG BLTIN BREAK CLOSE CONTINUE DELETE DO EXIT FOR FUNC
87 +%token <i> SUB GSUB IF INDEX LSUBSTR MATCHFCN NEXT NEXTFILE
68 88 %token <i> ADD MINUS MULT DIVIDE MOD
69 89 %token <i> ASSIGN ASGNOP ADDEQ SUBEQ MULTEQ DIVEQ MODEQ POWEQ
70 90 %token <i> PRINT PRINTF SPRINTF
71 91 %token <p> ELSE INTEST CONDEXPR
72 92 %token <i> POSTINCR PREINCR POSTDECR PREDECR
73 -%token <cp> VAR IVAR VARNF CALL NUMBER STRING FIELD
93 +%token <cp> VAR IVAR VARNF CALL NUMBER STRING
74 94 %token <s> REGEXPR
75 95
76 -%type <p> pas pattern ppattern plist pplist patlist prarg term
96 +%type <p> pas pattern ppattern plist pplist patlist prarg term re
77 97 %type <p> pa_pat pa_stat pa_stats
78 98 %type <s> reg_expr
79 99 %type <p> simple_stmt opt_simple_stmt stmt stmtlist
80 100 %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
101 +%type <p> for if else while
102 +%type <i> do st
103 +%type <i> pst opt_pst lbrace rbrace rparen comma nl opt_nl and bor
83 104 %type <i> subop print
84 105
85 106 %right ASGNOP
86 107 %right '?'
87 108 %right ':'
88 109 %left BOR
89 110 %left AND
90 111 %left GETLINE
91 112 %nonassoc APPEND EQ GE GT LE LT NE MATCHOP IN '|'
92 -%left ARG BLTIN BREAK CALL CLOSE CONTINUE DELETE DO EXIT FOR FIELD FUNC
113 +%left ARG BLTIN BREAK CALL CLOSE CONTINUE DELETE DO EXIT FOR FUNC
93 114 %left GSUB IF INDEX LSUBSTR MATCHFCN NEXT NUMBER
94 115 %left PRINT PRINTF RETURN SPLIT SPRINTF STRING SUB SUBSTR
95 116 %left REGEXPR VAR VARNF IVAR WHILE '('
96 117 %left CAT
97 118 %left '+' '-'
98 119 %left '*' '/' '%'
99 120 %left NOT UMINUS
100 121 %right POWER
101 122 %right DECR INCR
102 123 %left INDIRECT
103 124 %token LASTTOKEN /* must be last */
104 125
105 126 %%
106 127
107 128 program:
108 129 pas { if (errorflag==0)
109 130 winner = (Node *)stat3(PROGRAM, beginloc, $1, endloc); }
110 - | error { yyclearin; bracecheck(); ERROR "bailing out" SYNTAX; }
131 + | error { yyclearin; bracecheck(); SYNTAX("bailing out"); }
111 132 ;
112 133
113 134 and:
114 135 AND | and NL
115 136 ;
116 137
117 138 bor:
118 139 BOR | bor NL
119 140 ;
120 141
121 142 comma:
122 143 ',' | comma NL
123 144 ;
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
124 145
125 146 do:
126 147 DO | do NL
127 148 ;
128 149
129 150 else:
130 151 ELSE | else NL
131 152 ;
132 153
133 154 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); }
155 + FOR '(' opt_simple_stmt ';' opt_nl pattern ';' opt_nl opt_simple_stmt rparen {inloop++;} stmt
156 + { --inloop; $$ = stat4(FOR, $3, notnull($6), $9, $12); }
157 + | FOR '(' opt_simple_stmt ';' ';' opt_nl opt_simple_stmt rparen {inloop++;} stmt
158 + { --inloop; $$ = stat4(FOR, $3, NIL, $7, $10); }
159 + | FOR '(' varname IN varname rparen {inloop++;} stmt
160 + { --inloop; $$ = stat3(IN, $3, makearr($5), $8); }
140 161 ;
141 162
142 163 funcname:
143 164 VAR { setfname($1); }
144 165 | CALL { setfname($1); }
145 166 ;
146 167
147 168 if:
148 169 IF '(' pattern rparen { $$ = notnull($3); }
149 170 ;
150 171
151 172 lbrace:
152 173 '{' | lbrace NL
153 174 ;
154 175
155 176 nl:
156 177 NL | nl NL
157 178 ;
158 179
159 180 opt_nl:
160 181 /* empty */ { $$ = 0; }
161 182 | nl
162 183 ;
163 184
164 185 opt_pst:
165 186 /* empty */ { $$ = 0; }
166 187 | pst
167 188 ;
168 189
169 190
170 191 opt_simple_stmt:
171 192 /* empty */ { $$ = 0; }
172 193 | simple_stmt
173 194 ;
174 195
175 196 pas:
176 197 opt_pst { $$ = 0; }
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
177 198 | opt_pst pa_stats opt_pst { $$ = $2; }
178 199 ;
179 200
180 201 pa_pat:
181 202 pattern { $$ = notnull($1); }
182 203 ;
183 204
184 205 pa_stat:
185 206 pa_pat { $$ = stat2(PASTAT, $1, stat2(PRINT, rectonode(), NIL)); }
186 207 | 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); }
208 + | pa_pat ',' opt_nl pa_pat { $$ = pa2stat($1, $4, stat2(PRINT, rectonode(), NIL)); }
209 + | pa_pat ',' opt_nl pa_pat lbrace stmtlist '}' { $$ = pa2stat($1, $4, $6); }
189 210 | lbrace stmtlist '}' { $$ = stat2(PASTAT, NIL, $2); }
190 211 | XBEGIN lbrace stmtlist '}'
191 212 { beginloc = linkum(beginloc, $3); $$ = 0; }
192 213 | XEND lbrace stmtlist '}'
193 214 { endloc = linkum(endloc, $3); $$ = 0; }
194 215 | FUNC funcname '(' varlist rparen {infunc++;} lbrace stmtlist '}'
195 216 { infunc--; curfname=0; defn((Cell *)$2, $4, $8); $$ = 0; }
196 217 ;
197 218
198 219 pa_stats:
199 220 pa_stat
200 221 | pa_stats opt_pst pa_stat { $$ = linkum($1, $3); }
201 222 ;
202 223
203 224 patlist:
204 225 pattern
205 - | patlist comma pattern { $$ = linkum($1, $3); }
226 + | patlist comma pattern { $$ = linkum($1, $3); }
206 227 ;
207 228
208 229 ppattern:
209 230 var ASGNOP ppattern { $$ = op2($2, $1, $3); }
210 231 | ppattern '?' ppattern ':' ppattern %prec '?'
211 232 { $$ = op3(CONDEXPR, notnull($1), $3, $5); }
212 233 | ppattern bor ppattern %prec BOR
213 234 { $$ = op2(BOR, notnull($1), notnull($3)); }
214 235 | ppattern and ppattern %prec AND
215 236 { $$ = op2(AND, notnull($1), notnull($3)); }
216 - | NOT ppattern
217 - { $$ = op1(NOT, notnull($2)); }
218 237 | ppattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
219 238 | ppattern MATCHOP ppattern
220 239 { if (constnode($3))
221 240 $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
222 241 else
223 242 $$ = op3($2, (Node *)1, $1, $3); }
224 243 | ppattern IN varname { $$ = op2(INTEST, $1, makearr($3)); }
225 244 | '(' plist ')' IN varname { $$ = op2(INTEST, $2, makearr($5)); }
226 245 | ppattern term %prec CAT { $$ = op2(CAT, $1, $2); }
227 - | reg_expr
228 - { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); }
246 + | re
229 247 | term
230 248 ;
231 249
232 250 pattern:
233 251 var ASGNOP pattern { $$ = op2($2, $1, $3); }
234 252 | pattern '?' pattern ':' pattern %prec '?'
235 253 { $$ = op3(CONDEXPR, notnull($1), $3, $5); }
236 254 | pattern bor pattern %prec BOR
237 255 { $$ = op2(BOR, notnull($1), notnull($3)); }
238 256 | pattern and pattern %prec AND
239 257 { $$ = op2(AND, notnull($1), notnull($3)); }
240 - | NOT pattern
241 - { $$ = op1(NOT, op2(NE,$2,valtonode(lookup((uchar *)"$zero&null",symtab),CCON))); }
242 258 | pattern EQ pattern { $$ = op2($2, $1, $3); }
243 259 | pattern GE pattern { $$ = op2($2, $1, $3); }
244 260 | pattern GT pattern { $$ = op2($2, $1, $3); }
245 261 | pattern LE pattern { $$ = op2($2, $1, $3); }
246 262 | pattern LT pattern { $$ = op2($2, $1, $3); }
247 263 | pattern NE pattern { $$ = op2($2, $1, $3); }
248 264 | pattern MATCHOP reg_expr { $$ = op3($2, NIL, $1, (Node*)makedfa($3, 0)); }
249 265 | pattern MATCHOP pattern
250 266 { if (constnode($3))
251 267 $$ = op3($2, NIL, $1, (Node*)makedfa(strnode($3), 0));
252 268 else
253 269 $$ = op3($2, (Node *)1, $1, $3); }
254 270 | pattern IN varname { $$ = op2(INTEST, $1, makearr($3)); }
255 271 | '(' 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); }
272 + | pattern '|' GETLINE var {
273 + if (safe) SYNTAX("cmd | getline is unsafe");
274 + else $$ = op3(GETLINE, $4, itonp($2), $1); }
275 + | pattern '|' GETLINE {
276 + if (safe) SYNTAX("cmd | getline is unsafe");
277 + else $$ = op3(GETLINE, (Node*)0, itonp($2), $1); }
258 278 | pattern term %prec CAT { $$ = op2(CAT, $1, $2); }
259 - | reg_expr
260 - { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); }
279 + | re
261 280 | term
262 281 ;
263 282
264 283 plist:
265 284 pattern comma pattern { $$ = linkum($1, $3); }
266 285 | plist comma pattern { $$ = linkum($1, $3); }
267 286 ;
268 287
269 288 pplist:
270 289 ppattern
271 290 | pplist comma ppattern { $$ = linkum($1, $3); }
272 291
273 292 prarg:
274 293 /* empty */ { $$ = rectonode(); }
275 294 | pplist
276 295 | '(' plist ')' { $$ = $2; }
277 296 ;
278 297
279 298 print:
280 299 PRINT | PRINTF
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
281 300 ;
282 301
283 302 pst:
284 303 NL | ';' | pst NL | pst ';'
285 304 ;
286 305
287 306 rbrace:
288 307 '}' | rbrace NL
289 308 ;
290 309
310 +re:
311 + reg_expr
312 + { $$ = op3(MATCH, NIL, rectonode(), (Node*)makedfa($1, 0)); }
313 + | NOT re { $$ = op1(NOT, notnull($2)); }
314 + ;
315 +
291 316 reg_expr:
292 317 '/' {startreg();} REGEXPR '/' { $$ = $3; }
293 318 ;
294 319
295 320 rparen:
296 321 ')' | rparen NL
297 322 ;
298 323
299 324 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); }
325 + print prarg '|' term {
326 + if (safe) SYNTAX("print | is unsafe");
327 + else $$ = stat3($1, $2, itonp($3), $4); }
328 + | print prarg APPEND term {
329 + if (safe) SYNTAX("print >> is unsafe");
330 + else $$ = stat3($1, $2, itonp($3), $4); }
331 + | print prarg GT term {
332 + if (safe) SYNTAX("print > is unsafe");
333 + else $$ = stat3($1, $2, itonp($3), $4); }
303 334 | print prarg { $$ = stat3($1, $2, NIL, NIL); }
304 335 | DELETE varname '[' patlist ']' { $$ = stat2(DELETE, makearr($2), $4); }
305 - | DELETE varname { yyclearin; ERROR "you can only delete array[element]" SYNTAX; $$ = stat1(DELETE, $2); }
336 + | DELETE varname { $$ = stat2(DELETE, makearr($2), 0); }
306 337 | pattern { $$ = exptostat($1); }
307 - | error { yyclearin; ERROR "illegal statement" SYNTAX; }
338 + | error { yyclearin; SYNTAX("illegal statement"); }
308 339 ;
309 340
310 341 st:
311 - nl | ';' opt_nl
342 + nl
343 + | ';' opt_nl
312 344 ;
313 345
314 346 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)); }
347 + BREAK st {
348 + if (!inloop) SYNTAX("break illegal outside of loops");
349 + $$ = stat1(BREAK, NIL); }
350 + | CONTINUE st {
351 + if (!inloop) SYNTAX("continue illegal outside of loops");
352 + $$ = stat1(CONTINUE, NIL); }
353 + | do {inloop++;} stmt {--inloop;} WHILE '(' pattern ')' st
354 + { $$ = stat2(DO, $3, notnull($7)); }
320 355 | EXIT pattern st { $$ = stat1(EXIT, $2); }
321 356 | EXIT st { $$ = stat1(EXIT, NIL); }
322 357 | for
323 358 | if stmt else stmt { $$ = stat3(IF, $1, $2, $4); }
324 359 | if stmt { $$ = stat3(IF, $1, $2, NIL); }
325 360 | lbrace stmtlist rbrace { $$ = $2; }
326 361 | NEXT st { if (infunc)
327 - ERROR "next is illegal inside a function" SYNTAX;
362 + SYNTAX("next is illegal inside a function");
328 363 $$ = stat1(NEXT, NIL); }
364 + | NEXTFILE st { if (infunc)
365 + SYNTAX("nextfile is illegal inside a function");
366 + $$ = stat1(NEXTFILE, NIL); }
329 367 | RETURN pattern st { $$ = stat1(RETURN, $2); }
330 368 | RETURN st { $$ = stat1(RETURN, NIL); }
331 369 | simple_stmt st
332 - | while stmt { $$ = stat2(WHILE, $1, $2); }
370 + | while {inloop++;} stmt { --inloop; $$ = stat2(WHILE, $1, $3); }
333 371 | ';' opt_nl { $$ = 0; }
334 372 ;
335 373
336 374 stmtlist:
337 375 stmt
338 376 | stmtlist stmt { $$ = linkum($1, $2); }
339 377 ;
340 378
341 379 subop:
342 380 SUB | GSUB
343 381 ;
344 382
345 383 term:
346 - term '+' term { $$ = op2(ADD, $1, $3); }
384 + term '/' ASGNOP term { $$ = op2(DIVEQ, $1, $4); }
385 + | term '+' term { $$ = op2(ADD, $1, $3); }
347 386 | term '-' term { $$ = op2(MINUS, $1, $3); }
348 387 | term '*' term { $$ = op2(MULT, $1, $3); }
349 388 | term '/' term { $$ = op2(DIVIDE, $1, $3); }
350 389 | term '%' term { $$ = op2(MOD, $1, $3); }
351 390 | term POWER term { $$ = op2(POWER, $1, $3); }
352 391 | '-' term %prec UMINUS { $$ = op1(UMINUS, $2); }
353 392 | '+' 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); }
393 + | NOT term %prec UMINUS { $$ = op1(NOT, notnull($2)); }
394 + | BLTIN '(' ')' { $$ = op2(BLTIN, itonp($1), rectonode()); }
395 + | BLTIN '(' patlist ')' { $$ = op2(BLTIN, itonp($1), $3); }
396 + | BLTIN { $$ = op2(BLTIN, itonp($1), rectonode()); }
397 + | CALL '(' ')' { $$ = op2(CALL, celltonode($1,CVAR), NIL); }
398 + | CALL '(' patlist ')' { $$ = op2(CALL, celltonode($1,CVAR), $3); }
399 + | CLOSE term { $$ = op1(CLOSE, $2); }
359 400 | DECR var { $$ = op1(PREDECR, $2); }
360 401 | INCR var { $$ = op1(PREINCR, $2); }
361 402 | var DECR { $$ = op1(POSTDECR, $1); }
362 403 | 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); }
404 + | GETLINE var LT term { $$ = op3(GETLINE, $2, itonp($3), $4); }
405 + | GETLINE LT term { $$ = op3(GETLINE, NIL, itonp($2), $3); }
365 406 | GETLINE var { $$ = op3(GETLINE, $2, NIL, NIL); }
366 407 | GETLINE { $$ = op3(GETLINE, NIL, NIL, NIL); }
367 408 | INDEX '(' pattern comma pattern ')'
368 409 { $$ = op2(INDEX, $3, $5); }
369 410 | INDEX '(' pattern comma reg_expr ')'
370 - { ERROR "index() doesn't permit regular expressions" SYNTAX;
411 + { SYNTAX("index() doesn't permit regular expressions");
412 + /* LINTED align */
371 413 $$ = op2(INDEX, $3, (Node*)$5); }
372 414 | '(' pattern ')' { $$ = $2; }
373 415 | MATCHFCN '(' pattern comma reg_expr ')'
374 416 { $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa($5, 1)); }
375 417 | MATCHFCN '(' pattern comma pattern ')'
376 418 { if (constnode($5))
377 419 $$ = op3(MATCHFCN, NIL, $3, (Node*)makedfa(strnode($5), 1));
378 420 else
379 421 $$ = op3(MATCHFCN, (Node *)1, $3, $5); }
380 - | NUMBER { $$ = valtonode($1, CCON); }
422 + | NUMBER { $$ = celltonode($1, CCON); }
381 423 | SPLIT '(' pattern comma varname comma pattern ')' /* string */
382 424 { $$ = op4(SPLIT, $3, makearr($5), $7, (Node*)STRING); }
383 425 | SPLIT '(' pattern comma varname comma reg_expr ')' /* const /regexp/ */
384 426 { $$ = op4(SPLIT, $3, makearr($5), (Node*)makedfa($7, 1), (Node *)REGEXPR); }
385 427 | SPLIT '(' pattern comma varname ')'
386 428 { $$ = op4(SPLIT, $3, makearr($5), NIL, (Node*)STRING); } /* default */
387 429 | SPRINTF '(' patlist ')' { $$ = op1($1, $3); }
388 - | STRING { $$ = valtonode($1, CCON); }
430 + | STRING { $$ = celltonode($1, CCON); }
389 431 | subop '(' reg_expr comma pattern ')'
390 432 { $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, rectonode()); }
391 433 | subop '(' pattern comma pattern ')'
392 434 { if (constnode($3))
393 435 $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, rectonode());
394 436 else
395 437 $$ = op4($1, (Node *)1, $3, $5, rectonode()); }
396 438 | subop '(' reg_expr comma pattern comma var ')'
397 439 { $$ = op4($1, NIL, (Node*)makedfa($3, 1), $5, $7); }
398 440 | subop '(' pattern comma pattern comma var ')'
399 441 { if (constnode($3))
400 442 $$ = op4($1, NIL, (Node*)makedfa(strnode($3), 1), $5, $7);
401 443 else
402 444 $$ = op4($1, (Node *)1, $3, $5, $7); }
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
403 445 | SUBSTR '(' pattern comma pattern comma pattern ')'
404 446 { $$ = op3(SUBSTR, $3, $5, $7); }
405 447 | SUBSTR '(' pattern comma pattern ')'
406 448 { $$ = op3(SUBSTR, $3, $5, NIL); }
407 449 | var
408 450 ;
409 451
410 452 var:
411 453 varname
412 454 | varname '[' patlist ']' { $$ = op2(ARRAY, makearr($1), $3); }
413 - | FIELD { $$ = valtonode($1, CFLD); }
414 - | IVAR { $$ = op1(INDIRECT, valtonode($1, CVAR)); }
455 + | IVAR { $$ = op1(INDIRECT, celltonode($1, CVAR)); }
415 456 | INDIRECT term { $$ = op1(INDIRECT, $2); }
416 457 ;
417 458
418 459 varlist:
419 460 /* nothing */ { arglist = $$ = 0; }
420 - | VAR { arglist = $$ = valtonode($1,CVAR); }
421 - | varlist comma VAR { arglist = $$ = linkum($1,valtonode($3,CVAR)); }
461 + | VAR { arglist = $$ = celltonode($1,CVAR); }
462 + | varlist comma VAR {
463 + checkdup($1, $3);
464 + arglist = $$ = linkum($1,celltonode($3,CVAR)); }
422 465 ;
423 466
424 467 varname:
425 - VAR { $$ = valtonode($1, CVAR); }
426 - | ARG { $$ = op1(ARG, (Node *) $1); }
468 + VAR { $$ = celltonode($1, CVAR); }
469 + | ARG { $$ = op1(ARG, itonp($1)); }
427 470 | VARNF { $$ = op1(VARNF, (Node *) $1); }
428 471 ;
429 472
430 473
431 474 while:
432 475 WHILE '(' pattern rparen { $$ = notnull($3); }
433 476 ;
434 477
435 478 %%
436 479
437 480 static void
438 481 setfname(Cell *p)
439 482 {
440 483 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;
484 + SYNTAX("%s is an array, not a function", p->nval);
485 + else if (isfcn(p))
486 + SYNTAX("you can't define function %s more than once", p->nval);
444 487 curfname = p->nval;
445 488 }
446 489
447 490
448 491 static int
449 492 constnode(Node *p)
450 493 {
451 - return p->ntype == NVALUE && ((Cell *) (p->narg[0]))->csub == CCON;
494 + return (isvalue(p) && ((Cell *) (p->narg[0]))->csub == CCON);
452 495 }
453 496
454 497 static uchar *
455 498 strnode(Node *p)
456 499 {
457 - return ((Cell *)(p->narg[0]))->sval;
500 + return (((Cell *)(p->narg[0]))->sval);
458 501 }
459 502
460 503 static Node *
461 504 notnull(Node *n)
462 505 {
463 506 switch (n->nobj) {
464 507 case LE: case LT: case EQ: case NE: case GT: case GE:
465 508 case BOR: case AND: case NOT:
466 - return n;
509 + return (n);
467 510 default:
468 - return op2(NE, n, nullnode);
511 + return (op2(NE, n, nullnode));
512 + }
513 +}
514 +
515 +static void
516 +checkdup(Node *vl, Cell *cp) /* check if name already in list */
517 +{
518 + uchar *s = cp->nval;
519 +
520 + for (; vl; vl = vl->nnext) {
521 + if (strcmp((char *)s, (char *)((Cell *)(vl->narg[0]))->nval) == 0) {
522 + SYNTAX("duplicate argument %s", s);
523 + break;
524 + }
469 525 }
470 526 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX