source: vendor/gawk/3.1.5/awkgram.c@ 3513

Last change on this file since 3513 was 3076, checked in by bird, 18 years ago

gawk 3.1.5

File size: 144.9 KB
Line 
1/* A Bison parser, made by GNU Bison 2.0. */
2
3/* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21/* As a special exception, when this file is copied by Bison into a
22 Bison output file, you may use that output file without restriction.
23 This special exception was added by the Free Software Foundation
24 in version 1.24 of Bison. */
25
26/* Written by Richard Stallman by simplifying the original so called
27 ``semantic'' parser. */
28
29/* All symbols defined below should begin with yy or YY, to avoid
30 infringing on user name space. This should be done even for local
31 variables, as they might otherwise be expanded by user macros.
32 There are some unavoidable exceptions within include files to
33 define necessary library symbols; they are noted "INFRINGES ON
34 USER NAME SPACE" below. */
35
36/* Identify Bison output. */
37#define YYBISON 1
38
39/* Skeleton name. */
40#define YYSKELETON_NAME "yacc.c"
41
42/* Pure parsers. */
43#define YYPURE 0
44
45/* Using locations. */
46#define YYLSP_NEEDED 0
47
48
49
50/* Tokens. */
51#ifndef YYTOKENTYPE
52# define YYTOKENTYPE
53 /* Put the tokens into the symbol table, so that GDB and other debuggers
54 know about them. */
55 enum yytokentype {
56 FUNC_CALL = 258,
57 NAME = 259,
58 REGEXP = 260,
59 ERROR = 261,
60 YNUMBER = 262,
61 YSTRING = 263,
62 RELOP = 264,
63 IO_OUT = 265,
64 IO_IN = 266,
65 ASSIGNOP = 267,
66 ASSIGN = 268,
67 MATCHOP = 269,
68 CONCAT_OP = 270,
69 LEX_BEGIN = 271,
70 LEX_END = 272,
71 LEX_IF = 273,
72 LEX_ELSE = 274,
73 LEX_RETURN = 275,
74 LEX_DELETE = 276,
75 LEX_SWITCH = 277,
76 LEX_CASE = 278,
77 LEX_DEFAULT = 279,
78 LEX_WHILE = 280,
79 LEX_DO = 281,
80 LEX_FOR = 282,
81 LEX_BREAK = 283,
82 LEX_CONTINUE = 284,
83 LEX_PRINT = 285,
84 LEX_PRINTF = 286,
85 LEX_NEXT = 287,
86 LEX_EXIT = 288,
87 LEX_FUNCTION = 289,
88 LEX_GETLINE = 290,
89 LEX_NEXTFILE = 291,
90 LEX_IN = 292,
91 LEX_AND = 293,
92 LEX_OR = 294,
93 INCREMENT = 295,
94 DECREMENT = 296,
95 LEX_BUILTIN = 297,
96 LEX_LENGTH = 298,
97 NEWLINE = 299,
98 SLASH_BEFORE_EQUAL = 300,
99 UNARY = 301
100 };
101#endif
102#define FUNC_CALL 258
103#define NAME 259
104#define REGEXP 260
105#define ERROR 261
106#define YNUMBER 262
107#define YSTRING 263
108#define RELOP 264
109#define IO_OUT 265
110#define IO_IN 266
111#define ASSIGNOP 267
112#define ASSIGN 268
113#define MATCHOP 269
114#define CONCAT_OP 270
115#define LEX_BEGIN 271
116#define LEX_END 272
117#define LEX_IF 273
118#define LEX_ELSE 274
119#define LEX_RETURN 275
120#define LEX_DELETE 276
121#define LEX_SWITCH 277
122#define LEX_CASE 278
123#define LEX_DEFAULT 279
124#define LEX_WHILE 280
125#define LEX_DO 281
126#define LEX_FOR 282
127#define LEX_BREAK 283
128#define LEX_CONTINUE 284
129#define LEX_PRINT 285
130#define LEX_PRINTF 286
131#define LEX_NEXT 287
132#define LEX_EXIT 288
133#define LEX_FUNCTION 289
134#define LEX_GETLINE 290
135#define LEX_NEXTFILE 291
136#define LEX_IN 292
137#define LEX_AND 293
138#define LEX_OR 294
139#define INCREMENT 295
140#define DECREMENT 296
141#define LEX_BUILTIN 297
142#define LEX_LENGTH 298
143#define NEWLINE 299
144#define SLASH_BEFORE_EQUAL 300
145#define UNARY 301
146
147
148
149
150/* Copy the first part of user declarations. */
151#line 26 "awkgram.y"
152
153#ifdef GAWKDEBUG
154#define YYDEBUG 12
155#endif
156
157#include "awk.h"
158
159#define CAN_FREE TRUE
160#define DONT_FREE FALSE
161
162#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
163static void yyerror(const char *m, ...) ATTRIBUTE_PRINTF_1;
164#else
165static void yyerror(); /* va_alist */
166#endif
167static char *get_src_buf P((void));
168static int yylex P((void));
169static NODE *node_common P((NODETYPE op));
170static NODE *snode P((NODE *subn, NODETYPE op, int sindex));
171static NODE *make_for_loop P((NODE *init, NODE *cond, NODE *incr));
172static NODE *append_right P((NODE *list, NODE *new));
173static inline NODE *append_pattern P((NODE **list, NODE *patt));
174static void func_install P((NODE *params, NODE *def));
175static void pop_var P((NODE *np, int freeit));
176static void pop_params P((NODE *params));
177static NODE *make_param P((char *name));
178static NODE *mk_rexp P((NODE *exp));
179static int dup_parms P((NODE *func));
180static void param_sanity P((NODE *arglist));
181static int parms_shadow P((const char *fname, NODE *func));
182static int isnoeffect P((NODETYPE t));
183static int isassignable P((NODE *n));
184static void dumpintlstr P((const char *str, size_t len));
185static void dumpintlstr2 P((const char *str1, size_t len1, const char *str2, size_t len2));
186static void count_args P((NODE *n));
187static int isarray P((NODE *n));
188
189enum defref { FUNC_DEFINE, FUNC_USE };
190static void func_use P((const char *name, enum defref how));
191static void check_funcs P((void));
192
193static int want_regexp; /* lexical scanning kludge */
194static int can_return; /* parsing kludge */
195static int begin_or_end_rule = FALSE; /* parsing kludge */
196static int parsing_end_rule = FALSE; /* for warnings */
197static int in_print = FALSE; /* lexical scanning kludge for print */
198static int in_parens = 0; /* lexical scanning kludge for print */
199static char *lexptr; /* pointer to next char during parsing */
200static char *lexend;
201static char *lexptr_begin; /* keep track of where we were for error msgs */
202static char *lexeme; /* beginning of lexeme for debugging */
203static char *thisline = NULL;
204#define YYDEBUG_LEXER_TEXT (lexeme)
205static int param_counter;
206static char *tokstart = NULL;
207static char *tok = NULL;
208static char *tokend;
209
210static long func_count; /* total number of functions */
211
212#define HASHSIZE 1021 /* this constant only used here */
213NODE *variables[HASHSIZE];
214static int var_count; /* total number of global variables */
215
216extern char *source;
217extern int sourceline;
218extern struct src *srcfiles;
219extern long numfiles;
220extern int errcount;
221extern NODE *begin_block;
222extern NODE *end_block;
223
224/*
225 * This string cannot occur as a real awk identifier.
226 * Use it as a special token to make function parsing
227 * uniform, but if it's seen, don't install the function.
228 * e.g.
229 * function split(x) { return x }
230 * function x(a) { return a }
231 * should only produce one error message, and not core dump.
232 */
233static char builtin_func[] = "@builtin";
234
235
236/* Enabling traces. */
237#ifndef YYDEBUG
238# define YYDEBUG 0
239#endif
240
241/* Enabling verbose error messages. */
242#ifdef YYERROR_VERBOSE
243# undef YYERROR_VERBOSE
244# define YYERROR_VERBOSE 1
245#else
246# define YYERROR_VERBOSE 0
247#endif
248
249#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
250#line 110 "awkgram.y"
251typedef union YYSTYPE {
252 long lval;
253 AWKNUM fval;
254 NODE *nodeval;
255 NODETYPE nodetypeval;
256 char *sval;
257 NODE *(*ptrval) P((void));
258} YYSTYPE;
259/* Line 190 of yacc.c. */
260#line 261 "y.tab.c"
261# define yystype YYSTYPE /* obsolescent; will be withdrawn */
262# define YYSTYPE_IS_DECLARED 1
263# define YYSTYPE_IS_TRIVIAL 1
264#endif
265
266
267
268/* Copy the second part of user declarations. */
269
270
271/* Line 213 of yacc.c. */
272#line 273 "y.tab.c"
273
274#if ! defined (yyoverflow) || YYERROR_VERBOSE
275
276# ifndef YYFREE
277# define YYFREE free
278# endif
279# ifndef YYMALLOC
280# define YYMALLOC malloc
281# endif
282
283/* The parser invokes alloca or malloc; define the necessary symbols. */
284
285# ifdef YYSTACK_USE_ALLOCA
286# if YYSTACK_USE_ALLOCA
287# ifdef __GNUC__
288# define YYSTACK_ALLOC __builtin_alloca
289# else
290# define YYSTACK_ALLOC alloca
291# endif
292# endif
293# endif
294
295# ifdef YYSTACK_ALLOC
296 /* Pacify GCC's `empty if-body' warning. */
297# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
298# else
299# if defined (__STDC__) || defined (__cplusplus)
300# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
301# define YYSIZE_T size_t
302# endif
303# define YYSTACK_ALLOC YYMALLOC
304# define YYSTACK_FREE YYFREE
305# endif
306#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
307
308
309#if (! defined (yyoverflow) && (! defined (__cplusplus) || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
310
311/* A type that is properly aligned for any stack member. */
312union yyalloc
313{
314 short int yyss;
315 YYSTYPE yyvs;
316 };
317
318/* The size of the maximum gap between one aligned stack and the next. */
319# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
320
321/* The size of an array large to enough to hold all stacks, each with
322 N elements. */
323# define YYSTACK_BYTES(N) \
324 ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
325 + YYSTACK_GAP_MAXIMUM)
326
327/* Copy COUNT objects from FROM to TO. The source and destination do
328 not overlap. */
329# ifndef YYCOPY
330# if defined (__GNUC__) && 1 < __GNUC__
331# define YYCOPY(To, From, Count) \
332 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
333# else
334# define YYCOPY(To, From, Count) \
335 do \
336 { \
337 register YYSIZE_T yyi; \
338 for (yyi = 0; yyi < (Count); yyi++) \
339 (To)[yyi] = (From)[yyi]; \
340 } \
341 while (0)
342# endif
343# endif
344
345/* Relocate STACK from its old location to the new one. The
346 local variables YYSIZE and YYSTACKSIZE give the old and new number of
347 elements in the stack, and YYPTR gives the new location of the
348 stack. Advance YYPTR to a properly aligned location for the next
349 stack. */
350# define YYSTACK_RELOCATE(Stack) \
351 do \
352 { \
353 YYSIZE_T yynewbytes; \
354 YYCOPY (&yyptr->Stack, Stack, yysize); \
355 Stack = &yyptr->Stack; \
356 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
357 yyptr += yynewbytes / sizeof (*yyptr); \
358 } \
359 while (0)
360
361#endif
362
363#if defined (__STDC__) || defined (__cplusplus)
364 typedef signed char yysigned_char;
365#else
366 typedef short int yysigned_char;
367#endif
368
369/* YYFINAL -- State number of the termination state. */
370#define YYFINAL 5
371/* YYLAST -- Last index in YYTABLE. */
372#define YYLAST 1008
373
374/* YYNTOKENS -- Number of terminals. */
375#define YYNTOKENS 67
376/* YYNNTS -- Number of nonterminals. */
377#define YYNNTS 53
378/* YYNRULES -- Number of rules. */
379#define YYNRULES 155
380/* YYNRULES -- Number of states. */
381#define YYNSTATES 293
382
383/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
384#define YYUNDEFTOK 2
385#define YYMAXUTOK 301
386
387#define YYTRANSLATE(YYX) \
388 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
389
390/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
391static const unsigned char yytranslate[] =
392{
393 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
394 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
395 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
396 2, 2, 2, 56, 2, 2, 59, 55, 2, 2,
397 60, 61, 53, 51, 48, 52, 2, 54, 2, 2,
398 2, 2, 2, 2, 2, 2, 2, 2, 47, 66,
399 49, 2, 50, 46, 2, 2, 2, 2, 2, 2,
400 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
401 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
402 2, 62, 2, 63, 58, 2, 2, 2, 2, 2,
403 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
404 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
405 2, 2, 2, 64, 2, 65, 2, 2, 2, 2,
406 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
407 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
408 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
409 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
410 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
411 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
412 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
413 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
414 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
415 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
416 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
418 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
419 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
420 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
421 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
422 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
423 45, 57
424};
425
426#if YYDEBUG
427/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
428 YYRHS. */
429static const unsigned short int yyprhs[] =
430{
431 0, 0, 3, 7, 8, 11, 14, 17, 20, 23,
432 24, 26, 30, 32, 34, 40, 42, 44, 46, 48,
433 50, 51, 59, 60, 64, 66, 68, 69, 72, 75,
434 77, 80, 83, 87, 89, 99, 106, 115, 124, 137,
435 149, 152, 155, 158, 161, 165, 166, 171, 174, 175,
436 180, 186, 189, 194, 196, 197, 199, 201, 202, 205,
437 208, 214, 219, 221, 224, 227, 229, 231, 233, 235,
438 237, 243, 244, 245, 249, 256, 266, 268, 271, 272,
439 274, 275, 278, 279, 281, 283, 287, 289, 292, 296,
440 297, 299, 300, 302, 304, 308, 310, 313, 317, 321,
441 325, 329, 333, 337, 341, 345, 351, 353, 355, 357,
442 360, 362, 364, 366, 368, 370, 373, 379, 381, 384,
443 386, 390, 394, 398, 402, 406, 410, 414, 419, 422,
444 425, 428, 432, 437, 442, 444, 449, 451, 454, 457,
445 459, 461, 464, 467, 468, 470, 472, 477, 480, 483,
446 486, 488, 489, 491, 493, 495
447};
448
449/* YYRHS -- A `-1'-separated list of the rules' RHS. */
450static const yysigned_char yyrhs[] =
451{
452 68, 0, -1, 97, 69, 97, -1, -1, 69, 70,
453 -1, 69, 1, -1, 71, 72, -1, 71, 81, -1,
454 75, 72, -1, -1, 104, -1, 104, 48, 104, -1,
455 16, -1, 17, -1, 113, 80, 114, 116, 97, -1,
456 4, -1, 3, -1, 74, -1, 42, -1, 43, -1,
457 -1, 34, 76, 73, 60, 99, 115, 97, -1, -1,
458 79, 78, 5, -1, 54, -1, 45, -1, -1, 80,
459 82, -1, 80, 1, -1, 96, -1, 117, 97, -1,
460 117, 97, -1, 113, 80, 114, -1, 95, -1, 22,
461 60, 104, 115, 97, 113, 87, 97, 114, -1, 25,
462 60, 104, 115, 97, 82, -1, 26, 97, 82, 25,
463 60, 104, 115, 97, -1, 27, 60, 4, 37, 4,
464 115, 97, 82, -1, 27, 60, 86, 117, 97, 104,
465 117, 97, 86, 115, 97, 82, -1, 27, 60, 86,
466 117, 97, 117, 97, 86, 115, 97, 82, -1, 28,
467 81, -1, 29, 81, -1, 32, 81, -1, 36, 81,
468 -1, 33, 101, 81, -1, -1, 20, 83, 101, 81,
469 -1, 84, 81, -1, -1, 91, 85, 92, 93, -1,
470 21, 4, 62, 103, 63, -1, 21, 4, -1, 21,
471 60, 4, 61, -1, 104, -1, -1, 84, -1, 88,
472 -1, -1, 88, 89, -1, 88, 1, -1, 23, 90,
473 118, 97, 80, -1, 24, 118, 97, 80, -1, 7,
474 -1, 52, 7, -1, 51, 7, -1, 8, -1, 77,
475 -1, 30, -1, 31, -1, 102, -1, 60, 104, 119,
476 103, 115, -1, -1, -1, 10, 94, 108, -1, 18,
477 60, 104, 115, 97, 82, -1, 18, 60, 104, 115,
478 97, 82, 19, 97, 82, -1, 44, -1, 96, 44,
479 -1, -1, 96, -1, -1, 49, 109, -1, -1, 100,
480 -1, 4, -1, 100, 119, 4, -1, 1, -1, 100,
481 1, -1, 100, 119, 1, -1, -1, 104, -1, -1,
482 103, -1, 104, -1, 103, 119, 104, -1, 1, -1,
483 103, 1, -1, 103, 1, 104, -1, 103, 119, 1,
484 -1, 112, 105, 104, -1, 104, 38, 104, -1, 104,
485 39, 104, -1, 104, 14, 104, -1, 104, 37, 4,
486 -1, 104, 107, 104, -1, 104, 46, 104, 47, 104,
487 -1, 108, -1, 13, -1, 12, -1, 45, 13, -1,
488 9, -1, 49, -1, 106, -1, 50, -1, 77, -1,
489 56, 77, -1, 60, 103, 115, 37, 4, -1, 109,
490 -1, 108, 109, -1, 110, -1, 109, 58, 109, -1,
491 109, 53, 109, -1, 109, 54, 109, -1, 109, 55,
492 109, -1, 109, 51, 109, -1, 109, 52, 109, -1,
493 35, 111, 98, -1, 109, 11, 35, 111, -1, 112,
494 40, -1, 112, 41, -1, 56, 109, -1, 60, 104,
495 115, -1, 42, 60, 102, 115, -1, 43, 60, 102,
496 115, -1, 43, -1, 3, 60, 102, 115, -1, 112,
497 -1, 40, 112, -1, 41, 112, -1, 7, -1, 8,
498 -1, 52, 109, -1, 51, 109, -1, -1, 112, -1,
499 4, -1, 4, 62, 103, 63, -1, 59, 110, -1,
500 64, 97, -1, 65, 97, -1, 61, -1, -1, 117,
501 -1, 66, -1, 47, -1, 48, 97, -1
502};
503
504/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
505static const unsigned short int yyrline[] =
506{
507 0, 171, 171, 177, 179, 184, 196, 200, 215, 226,
508 229, 233, 243, 248, 256, 261, 263, 265, 276, 277,
509 282, 281, 305, 304, 330, 331, 336, 337, 355, 360,
510 361, 365, 367, 369, 371, 373, 375, 377, 421, 425,
511 430, 433, 436, 445, 465, 468, 467, 477, 489, 489,
512 520, 522, 536, 551, 557, 558, 563, 616, 617, 634,
513 639, 641, 646, 648, 653, 655, 657, 662, 663, 671,
514 672, 678, 683, 683, 695, 700, 707, 708, 711, 713,
515 718, 719, 725, 726, 731, 733, 735, 737, 739, 746,
516 747, 753, 754, 759, 761, 767, 769, 771, 773, 778,
517 797, 799, 801, 807, 809, 815, 817, 822, 824, 826,
518 831, 833, 837, 838, 843, 845, 853, 855, 857, 862,
519 864, 866, 868, 870, 872, 874, 876, 882, 887, 889,
520 894, 896, 898, 901, 903, 911, 919, 920, 922, 924,
521 926, 929, 937, 949, 950, 955, 957, 971, 982, 986,
522 990, 993, 995, 999, 1003, 1006
523};
524#endif
525
526#if YYDEBUG || YYERROR_VERBOSE
527/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
528 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
529static const char *const yytname[] =
530{
531 "$end", "error", "$undefined", "FUNC_CALL", "NAME", "REGEXP", "ERROR",
532 "YNUMBER", "YSTRING", "RELOP", "IO_OUT", "IO_IN", "ASSIGNOP", "ASSIGN",
533 "MATCHOP", "CONCAT_OP", "LEX_BEGIN", "LEX_END", "LEX_IF", "LEX_ELSE",
534 "LEX_RETURN", "LEX_DELETE", "LEX_SWITCH", "LEX_CASE", "LEX_DEFAULT",
535 "LEX_WHILE", "LEX_DO", "LEX_FOR", "LEX_BREAK", "LEX_CONTINUE",
536 "LEX_PRINT", "LEX_PRINTF", "LEX_NEXT", "LEX_EXIT", "LEX_FUNCTION",
537 "LEX_GETLINE", "LEX_NEXTFILE", "LEX_IN", "LEX_AND", "LEX_OR",
538 "INCREMENT", "DECREMENT", "LEX_BUILTIN", "LEX_LENGTH", "NEWLINE",
539 "SLASH_BEFORE_EQUAL", "'?'", "':'", "','", "'<'", "'>'", "'+'", "'-'",
540 "'*'", "'/'", "'%'", "'!'", "UNARY", "'^'", "'$'", "'('", "')'", "'['",
541 "']'", "'{'", "'}'", "';'", "$accept", "start", "program", "rule",
542 "pattern", "action", "func_name", "lex_builtin", "function_prologue",
543 "@1", "regexp", "@2", "a_slash", "statements", "statement_term",
544 "statement", "@3", "simple_stmt", "@4", "opt_simple_stmt", "switch_body",
545 "case_statements", "case_statement", "case_value", "print",
546 "print_expression_list", "output_redir", "@5", "if_statement", "nls",
547 "opt_nls", "input_redir", "opt_param_list", "param_list", "opt_exp",
548 "opt_expression_list", "expression_list", "exp", "assign_operator",
549 "relop_or_less", "a_relop", "common_exp", "simp_exp",
550 "non_post_simp_exp", "opt_variable", "variable", "l_brace", "r_brace",
551 "r_paren", "opt_semi", "semi", "colon", "comma", 0
552};
553#endif
554
555# ifdef YYPRINT
556/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
557 token YYLEX-NUM. */
558static const unsigned short int yytoknum[] =
559{
560 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
561 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
562 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
563 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
564 295, 296, 297, 298, 299, 300, 63, 58, 44, 60,
565 62, 43, 45, 42, 47, 37, 33, 301, 94, 36,
566 40, 41, 91, 93, 123, 125, 59
567};
568# endif
569
570/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
571static const unsigned char yyr1[] =
572{
573 0, 67, 68, 69, 69, 69, 70, 70, 70, 71,
574 71, 71, 71, 71, 72, 73, 73, 73, 74, 74,
575 76, 75, 78, 77, 79, 79, 80, 80, 80, 81,
576 81, 82, 82, 82, 82, 82, 82, 82, 82, 82,
577 82, 82, 82, 82, 82, 83, 82, 82, 85, 84,
578 84, 84, 84, 84, 86, 86, 87, 88, 88, 88,
579 89, 89, 90, 90, 90, 90, 90, 91, 91, 92,
580 92, 93, 94, 93, 95, 95, 96, 96, 97, 97,
581 98, 98, 99, 99, 100, 100, 100, 100, 100, 101,
582 101, 102, 102, 103, 103, 103, 103, 103, 103, 104,
583 104, 104, 104, 104, 104, 104, 104, 105, 105, 105,
584 106, 106, 107, 107, 108, 108, 108, 108, 108, 109,
585 109, 109, 109, 109, 109, 109, 109, 109, 109, 109,
586 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
587 110, 110, 110, 111, 111, 112, 112, 112, 113, 114,
588 115, 116, 116, 117, 118, 119
589};
590
591/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
592static const unsigned char yyr2[] =
593{
594 0, 2, 3, 0, 2, 2, 2, 2, 2, 0,
595 1, 3, 1, 1, 5, 1, 1, 1, 1, 1,
596 0, 7, 0, 3, 1, 1, 0, 2, 2, 1,
597 2, 2, 3, 1, 9, 6, 8, 8, 12, 11,
598 2, 2, 2, 2, 3, 0, 4, 2, 0, 4,
599 5, 2, 4, 1, 0, 1, 1, 0, 2, 2,
600 5, 4, 1, 2, 2, 1, 1, 1, 1, 1,
601 5, 0, 0, 3, 6, 9, 1, 2, 0, 1,
602 0, 2, 0, 1, 1, 3, 1, 2, 3, 0,
603 1, 0, 1, 1, 3, 1, 2, 3, 3, 3,
604 3, 3, 3, 3, 3, 5, 1, 1, 1, 2,
605 1, 1, 1, 1, 1, 2, 5, 1, 2, 1,
606 3, 3, 3, 3, 3, 3, 3, 4, 2, 2,
607 2, 3, 4, 4, 1, 4, 1, 2, 2, 1,
608 1, 2, 2, 0, 1, 1, 4, 2, 2, 2,
609 1, 0, 1, 1, 1, 2
610};
611
612/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
613 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
614 means the default is an error. */
615static const unsigned char yydefact[] =
616{
617 78, 76, 0, 79, 3, 1, 77, 0, 5, 0,
618 145, 139, 140, 12, 13, 20, 143, 0, 0, 0,
619 134, 25, 0, 0, 24, 0, 0, 0, 4, 0,
620 0, 114, 22, 2, 10, 106, 117, 119, 136, 0,
621 0, 0, 80, 144, 137, 138, 0, 0, 0, 0,
622 142, 136, 141, 115, 130, 147, 136, 95, 0, 93,
623 78, 153, 6, 7, 29, 26, 78, 8, 0, 110,
624 0, 0, 0, 0, 0, 0, 111, 113, 112, 0,
625 118, 0, 0, 0, 0, 0, 0, 0, 108, 107,
626 128, 129, 0, 0, 0, 0, 93, 0, 16, 15,
627 18, 19, 0, 17, 0, 126, 0, 0, 0, 96,
628 78, 150, 0, 0, 131, 148, 0, 30, 23, 102,
629 103, 100, 101, 0, 11, 104, 143, 124, 125, 121,
630 122, 123, 120, 109, 99, 135, 146, 0, 81, 132,
631 133, 97, 155, 0, 98, 94, 28, 0, 45, 0,
632 0, 0, 78, 0, 0, 0, 67, 68, 0, 89,
633 0, 78, 27, 0, 48, 33, 53, 26, 151, 78,
634 0, 127, 86, 84, 0, 0, 116, 0, 89, 51,
635 0, 0, 0, 0, 54, 40, 41, 42, 0, 90,
636 43, 149, 47, 0, 0, 78, 152, 31, 105, 78,
637 87, 0, 0, 0, 0, 0, 0, 0, 0, 145,
638 55, 0, 44, 0, 71, 69, 32, 14, 21, 88,
639 85, 78, 46, 0, 52, 78, 78, 0, 0, 78,
640 93, 72, 49, 0, 50, 0, 0, 0, 0, 0,
641 0, 0, 74, 57, 35, 0, 78, 0, 78, 0,
642 73, 78, 78, 0, 78, 0, 78, 54, 70, 0,
643 0, 59, 0, 0, 58, 36, 37, 54, 0, 75,
644 34, 62, 65, 0, 0, 66, 0, 154, 78, 0,
645 78, 64, 63, 78, 26, 78, 0, 26, 0, 0,
646 39, 0, 38
647};
648
649/* YYDEFGOTO[NTERM-NUM]. */
650static const short int yydefgoto[] =
651{
652 -1, 2, 7, 28, 29, 62, 102, 103, 30, 41,
653 31, 68, 32, 116, 63, 162, 178, 163, 193, 211,
654 252, 253, 264, 276, 164, 214, 232, 241, 165, 3,
655 4, 105, 174, 175, 188, 94, 95, 166, 93, 78,
656 79, 35, 36, 37, 42, 38, 167, 168, 114, 195,
657 169, 278, 113
658};
659
660/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
661 STATE-NUM. */
662#define YYPACT_NINF -236
663static const short int yypact[] =
664{
665 -15, -236, 31, -3, -236, -236, -236, 292, -236, -8,
666 -2, -236, -236, -236, -236, -236, 26, 26, 26, 4,
667 6, -236, 934, 934, -236, 876, 262, 717, -236, -16,
668 3, -236, -236, -236, 769, 934, 480, -236, 554, 656,
669 717, 33, 49, -236, -236, -236, 656, 656, 934, 905,
670 41, -1, 41, -236, 41, -236, -236, -236, 117, 695,
671 -15, -236, -236, -236, -3, -236, -15, -236, 101, -236,
672 905, 103, 905, 905, 905, 905, -236, -236, -236, 905,
673 480, 74, 934, 934, 934, 934, 934, 934, -236, -236,
674 -236, -236, 100, 905, 54, 17, 958, 32, -236, -236,
675 -236, -236, 56, -236, 934, -236, 54, 54, 695, 905,
676 -15, -236, 86, 739, -236, -236, 454, -236, -236, 133,
677 -236, 184, 166, 823, 958, 7, 26, 136, 136, 41,
678 41, 41, 41, -236, 958, -236, -236, 43, 538, -236,
679 -236, 958, -236, 121, -236, 958, -236, 68, -236, 2,
680 69, 70, -15, 71, 61, 61, -236, -236, 61, 905,
681 61, -15, -236, 61, -236, -236, 958, -236, 73, -15,
682 905, -236, -236, -236, 54, 123, -236, 905, 905, 81,
683 131, 905, 905, 580, 793, -236, -236, -236, 61, 958,
684 -236, -236, -236, 520, 454, -15, -236, -236, 958, -15,
685 -236, 45, 695, 61, 717, 83, 695, 695, 130, -11,
686 -236, 73, -236, 717, 147, -236, -236, -236, -236, -236,
687 -236, -15, -236, 34, -236, -15, -15, 108, 169, -15,
688 508, -236, -236, 580, -236, 3, 580, 905, 54, 634,
689 717, 905, 155, -236, -236, 695, -15, 502, -15, 117,
690 934, -15, -15, 19, -15, 580, -15, 847, -236, 580,
691 111, -236, 201, 132, -236, -236, -236, 847, 54, -236,
692 -236, -236, -236, 178, 179, -236, 132, -236, -15, 54,
693 -15, -236, -236, -15, -236, -15, 580, -236, 346, 580,
694 -236, 400, -236
695};
696
697/* YYPGOTO[NTERM-NUM]. */
698static const short int yypgoto[] =
699{
700 -236, -236, -236, -236, -236, 165, -236, -236, -236, -236,
701 -24, -236, -236, -150, 152, -178, -236, -165, -236, -235,
702 -236, -236, -236, -236, -236, -236, -236, -236, -236, -22,
703 -7, -236, -236, -236, 21, -32, -17, 47, -236, -236,
704 -236, -41, 66, 175, 76, -14, -5, -181, 52, -236,
705 9, -71, -130
706};
707
708/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
709 positive, shift that token. If negative, reduce the rule which
710 number is the opposite. If zero, do what YYDEFACT says.
711 If YYTABLE_NINF, syntax error. */
712#define YYTABLE_NINF -93
713static const short int yytable[] =
714{
715 33, 53, 43, 44, 45, 208, 179, 64, 51, 51,
716 58, 51, 56, 216, 106, 107, -93, 194, 109, 210,
717 261, 51, 268, 97, 65, 65, 228, -92, 1, 1,
718 10, 5, 279, 109, 51, 109, 98, 99, 66, 90,
719 91, 6, 262, 263, 172, 201, 219, 173, 60, 220,
720 61, 40, 39, 115, 34, 242, -93, -93, 244, 117,
721 40, -92, 180, -56, 46, 110, 47, 60, 51, 51,
722 51, 51, 51, 51, 59, 100, 101, 266, -92, 270,
723 110, 269, 110, -92, -56, 26, 96, 96, 50, 52,
724 51, 54, 210, 96, 96, 136, 108, 234, 104, 87,
725 240, 80, 210, 142, -82, 1, 118, 120, 290, 126,
726 112, 292, 43, 133, 54, 111, 137, 119, 109, 121,
727 122, 123, 124, 143, 200, 176, 125, 61, 177, 181,
728 182, 184, 64, 64, 288, 205, 64, 291, 64, 61,
729 134, 64, 69, 204, 224, 183, 135, -93, 127, 128,
730 129, 130, 131, 132, 191, 227, 141, 231, 139, 140,
731 145, 215, 197, 66, 66, 110, 64, 66, 237, 66,
732 138, 110, 66, 238, 251, 69, 161, 196, 111, 277,
733 70, 64, 76, 77, -83, 281, 282, 223, 217, 84,
734 85, 86, 218, 69, 87, 67, 58, 66, 70, 203,
735 250, 55, 171, 71, 72, 283, 189, 0, 271, 272,
736 0, 0, 66, 0, 233, 76, 77, 198, 235, 236,
737 229, 71, 239, 249, 202, 189, 199, 51, 206, 207,
738 243, 0, 0, 76, 77, 0, 51, 0, 275, 255,
739 96, 257, 0, 0, 259, 260, 21, 265, 248, 267,
740 0, 96, 273, 274, 221, 24, 256, 0, 225, 226,
741 230, 0, 0, 0, 0, 9, 10, 0, 0, 11,
742 12, 284, 0, 286, 0, 0, 287, 0, 289, 0,
743 0, 0, 0, 0, 245, 0, 247, 96, 0, 0,
744 246, 0, -78, 8, 0, 9, 10, 254, 0, 11,
745 12, 258, 17, 18, 19, 20, 185, 186, 13, 14,
746 187, 0, 190, 22, 23, 192, 80, 0, 48, 0,
747 280, 26, 49, 0, 0, 0, 15, 16, 0, 0,
748 0, 285, 17, 18, 19, 20, 1, 21, 0, 0,
749 212, 0, 0, 22, 23, 0, 24, 146, 25, 9,
750 10, 26, 27, 11, 12, 222, -9, 0, -9, 0,
751 0, 0, 0, 0, 147, 0, 148, 149, 150, -61,
752 -61, 151, 152, 153, 154, 155, 156, 157, 158, 159,
753 0, 16, 160, 0, 0, 0, 17, 18, 19, 20,
754 -61, 21, 0, 0, 0, 0, 0, 22, 23, 0,
755 24, 146, 25, 9, 10, 26, 27, 11, 12, 0,
756 60, -61, 61, 0, 0, 0, 0, 0, 147, 0,
757 148, 149, 150, -60, -60, 151, 152, 153, 154, 155,
758 156, 157, 158, 159, 0, 16, 160, 0, 0, 0,
759 17, 18, 19, 20, -60, 21, 0, 0, 0, 0,
760 0, 22, 23, 0, 24, 146, 25, 9, 10, 26,
761 27, 11, 12, 0, 60, -60, 61, 0, 0, 0,
762 0, 0, 147, 0, 148, 149, 150, 0, 0, 151,
763 152, 153, 154, 155, 156, 157, 158, 159, 0, 16,
764 160, 81, 0, 0, 17, 18, 19, 20, 0, 21,
765 0, 0, 0, 0, 0, 22, 23, 0, 24, 0,
766 25, 69, 0, 26, 27, 0, 70, 69, 60, 161,
767 61, 57, 70, 9, 10, 0, 0, 11, 12, 0,
768 -91, 82, 83, 84, 85, 86, 0, 0, 87, 71,
769 72, 73, 0, 0, 0, 71, 72, 73, 74, -93,
770 0, 76, 77, 0, 74, 16, 110, 76, 77, 0,
771 17, 18, 19, 20, -91, 21, 88, 89, 61, 111,
772 0, 22, 23, 0, 24, 0, 25, 0, 0, 26,
773 213, -91, 0, 9, 10, 0, -91, 11, 12, 82,
774 83, 84, 85, 86, 90, 91, 87, 0, 147, 92,
775 148, 149, 150, 0, 0, 151, 152, 153, 154, 155,
776 156, 157, 158, 159, 0, 16, 160, 0, 0, 0,
777 17, 18, 19, 20, 0, 21, 0, 0, 0, 0,
778 0, 22, 23, 0, 24, 0, 25, 9, 10, 26,
779 27, 11, 12, 0, 60, 0, 61, 0, 0, 0,
780 0, 0, 0, 0, 0, 0, 0, 57, 0, 9,
781 10, 0, 0, 11, 12, 0, 0, 0, 0, 16,
782 0, 0, 0, 0, 17, 18, 19, 20, 0, 21,
783 0, 0, 0, 0, 0, 22, 23, 0, 24, 0,
784 25, 16, 0, 26, 27, 0, 17, 18, 19, 20,
785 61, 21, 0, 0, 69, 0, 0, 22, 23, 70,
786 24, 0, 25, 0, 0, 26, 27, -91, 57, 0,
787 9, 10, 0, 0, 11, 12, 0, 0, 0, 0,
788 0, 0, 71, 72, 73, 0, 0, 0, 0, 0,
789 144, 74, 9, 10, 76, 77, 11, 12, 0, 0,
790 0, 0, 16, 0, 0, 0, 111, 17, 18, 19,
791 20, 0, 21, 0, 0, 0, 0, 0, 22, 23,
792 0, 24, 0, 25, 16, 0, 26, 27, 69, 17,
793 18, 19, 20, 70, 21, 0, 0, 0, 0, 0,
794 22, 23, 0, 24, 0, 25, 9, 209, 26, 27,
795 11, 12, 0, 0, 0, 0, 71, 72, 73, 0,
796 0, 0, 0, 0, 149, 74, 0, 75, 76, 77,
797 0, 0, 0, 156, 157, 0, 0, 0, 16, 0,
798 0, 0, 69, 17, 18, 19, 20, 70, 21, 0,
799 0, 0, 0, 0, 22, 23, 0, 24, 0, 25,
800 9, 10, 26, 27, 11, 12, 0, 0, 0, 0,
801 71, 72, 73, 0, 0, 0, 0, 0, 149, 74,
802 170, 0, 76, 77, 0, 0, 0, 156, 157, 9,
803 10, 0, 16, 11, 12, 0, 0, 17, 18, 19,
804 20, 0, 21, 0, 0, 0, 0, 0, 22, 23,
805 0, 24, 0, 25, 0, 0, 26, 27, 9, 10,
806 0, 16, 11, 12, 0, 0, 17, 18, 19, 20,
807 0, 21, 0, 0, 0, 0, 0, 22, 23, 0,
808 24, 0, 48, 0, 0, 26, 49, 9, 10, 0,
809 16, 11, 12, 0, 0, 17, 18, 19, 20, 0,
810 21, 0, 0, 0, 0, 0, 22, 23, 0, 24,
811 0, 25, 0, 0, 26, 27, 0, 69, 0, 16,
812 0, 0, 70, 0, 17, 18, 19, 20, 0, 0,
813 0, 0, 0, 0, 0, 22, 23, 0, 0, 0,
814 48, 0, 0, 26, 49, 71, 72, 73, 0, 0,
815 0, 0, 0, 0, 74, 0, 0, 76, 77
816};
817
818static const short int yycheck[] =
819{
820 7, 25, 16, 17, 18, 183, 4, 29, 22, 23,
821 27, 25, 26, 194, 46, 47, 9, 167, 1, 184,
822 1, 35, 257, 40, 29, 30, 37, 10, 44, 44,
823 4, 0, 267, 1, 48, 1, 3, 4, 29, 40,
824 41, 44, 23, 24, 1, 175, 1, 4, 64, 4,
825 66, 62, 60, 60, 7, 233, 49, 50, 236, 66,
826 62, 44, 60, 44, 60, 48, 60, 64, 82, 83,
827 84, 85, 86, 87, 27, 42, 43, 255, 61, 260,
828 48, 259, 48, 66, 65, 59, 39, 40, 22, 23,
829 104, 25, 257, 46, 47, 63, 49, 63, 49, 58,
830 230, 35, 267, 110, 61, 44, 5, 4, 286, 35,
831 58, 289, 126, 13, 48, 61, 60, 70, 1, 72,
832 73, 74, 75, 37, 1, 4, 79, 66, 60, 60,
833 60, 60, 154, 155, 284, 4, 158, 287, 160, 66,
834 93, 163, 9, 62, 61, 152, 94, 14, 82, 83,
835 84, 85, 86, 87, 161, 25, 109, 10, 106, 107,
836 113, 193, 169, 154, 155, 48, 188, 158, 60, 160,
837 104, 48, 163, 4, 19, 9, 65, 168, 61, 47,
838 14, 203, 49, 50, 61, 7, 7, 204, 195, 53,
839 54, 55, 199, 9, 58, 30, 213, 188, 14, 178,
840 241, 26, 126, 37, 38, 276, 159, -1, 7, 8,
841 -1, -1, 203, -1, 221, 49, 50, 170, 225, 226,
842 211, 37, 229, 240, 177, 178, 174, 241, 181, 182,
843 235, -1, -1, 49, 50, -1, 250, -1, 262, 246,
844 193, 248, -1, -1, 251, 252, 45, 254, 239, 256,
845 -1, 204, 51, 52, 202, 54, 247, -1, 206, 207,
846 213, -1, -1, -1, -1, 3, 4, -1, -1, 7,
847 8, 278, -1, 280, -1, -1, 283, -1, 285, -1,
848 -1, -1, -1, -1, 237, -1, 239, 240, -1, -1,
849 238, -1, 0, 1, -1, 3, 4, 245, -1, 7,
850 8, 249, 40, 41, 42, 43, 154, 155, 16, 17,
851 158, -1, 160, 51, 52, 163, 250, -1, 56, -1,
852 268, 59, 60, -1, -1, -1, 34, 35, -1, -1,
853 -1, 279, 40, 41, 42, 43, 44, 45, -1, -1,
854 188, -1, -1, 51, 52, -1, 54, 1, 56, 3,
855 4, 59, 60, 7, 8, 203, 64, -1, 66, -1,
856 -1, -1, -1, -1, 18, -1, 20, 21, 22, 23,
857 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
858 -1, 35, 36, -1, -1, -1, 40, 41, 42, 43,
859 44, 45, -1, -1, -1, -1, -1, 51, 52, -1,
860 54, 1, 56, 3, 4, 59, 60, 7, 8, -1,
861 64, 65, 66, -1, -1, -1, -1, -1, 18, -1,
862 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
863 30, 31, 32, 33, -1, 35, 36, -1, -1, -1,
864 40, 41, 42, 43, 44, 45, -1, -1, -1, -1,
865 -1, 51, 52, -1, 54, 1, 56, 3, 4, 59,
866 60, 7, 8, -1, 64, 65, 66, -1, -1, -1,
867 -1, -1, 18, -1, 20, 21, 22, -1, -1, 25,
868 26, 27, 28, 29, 30, 31, 32, 33, -1, 35,
869 36, 11, -1, -1, 40, 41, 42, 43, -1, 45,
870 -1, -1, -1, -1, -1, 51, 52, -1, 54, -1,
871 56, 9, -1, 59, 60, -1, 14, 9, 64, 65,
872 66, 1, 14, 3, 4, -1, -1, 7, 8, -1,
873 10, 51, 52, 53, 54, 55, -1, -1, 58, 37,
874 38, 39, -1, -1, -1, 37, 38, 39, 46, 11,
875 -1, 49, 50, -1, 46, 35, 48, 49, 50, -1,
876 40, 41, 42, 43, 44, 45, 12, 13, 66, 61,
877 -1, 51, 52, -1, 54, -1, 56, -1, -1, 59,
878 60, 61, -1, 3, 4, -1, 66, 7, 8, 51,
879 52, 53, 54, 55, 40, 41, 58, -1, 18, 45,
880 20, 21, 22, -1, -1, 25, 26, 27, 28, 29,
881 30, 31, 32, 33, -1, 35, 36, -1, -1, -1,
882 40, 41, 42, 43, -1, 45, -1, -1, -1, -1,
883 -1, 51, 52, -1, 54, -1, 56, 3, 4, 59,
884 60, 7, 8, -1, 64, -1, 66, -1, -1, -1,
885 -1, -1, -1, -1, -1, -1, -1, 1, -1, 3,
886 4, -1, -1, 7, 8, -1, -1, -1, -1, 35,
887 -1, -1, -1, -1, 40, 41, 42, 43, -1, 45,
888 -1, -1, -1, -1, -1, 51, 52, -1, 54, -1,
889 56, 35, -1, 59, 60, -1, 40, 41, 42, 43,
890 66, 45, -1, -1, 9, -1, -1, 51, 52, 14,
891 54, -1, 56, -1, -1, 59, 60, 61, 1, -1,
892 3, 4, -1, -1, 7, 8, -1, -1, -1, -1,
893 -1, -1, 37, 38, 39, -1, -1, -1, -1, -1,
894 1, 46, 3, 4, 49, 50, 7, 8, -1, -1,
895 -1, -1, 35, -1, -1, -1, 61, 40, 41, 42,
896 43, -1, 45, -1, -1, -1, -1, -1, 51, 52,
897 -1, 54, -1, 56, 35, -1, 59, 60, 9, 40,
898 41, 42, 43, 14, 45, -1, -1, -1, -1, -1,
899 51, 52, -1, 54, -1, 56, 3, 4, 59, 60,
900 7, 8, -1, -1, -1, -1, 37, 38, 39, -1,
901 -1, -1, -1, -1, 21, 46, -1, 48, 49, 50,
902 -1, -1, -1, 30, 31, -1, -1, -1, 35, -1,
903 -1, -1, 9, 40, 41, 42, 43, 14, 45, -1,
904 -1, -1, -1, -1, 51, 52, -1, 54, -1, 56,
905 3, 4, 59, 60, 7, 8, -1, -1, -1, -1,
906 37, 38, 39, -1, -1, -1, -1, -1, 21, 46,
907 47, -1, 49, 50, -1, -1, -1, 30, 31, 3,
908 4, -1, 35, 7, 8, -1, -1, 40, 41, 42,
909 43, -1, 45, -1, -1, -1, -1, -1, 51, 52,
910 -1, 54, -1, 56, -1, -1, 59, 60, 3, 4,
911 -1, 35, 7, 8, -1, -1, 40, 41, 42, 43,
912 -1, 45, -1, -1, -1, -1, -1, 51, 52, -1,
913 54, -1, 56, -1, -1, 59, 60, 3, 4, -1,
914 35, 7, 8, -1, -1, 40, 41, 42, 43, -1,
915 45, -1, -1, -1, -1, -1, 51, 52, -1, 54,
916 -1, 56, -1, -1, 59, 60, -1, 9, -1, 35,
917 -1, -1, 14, -1, 40, 41, 42, 43, -1, -1,
918 -1, -1, -1, -1, -1, 51, 52, -1, -1, -1,
919 56, -1, -1, 59, 60, 37, 38, 39, -1, -1,
920 -1, -1, -1, -1, 46, -1, -1, 49, 50
921};
922
923/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
924 symbol of state STATE-NUM. */
925static const unsigned char yystos[] =
926{
927 0, 44, 68, 96, 97, 0, 44, 69, 1, 3,
928 4, 7, 8, 16, 17, 34, 35, 40, 41, 42,
929 43, 45, 51, 52, 54, 56, 59, 60, 70, 71,
930 75, 77, 79, 97, 104, 108, 109, 110, 112, 60,
931 62, 76, 111, 112, 112, 112, 60, 60, 56, 60,
932 109, 112, 109, 77, 109, 110, 112, 1, 103, 104,
933 64, 66, 72, 81, 96, 113, 117, 72, 78, 9,
934 14, 37, 38, 39, 46, 48, 49, 50, 106, 107,
935 109, 11, 51, 52, 53, 54, 55, 58, 12, 13,
936 40, 41, 45, 105, 102, 103, 104, 103, 3, 4,
937 42, 43, 73, 74, 49, 98, 102, 102, 104, 1,
938 48, 61, 115, 119, 115, 97, 80, 97, 5, 104,
939 4, 104, 104, 104, 104, 104, 35, 109, 109, 109,
940 109, 109, 109, 13, 104, 115, 63, 60, 109, 115,
941 115, 104, 97, 37, 1, 104, 1, 18, 20, 21,
942 22, 25, 26, 27, 28, 29, 30, 31, 32, 33,
943 36, 65, 82, 84, 91, 95, 104, 113, 114, 117,
944 47, 111, 1, 4, 99, 100, 4, 60, 83, 4,
945 60, 60, 60, 97, 60, 81, 81, 81, 101, 104,
946 81, 97, 81, 85, 80, 116, 117, 97, 104, 115,
947 1, 119, 104, 101, 62, 4, 104, 104, 82, 4,
948 84, 86, 81, 60, 92, 102, 114, 97, 97, 1,
949 4, 115, 81, 103, 61, 115, 115, 25, 37, 117,
950 104, 10, 93, 97, 63, 97, 97, 60, 4, 97,
951 119, 94, 82, 113, 82, 104, 115, 104, 117, 103,
952 108, 19, 87, 88, 115, 97, 117, 97, 115, 97,
953 97, 1, 23, 24, 89, 97, 82, 97, 86, 82,
954 114, 7, 8, 51, 52, 77, 90, 47, 118, 86,
955 115, 7, 7, 118, 97, 115, 97, 97, 80, 97,
956 82, 80, 82
957};
958
959#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
960# define YYSIZE_T __SIZE_TYPE__
961#endif
962#if ! defined (YYSIZE_T) && defined (size_t)
963# define YYSIZE_T size_t
964#endif
965#if ! defined (YYSIZE_T)
966# if defined (__STDC__) || defined (__cplusplus)
967# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
968# define YYSIZE_T size_t
969# endif
970#endif
971#if ! defined (YYSIZE_T)
972# define YYSIZE_T unsigned int
973#endif
974
975#define yyerrok (yyerrstatus = 0)
976#define yyclearin (yychar = YYEMPTY)
977#define YYEMPTY (-2)
978#define YYEOF 0
979
980#define YYACCEPT goto yyacceptlab
981#define YYABORT goto yyabortlab
982#define YYERROR goto yyerrorlab
983
984
985/* Like YYERROR except do call yyerror. This remains here temporarily
986 to ease the transition to the new meaning of YYERROR, for GCC.
987 Once GCC version 2 has supplanted version 1, this can go. */
988
989#define YYFAIL goto yyerrlab
990
991#define YYRECOVERING() (!!yyerrstatus)
992
993#define YYBACKUP(Token, Value) \
994do \
995 if (yychar == YYEMPTY && yylen == 1) \
996 { \
997 yychar = (Token); \
998 yylval = (Value); \
999 yytoken = YYTRANSLATE (yychar); \
1000 YYPOPSTACK; \
1001 goto yybackup; \
1002 } \
1003 else \
1004 { \
1005 yyerror ("syntax error: cannot back up");\
1006 YYERROR; \
1007 } \
1008while (0)
1009
1010
1011#define YYTERROR 1
1012#define YYERRCODE 256
1013
1014
1015/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
1016 If N is 0, then set CURRENT to the empty location which ends
1017 the previous symbol: RHS[0] (always defined). */
1018
1019#define YYRHSLOC(Rhs, K) ((Rhs)[K])
1020#ifndef YYLLOC_DEFAULT
1021# define YYLLOC_DEFAULT(Current, Rhs, N) \
1022 do \
1023 if (N) \
1024 { \
1025 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
1026 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
1027 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
1028 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
1029 } \
1030 else \
1031 { \
1032 (Current).first_line = (Current).last_line = \
1033 YYRHSLOC (Rhs, 0).last_line; \
1034 (Current).first_column = (Current).last_column = \
1035 YYRHSLOC (Rhs, 0).last_column; \
1036 } \
1037 while (0)
1038#endif
1039
1040
1041/* YY_LOCATION_PRINT -- Print the location on the stream.
1042 This macro was not mandated originally: define only if we know
1043 we won't break user code: when these are the locations we know. */
1044
1045#ifndef YY_LOCATION_PRINT
1046# if YYLTYPE_IS_TRIVIAL
1047# define YY_LOCATION_PRINT(File, Loc) \
1048 fprintf (File, "%d.%d-%d.%d", \
1049 (Loc).first_line, (Loc).first_column, \
1050 (Loc).last_line, (Loc).last_column)
1051# else
1052# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
1053# endif
1054#endif
1055
1056
1057/* YYLEX -- calling `yylex' with the right arguments. */
1058
1059#ifdef YYLEX_PARAM
1060# define YYLEX yylex (YYLEX_PARAM)
1061#else
1062# define YYLEX yylex ()
1063#endif
1064
1065/* Enable debugging if requested. */
1066#if YYDEBUG
1067
1068# ifndef YYFPRINTF
1069# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1070# define YYFPRINTF fprintf
1071# endif
1072
1073# define YYDPRINTF(Args) \
1074do { \
1075 if (yydebug) \
1076 YYFPRINTF Args; \
1077} while (0)
1078
1079# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
1080do { \
1081 if (yydebug) \
1082 { \
1083 YYFPRINTF (stderr, "%s ", Title); \
1084 yysymprint (stderr, \
1085 Type, Value); \
1086 YYFPRINTF (stderr, "\n"); \
1087 } \
1088} while (0)
1089
1090/*------------------------------------------------------------------.
1091| yy_stack_print -- Print the state stack from its BOTTOM up to its |
1092| TOP (included). |
1093`------------------------------------------------------------------*/
1094
1095#if defined (__STDC__) || defined (__cplusplus)
1096static void
1097yy_stack_print (short int *bottom, short int *top)
1098#else
1099static void
1100yy_stack_print (bottom, top)
1101 short int *bottom;
1102 short int *top;
1103#endif
1104{
1105 YYFPRINTF (stderr, "Stack now");
1106 for (/* Nothing. */; bottom <= top; ++bottom)
1107 YYFPRINTF (stderr, " %d", *bottom);
1108 YYFPRINTF (stderr, "\n");
1109}
1110
1111# define YY_STACK_PRINT(Bottom, Top) \
1112do { \
1113 if (yydebug) \
1114 yy_stack_print ((Bottom), (Top)); \
1115} while (0)
1116
1117
1118/*------------------------------------------------.
1119| Report that the YYRULE is going to be reduced. |
1120`------------------------------------------------*/
1121
1122#if defined (__STDC__) || defined (__cplusplus)
1123static void
1124yy_reduce_print (int yyrule)
1125#else
1126static void
1127yy_reduce_print (yyrule)
1128 int yyrule;
1129#endif
1130{
1131 int yyi;
1132 unsigned int yylno = yyrline[yyrule];
1133 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
1134 yyrule - 1, yylno);
1135 /* Print the symbols being reduced, and their result. */
1136 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
1137 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
1138 YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
1139}
1140
1141# define YY_REDUCE_PRINT(Rule) \
1142do { \
1143 if (yydebug) \
1144 yy_reduce_print (Rule); \
1145} while (0)
1146
1147/* Nonzero means print parse trace. It is left uninitialized so that
1148 multiple parsers can coexist. */
1149int yydebug;
1150#else /* !YYDEBUG */
1151# define YYDPRINTF(Args)
1152# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1153# define YY_STACK_PRINT(Bottom, Top)
1154# define YY_REDUCE_PRINT(Rule)
1155#endif /* !YYDEBUG */
1156
1157
1158/* YYINITDEPTH -- initial size of the parser's stacks. */
1159#ifndef YYINITDEPTH
1160# define YYINITDEPTH 200
1161#endif
1162
1163/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1164 if the built-in stack extension method is used).
1165
1166 Do not make this value too large; the results are undefined if
1167 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
1168 evaluated with infinite-precision integer arithmetic. */
1169
1170#ifndef YYMAXDEPTH
1171# define YYMAXDEPTH 10000
1172#endif
1173
1174
1175
1176
1177#if YYERROR_VERBOSE
1178
1179# ifndef yystrlen
1180# if defined (__GLIBC__) && defined (_STRING_H)
1181# define yystrlen strlen
1182# else
1183/* Return the length of YYSTR. */
1184static YYSIZE_T
1185# if defined (__STDC__) || defined (__cplusplus)
1186yystrlen (const char *yystr)
1187# else
1188yystrlen (yystr)
1189 const char *yystr;
1190# endif
1191{
1192 register const char *yys = yystr;
1193
1194 while (*yys++ != '\0')
1195 continue;
1196
1197 return yys - yystr - 1;
1198}
1199# endif
1200# endif
1201
1202# ifndef yystpcpy
1203# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
1204# define yystpcpy stpcpy
1205# else
1206/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1207 YYDEST. */
1208static char *
1209# if defined (__STDC__) || defined (__cplusplus)
1210yystpcpy (char *yydest, const char *yysrc)
1211# else
1212yystpcpy (yydest, yysrc)
1213 char *yydest;
1214 const char *yysrc;
1215# endif
1216{
1217 register char *yyd = yydest;
1218 register const char *yys = yysrc;
1219
1220 while ((*yyd++ = *yys++) != '\0')
1221 continue;
1222
1223 return yyd - 1;
1224}
1225# endif
1226# endif
1227
1228#endif /* !YYERROR_VERBOSE */
1229
1230
1231
1232
1233#if YYDEBUG
1234/*--------------------------------.
1235| Print this symbol on YYOUTPUT. |
1236`--------------------------------*/
1237
1238#if defined (__STDC__) || defined (__cplusplus)
1239static void
1240yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
1241#else
1242static void
1243yysymprint (yyoutput, yytype, yyvaluep)
1244 FILE *yyoutput;
1245 int yytype;
1246 YYSTYPE *yyvaluep;
1247#endif
1248{
1249 /* Pacify ``unused variable'' warnings. */
1250 (void) yyvaluep;
1251
1252 if (yytype < YYNTOKENS)
1253 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
1254 else
1255 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
1256
1257
1258# ifdef YYPRINT
1259 if (yytype < YYNTOKENS)
1260 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
1261# endif
1262 switch (yytype)
1263 {
1264 default:
1265 break;
1266 }
1267 YYFPRINTF (yyoutput, ")");
1268}
1269
1270#endif /* ! YYDEBUG */
1271/*-----------------------------------------------.
1272| Release the memory associated to this symbol. |
1273`-----------------------------------------------*/
1274
1275#if defined (__STDC__) || defined (__cplusplus)
1276static void
1277yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1278#else
1279static void
1280yydestruct (yymsg, yytype, yyvaluep)
1281 const char *yymsg;
1282 int yytype;
1283 YYSTYPE *yyvaluep;
1284#endif
1285{
1286 /* Pacify ``unused variable'' warnings. */
1287 (void) yyvaluep;
1288
1289 if (!yymsg)
1290 yymsg = "Deleting";
1291 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1292
1293 switch (yytype)
1294 {
1295
1296 default:
1297 break;
1298 }
1299}
1300
1301
1302
1303/* Prevent warnings from -Wmissing-prototypes. */
1304
1305#ifdef YYPARSE_PARAM
1306# if defined (__STDC__) || defined (__cplusplus)
1307int yyparse (void *YYPARSE_PARAM);
1308# else
1309int yyparse ();
1310# endif
1311#else /* ! YYPARSE_PARAM */
1312#if defined (__STDC__) || defined (__cplusplus)
1313int yyparse (void);
1314#else
1315int yyparse ();
1316#endif
1317#endif /* ! YYPARSE_PARAM */
1318
1319
1320
1321/* The look-ahead symbol. */
1322int yychar;
1323
1324/* The semantic value of the look-ahead symbol. */
1325YYSTYPE yylval;
1326
1327/* Number of syntax errors so far. */
1328int yynerrs;
1329
1330
1331
1332/*----------.
1333| yyparse. |
1334`----------*/
1335
1336#ifdef YYPARSE_PARAM
1337# if defined (__STDC__) || defined (__cplusplus)
1338int yyparse (void *YYPARSE_PARAM)
1339# else
1340int yyparse (YYPARSE_PARAM)
1341 void *YYPARSE_PARAM;
1342# endif
1343#else /* ! YYPARSE_PARAM */
1344#if defined (__STDC__) || defined (__cplusplus)
1345int
1346yyparse (void)
1347#else
1348int
1349yyparse ()
1350
1351#endif
1352#endif
1353{
1354
1355 register int yystate;
1356 register int yyn;
1357 int yyresult;
1358 /* Number of tokens to shift before error messages enabled. */
1359 int yyerrstatus;
1360 /* Look-ahead token as an internal (translated) token number. */
1361 int yytoken = 0;
1362
1363 /* Three stacks and their tools:
1364 `yyss': related to states,
1365 `yyvs': related to semantic values,
1366 `yyls': related to locations.
1367
1368 Refer to the stacks thru separate pointers, to allow yyoverflow
1369 to reallocate them elsewhere. */
1370
1371 /* The state stack. */
1372 short int yyssa[YYINITDEPTH];
1373 short int *yyss = yyssa;
1374 register short int *yyssp;
1375
1376 /* The semantic value stack. */
1377 YYSTYPE yyvsa[YYINITDEPTH];
1378 YYSTYPE *yyvs = yyvsa;
1379 register YYSTYPE *yyvsp;
1380
1381
1382
1383#define YYPOPSTACK (yyvsp--, yyssp--)
1384
1385 YYSIZE_T yystacksize = YYINITDEPTH;
1386
1387 /* The variables used to return semantic value and location from the
1388 action routines. */
1389 YYSTYPE yyval;
1390
1391
1392 /* When reducing, the number of symbols on the RHS of the reduced
1393 rule. */
1394 int yylen;
1395
1396 YYDPRINTF ((stderr, "Starting parse\n"));
1397
1398 yystate = 0;
1399 yyerrstatus = 0;
1400 yynerrs = 0;
1401 yychar = YYEMPTY; /* Cause a token to be read. */
1402
1403 /* Initialize stack pointers.
1404 Waste one element of value and location stack
1405 so that they stay on the same level as the state stack.
1406 The wasted elements are never initialized. */
1407
1408 yyssp = yyss;
1409 yyvsp = yyvs;
1410
1411
1412 yyvsp[0] = yylval;
1413
1414 goto yysetstate;
1415
1416/*------------------------------------------------------------.
1417| yynewstate -- Push a new state, which is found in yystate. |
1418`------------------------------------------------------------*/
1419 yynewstate:
1420 /* In all cases, when you get here, the value and location stacks
1421 have just been pushed. so pushing a state here evens the stacks.
1422 */
1423 yyssp++;
1424
1425 yysetstate:
1426 *yyssp = yystate;
1427
1428 if (yyss + yystacksize - 1 <= yyssp)
1429 {
1430 /* Get the current used size of the three stacks, in elements. */
1431 YYSIZE_T yysize = yyssp - yyss + 1;
1432
1433#ifdef yyoverflow
1434 {
1435 /* Give user a chance to reallocate the stack. Use copies of
1436 these so that the &'s don't force the real ones into
1437 memory. */
1438 YYSTYPE *yyvs1 = yyvs;
1439 short int *yyss1 = yyss;
1440
1441
1442 /* Each stack pointer address is followed by the size of the
1443 data in use in that stack, in bytes. This used to be a
1444 conditional around just the two extra args, but that might
1445 be undefined if yyoverflow is a macro. */
1446 yyoverflow ("parser stack overflow",
1447 &yyss1, yysize * sizeof (*yyssp),
1448 &yyvs1, yysize * sizeof (*yyvsp),
1449
1450 &yystacksize);
1451
1452 yyss = yyss1;
1453 yyvs = yyvs1;
1454 }
1455#else /* no yyoverflow */
1456# ifndef YYSTACK_RELOCATE
1457 goto yyoverflowlab;
1458# else
1459 /* Extend the stack our own way. */
1460 if (YYMAXDEPTH <= yystacksize)
1461 goto yyoverflowlab;
1462 yystacksize *= 2;
1463 if (YYMAXDEPTH < yystacksize)
1464 yystacksize = YYMAXDEPTH;
1465
1466 {
1467 short int *yyss1 = yyss;
1468 union yyalloc *yyptr =
1469 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1470 if (! yyptr)
1471 goto yyoverflowlab;
1472 YYSTACK_RELOCATE (yyss);
1473 YYSTACK_RELOCATE (yyvs);
1474
1475# undef YYSTACK_RELOCATE
1476 if (yyss1 != yyssa)
1477 YYSTACK_FREE (yyss1);
1478 }
1479# endif
1480#endif /* no yyoverflow */
1481
1482 yyssp = yyss + yysize - 1;
1483 yyvsp = yyvs + yysize - 1;
1484
1485
1486 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1487 (unsigned long int) yystacksize));
1488
1489 if (yyss + yystacksize - 1 <= yyssp)
1490 YYABORT;
1491 }
1492
1493 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1494
1495 goto yybackup;
1496
1497/*-----------.
1498| yybackup. |
1499`-----------*/
1500yybackup:
1501
1502/* Do appropriate processing given the current state. */
1503/* Read a look-ahead token if we need one and don't already have one. */
1504/* yyresume: */
1505
1506 /* First try to decide what to do without reference to look-ahead token. */
1507
1508 yyn = yypact[yystate];
1509 if (yyn == YYPACT_NINF)
1510 goto yydefault;
1511
1512 /* Not known => get a look-ahead token if don't already have one. */
1513
1514 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1515 if (yychar == YYEMPTY)
1516 {
1517 YYDPRINTF ((stderr, "Reading a token: "));
1518 yychar = YYLEX;
1519 }
1520
1521 if (yychar <= YYEOF)
1522 {
1523 yychar = yytoken = YYEOF;
1524 YYDPRINTF ((stderr, "Now at end of input.\n"));
1525 }
1526 else
1527 {
1528 yytoken = YYTRANSLATE (yychar);
1529 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1530 }
1531
1532 /* If the proper action on seeing token YYTOKEN is to reduce or to
1533 detect an error, take that action. */
1534 yyn += yytoken;
1535 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1536 goto yydefault;
1537 yyn = yytable[yyn];
1538 if (yyn <= 0)
1539 {
1540 if (yyn == 0 || yyn == YYTABLE_NINF)
1541 goto yyerrlab;
1542 yyn = -yyn;
1543 goto yyreduce;
1544 }
1545
1546 if (yyn == YYFINAL)
1547 YYACCEPT;
1548
1549 /* Shift the look-ahead token. */
1550 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1551
1552 /* Discard the token being shifted unless it is eof. */
1553 if (yychar != YYEOF)
1554 yychar = YYEMPTY;
1555
1556 *++yyvsp = yylval;
1557
1558
1559 /* Count tokens shifted since error; after three, turn off error
1560 status. */
1561 if (yyerrstatus)
1562 yyerrstatus--;
1563
1564 yystate = yyn;
1565 goto yynewstate;
1566
1567
1568/*-----------------------------------------------------------.
1569| yydefault -- do the default action for the current state. |
1570`-----------------------------------------------------------*/
1571yydefault:
1572 yyn = yydefact[yystate];
1573 if (yyn == 0)
1574 goto yyerrlab;
1575 goto yyreduce;
1576
1577
1578/*-----------------------------.
1579| yyreduce -- Do a reduction. |
1580`-----------------------------*/
1581yyreduce:
1582 /* yyn is the number of a rule to reduce with. */
1583 yylen = yyr2[yyn];
1584
1585 /* If YYLEN is nonzero, implement the default value of the action:
1586 `$$ = $1'.
1587
1588 Otherwise, the following line sets YYVAL to garbage.
1589 This behavior is undocumented and Bison
1590 users should not rely upon it. Assigning to YYVAL
1591 unconditionally makes the parser a bit smaller, and it avoids a
1592 GCC warning that YYVAL may be used uninitialized. */
1593 yyval = yyvsp[1-yylen];
1594
1595
1596 YY_REDUCE_PRINT (yyn);
1597 switch (yyn)
1598 {
1599 case 2:
1600#line 172 "awkgram.y"
1601 {
1602 check_funcs();
1603 }
1604 break;
1605
1606 case 4:
1607#line 180 "awkgram.y"
1608 {
1609 begin_or_end_rule = parsing_end_rule = FALSE;
1610 yyerrok;
1611 }
1612 break;
1613
1614 case 5:
1615#line 185 "awkgram.y"
1616 {
1617 begin_or_end_rule = parsing_end_rule = FALSE;
1618 /*
1619 * If errors, give up, don't produce an infinite
1620 * stream of syntax error messages.
1621 */
1622 /* yyerrok; */
1623 }
1624 break;
1625
1626 case 6:
1627#line 197 "awkgram.y"
1628 {
1629 (yyvsp[-1].nodeval)->rnode = (yyvsp[0].nodeval);
1630 }
1631 break;
1632
1633 case 7:
1634#line 201 "awkgram.y"
1635 {
1636 if ((yyvsp[-1].nodeval)->lnode != NULL) {
1637 /* pattern rule with non-empty pattern */
1638 (yyvsp[-1].nodeval)->rnode = node(NULL, Node_K_print_rec, NULL);
1639 } else {
1640 /* an error */
1641 if (begin_or_end_rule)
1642 msg(_("%s blocks must have an action part"),
1643 (parsing_end_rule ? "END" : "BEGIN"));
1644 else
1645 msg(_("each rule must have a pattern or an action part"));
1646 errcount++;
1647 }
1648 }
1649 break;
1650
1651 case 8:
1652#line 216 "awkgram.y"
1653 {
1654 can_return = FALSE;
1655 if ((yyvsp[-1].nodeval))
1656 func_install((yyvsp[-1].nodeval), (yyvsp[0].nodeval));
1657 yyerrok;
1658 }
1659 break;
1660
1661 case 9:
1662#line 226 "awkgram.y"
1663 {
1664 (yyval.nodeval) = append_pattern(&expression_value, (NODE *) NULL);
1665 }
1666 break;
1667
1668 case 10:
1669#line 230 "awkgram.y"
1670 {
1671 (yyval.nodeval) = append_pattern(&expression_value, (yyvsp[0].nodeval));
1672 }
1673 break;
1674
1675 case 11:
1676#line 234 "awkgram.y"
1677 {
1678 NODE *r;
1679
1680 getnode(r);
1681 r->type = Node_line_range;
1682 r->condpair = node((yyvsp[-2].nodeval), Node_cond_pair, (yyvsp[0].nodeval));
1683 r->triggered = FALSE;
1684 (yyval.nodeval) = append_pattern(&expression_value, r);
1685 }
1686 break;
1687
1688 case 12:
1689#line 244 "awkgram.y"
1690 {
1691 begin_or_end_rule = TRUE;
1692 (yyval.nodeval) = append_pattern(&begin_block, (NODE *) NULL);
1693 }
1694 break;
1695
1696 case 13:
1697#line 249 "awkgram.y"
1698 {
1699 begin_or_end_rule = parsing_end_rule = TRUE;
1700 (yyval.nodeval) = append_pattern(&end_block, (NODE *) NULL);
1701 }
1702 break;
1703
1704 case 14:
1705#line 257 "awkgram.y"
1706 { (yyval.nodeval) = (yyvsp[-3].nodeval); }
1707 break;
1708
1709 case 15:
1710#line 262 "awkgram.y"
1711 { (yyval.sval) = (yyvsp[0].sval); }
1712 break;
1713
1714 case 16:
1715#line 264 "awkgram.y"
1716 { (yyval.sval) = (yyvsp[0].sval); }
1717 break;
1718
1719 case 17:
1720#line 266 "awkgram.y"
1721 {
1722 yyerror(_("`%s' is a built-in function, it cannot be redefined"),
1723 tokstart);
1724 errcount++;
1725 (yyval.sval) = builtin_func;
1726 /* yyerrok; */
1727 }
1728 break;
1729
1730 case 20:
1731#line 282 "awkgram.y"
1732 {
1733 param_counter = 0;
1734 }
1735 break;
1736
1737 case 21:
1738#line 286 "awkgram.y"
1739 {
1740 NODE *t;
1741
1742 t = make_param((yyvsp[-4].sval));
1743 t->flags |= FUNC;
1744 (yyval.nodeval) = append_right(t, (yyvsp[-2].nodeval));
1745 can_return = TRUE;
1746 /* check for duplicate parameter names */
1747 if (dup_parms((yyval.nodeval)))
1748 errcount++;
1749 }
1750 break;
1751
1752 case 22:
1753#line 305 "awkgram.y"
1754 { ++want_regexp; }
1755 break;
1756
1757 case 23:
1758#line 307 "awkgram.y"
1759 {
1760 NODE *n;
1761 size_t len = strlen((yyvsp[0].sval));
1762
1763 if (do_lint) {
1764 if (len == 0)
1765 lintwarn(_("regexp constant `//' looks like a C++ comment, but is not"));
1766 else if (((yyvsp[0].sval))[0] == '*' && ((yyvsp[0].sval))[len-1] == '*')
1767 /* possible C comment */
1768 lintwarn(_("regexp constant `/%s/' looks like a C comment, but is not"), tokstart);
1769 }
1770 getnode(n);
1771 n->type = Node_regex;
1772 n->re_exp = make_string((yyvsp[0].sval), len);
1773 n->re_reg = make_regexp((yyvsp[0].sval), len, FALSE, TRUE);
1774 n->re_text = NULL;
1775 n->re_flags = CONST;
1776 n->re_cnt = 1;
1777 (yyval.nodeval) = n;
1778 }
1779 break;
1780
1781 case 26:
1782#line 336 "awkgram.y"
1783 { (yyval.nodeval) = NULL; }
1784 break;
1785
1786 case 27:
1787#line 338 "awkgram.y"
1788 {
1789 if ((yyvsp[0].nodeval) == NULL)
1790 (yyval.nodeval) = (yyvsp[-1].nodeval);
1791 else {
1792 if (do_lint && isnoeffect((yyvsp[0].nodeval)->type))
1793 lintwarn(_("statement may have no effect"));
1794 if ((yyvsp[-1].nodeval) == NULL)
1795 (yyval.nodeval) = (yyvsp[0].nodeval);
1796 else
1797 (yyval.nodeval) = append_right(
1798 ((yyvsp[-1].nodeval)->type == Node_statement_list ? (yyvsp[-1].nodeval)
1799 : node((yyvsp[-1].nodeval), Node_statement_list, (NODE *) NULL)),
1800 ((yyvsp[0].nodeval)->type == Node_statement_list ? (yyvsp[0].nodeval)
1801 : node((yyvsp[0].nodeval), Node_statement_list, (NODE *) NULL)));
1802 }
1803 yyerrok;
1804 }
1805 break;
1806
1807 case 28:
1808#line 356 "awkgram.y"
1809 { (yyval.nodeval) = NULL; }
1810 break;
1811
1812 case 31:
1813#line 366 "awkgram.y"
1814 { (yyval.nodeval) = NULL; }
1815 break;
1816
1817 case 32:
1818#line 368 "awkgram.y"
1819 { (yyval.nodeval) = (yyvsp[-1].nodeval); }
1820 break;
1821
1822 case 33:
1823#line 370 "awkgram.y"
1824 { (yyval.nodeval) = (yyvsp[0].nodeval); }
1825 break;
1826
1827 case 34:
1828#line 372 "awkgram.y"
1829 { (yyval.nodeval) = node((yyvsp[-6].nodeval), Node_K_switch, (yyvsp[-2].nodeval)); }
1830 break;
1831
1832 case 35:
1833#line 374 "awkgram.y"
1834 { (yyval.nodeval) = node((yyvsp[-3].nodeval), Node_K_while, (yyvsp[0].nodeval)); }
1835 break;
1836
1837 case 36:
1838#line 376 "awkgram.y"
1839 { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_K_do, (yyvsp[-5].nodeval)); }
1840 break;
1841
1842 case 37:
1843#line 378 "awkgram.y"
1844 {
1845 /*
1846 * Efficiency hack. Recognize the special case of
1847 *
1848 * for (iggy in foo)
1849 * delete foo[iggy]
1850 *
1851 * and treat it as if it were
1852 *
1853 * delete foo
1854 *
1855 * Check that the body is a `delete a[i]' statement,
1856 * and that both the loop var and array names match.
1857 */
1858 if ((yyvsp[0].nodeval) != NULL && (yyvsp[0].nodeval)->type == Node_K_delete && (yyvsp[0].nodeval)->rnode != NULL) {
1859 NODE *arr, *sub;
1860
1861 assert((yyvsp[0].nodeval)->rnode->type == Node_expression_list);
1862 arr = (yyvsp[0].nodeval)->lnode; /* array var */
1863 sub = (yyvsp[0].nodeval)->rnode->lnode; /* index var */
1864
1865 if ( (arr->type == Node_var_new
1866 || arr->type == Node_var_array
1867 || arr->type == Node_param_list)
1868 && (sub->type == Node_var_new
1869 || sub->type == Node_var
1870 || sub->type == Node_param_list)
1871 && strcmp((yyvsp[-5].sval), sub->vname) == 0
1872 && strcmp((yyvsp[-3].sval), arr->vname) == 0) {
1873 (yyvsp[0].nodeval)->type = Node_K_delete_loop;
1874 (yyval.nodeval) = (yyvsp[0].nodeval);
1875 free((yyvsp[-5].sval)); /* thanks to valgrind for pointing these out */
1876 free((yyvsp[-3].sval));
1877 }
1878 else
1879 goto regular_loop;
1880 } else {
1881 regular_loop:
1882 (yyval.nodeval) = node((yyvsp[0].nodeval), Node_K_arrayfor,
1883 make_for_loop(variable((yyvsp[-5].sval), CAN_FREE, Node_var),
1884 (NODE *) NULL, variable((yyvsp[-3].sval), CAN_FREE, Node_var_array)));
1885 }
1886 }
1887 break;
1888
1889 case 38:
1890#line 422 "awkgram.y"
1891 {
1892 (yyval.nodeval) = node((yyvsp[0].nodeval), Node_K_for, (NODE *) make_for_loop((yyvsp[-9].nodeval), (yyvsp[-6].nodeval), (yyvsp[-3].nodeval)));
1893 }
1894 break;
1895
1896 case 39:
1897#line 426 "awkgram.y"
1898 {
1899 (yyval.nodeval) = node((yyvsp[0].nodeval), Node_K_for,
1900 (NODE *) make_for_loop((yyvsp[-8].nodeval), (NODE *) NULL, (yyvsp[-3].nodeval)));
1901 }
1902 break;
1903
1904 case 40:
1905#line 432 "awkgram.y"
1906 { (yyval.nodeval) = node((NODE *) NULL, Node_K_break, (NODE *) NULL); }
1907 break;
1908
1909 case 41:
1910#line 435 "awkgram.y"
1911 { (yyval.nodeval) = node((NODE *) NULL, Node_K_continue, (NODE *) NULL); }
1912 break;
1913
1914 case 42:
1915#line 437 "awkgram.y"
1916 { NODETYPE type;
1917
1918 if (begin_or_end_rule)
1919 yyerror(_("`%s' used in %s action"), "next",
1920 (parsing_end_rule ? "END" : "BEGIN"));
1921 type = Node_K_next;
1922 (yyval.nodeval) = node((NODE *) NULL, type, (NODE *) NULL);
1923 }
1924 break;
1925
1926 case 43:
1927#line 446 "awkgram.y"
1928 {
1929 if (do_traditional) {
1930 /*
1931 * can't use yyerror, since may have overshot
1932 * the source line
1933 */
1934 errcount++;
1935 error(_("`nextfile' is a gawk extension"));
1936 }
1937 if (do_lint)
1938 lintwarn(_("`nextfile' is a gawk extension"));
1939 if (begin_or_end_rule) {
1940 /* same thing */
1941 errcount++;
1942 error(_("`%s' used in %s action"), "nextfile",
1943 (parsing_end_rule ? "END" : "BEGIN"));
1944 }
1945 (yyval.nodeval) = node((NODE *) NULL, Node_K_nextfile, (NODE *) NULL);
1946 }
1947 break;
1948
1949 case 44:
1950#line 466 "awkgram.y"
1951 { (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_K_exit, (NODE *) NULL); }
1952 break;
1953
1954 case 45:
1955#line 468 "awkgram.y"
1956 {
1957 if (! can_return)
1958 yyerror(_("`return' used outside function context"));
1959 }
1960 break;
1961
1962 case 46:
1963#line 473 "awkgram.y"
1964 {
1965 (yyval.nodeval) = node((yyvsp[-1].nodeval) == NULL ? Nnull_string : (yyvsp[-1].nodeval),
1966 Node_K_return, (NODE *) NULL);
1967 }
1968 break;
1969
1970 case 48:
1971#line 489 "awkgram.y"
1972 { in_print = TRUE; in_parens = 0; }
1973 break;
1974
1975 case 49:
1976#line 490 "awkgram.y"
1977 {
1978 /*
1979 * Optimization: plain `print' has no expression list, so $3 is null.
1980 * If $3 is an expression list with one element (rnode == null)
1981 * and lnode is a field spec for field 0, we have `print $0'.
1982 * For both, use Node_K_print_rec, which is faster for these two cases.
1983 */
1984 if ((yyvsp[-3].nodetypeval) == Node_K_print &&
1985 ((yyvsp[-1].nodeval) == NULL
1986 || ((yyvsp[-1].nodeval)->type == Node_expression_list
1987 && (yyvsp[-1].nodeval)->rnode == NULL
1988 && (yyvsp[-1].nodeval)->lnode->type == Node_field_spec
1989 && (yyvsp[-1].nodeval)->lnode->lnode->type == Node_val
1990 && (yyvsp[-1].nodeval)->lnode->lnode->numbr == 0.0))
1991 ) {
1992 static int warned = FALSE;
1993
1994 (yyval.nodeval) = node(NULL, Node_K_print_rec, (yyvsp[0].nodeval));
1995
1996 if (do_lint && (yyvsp[-1].nodeval) == NULL && begin_or_end_rule && ! warned) {
1997 warned = TRUE;
1998 lintwarn(
1999 _("plain `print' in BEGIN or END rule should probably be `print \"\"'"));
2000 }
2001 } else {
2002 (yyval.nodeval) = node((yyvsp[-1].nodeval), (yyvsp[-3].nodetypeval), (yyvsp[0].nodeval));
2003 if ((yyval.nodeval)->type == Node_K_printf)
2004 count_args((yyval.nodeval));
2005 }
2006 }
2007 break;
2008
2009 case 50:
2010#line 521 "awkgram.y"
2011 { (yyval.nodeval) = node(variable((yyvsp[-3].sval), CAN_FREE, Node_var_array), Node_K_delete, (yyvsp[-1].nodeval)); }
2012 break;
2013
2014 case 51:
2015#line 523 "awkgram.y"
2016 {
2017 if (do_lint)
2018 lintwarn(_("`delete array' is a gawk extension"));
2019 if (do_traditional) {
2020 /*
2021 * can't use yyerror, since may have overshot
2022 * the source line
2023 */
2024 errcount++;
2025 error(_("`delete array' is a gawk extension"));
2026 }
2027 (yyval.nodeval) = node(variable((yyvsp[0].sval), CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL);
2028 }
2029 break;
2030
2031 case 52:
2032#line 537 "awkgram.y"
2033 {
2034 /* this is for tawk compatibility. maybe the warnings should always be done. */
2035 if (do_lint)
2036 lintwarn(_("`delete(array)' is a non-portable tawk extension"));
2037 if (do_traditional) {
2038 /*
2039 * can't use yyerror, since may have overshot
2040 * the source line
2041 */
2042 errcount++;
2043 error(_("`delete(array)' is a non-portable tawk extension"));
2044 }
2045 (yyval.nodeval) = node(variable((yyvsp[-1].sval), CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL);
2046 }
2047 break;
2048
2049 case 53:
2050#line 552 "awkgram.y"
2051 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2052 break;
2053
2054 case 54:
2055#line 557 "awkgram.y"
2056 { (yyval.nodeval) = NULL; }
2057 break;
2058
2059 case 55:
2060#line 559 "awkgram.y"
2061 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2062 break;
2063
2064 case 56:
2065#line 564 "awkgram.y"
2066 {
2067 if ((yyvsp[0].nodeval) == NULL) {
2068 (yyval.nodeval) = NULL;
2069 } else {
2070 NODE *dflt = NULL;
2071 NODE *head = (yyvsp[0].nodeval);
2072 NODE *curr;
2073
2074 const char **case_values = NULL;
2075
2076 int maxcount = 128;
2077 int case_count = 0;
2078 int i;
2079
2080 emalloc(case_values, const char **, sizeof(char*) * maxcount, "switch_body");
2081 for (curr = (yyvsp[0].nodeval); curr != NULL; curr = curr->rnode) {
2082 /* Assure that case statement values are unique. */
2083 if (curr->lnode->type == Node_K_case) {
2084 char *caseval;
2085
2086 if (curr->lnode->lnode->type == Node_regex)
2087 caseval = curr->lnode->lnode->re_exp->stptr;
2088 else
2089 caseval = force_string(tree_eval(curr->lnode->lnode))->stptr;
2090
2091 for (i = 0; i < case_count; i++)
2092 if (strcmp(caseval, case_values[i]) == 0)
2093 yyerror(_("duplicate case values in switch body: %s"), caseval);
2094
2095 if (case_count >= maxcount) {
2096 maxcount += 128;
2097 erealloc(case_values, const char **, sizeof(char*) * maxcount, "switch_body");
2098 }
2099 case_values[case_count++] = caseval;
2100 } else {
2101 /* Otherwise save a pointer to the default node. */
2102 if (dflt != NULL)
2103 yyerror(_("Duplicate `default' detected in switch body"));
2104 dflt = curr;
2105 }
2106 }
2107
2108 free(case_values);
2109
2110 /* Create the switch body. */
2111 (yyval.nodeval) = node(head, Node_switch_body, dflt);
2112 }
2113 }
2114 break;
2115
2116 case 57:
2117#line 616 "awkgram.y"
2118 { (yyval.nodeval) = NULL; }
2119 break;
2120
2121 case 58:
2122#line 618 "awkgram.y"
2123 {
2124 if ((yyvsp[0].nodeval) == NULL)
2125 (yyval.nodeval) = (yyvsp[-1].nodeval);
2126 else {
2127 if (do_lint && isnoeffect((yyvsp[0].nodeval)->type))
2128 lintwarn(_("statement may have no effect"));
2129 if ((yyvsp[-1].nodeval) == NULL)
2130 (yyval.nodeval) = node((yyvsp[0].nodeval), Node_case_list, (NODE *) NULL);
2131 else
2132 (yyval.nodeval) = append_right(
2133 ((yyvsp[-1].nodeval)->type == Node_case_list ? (yyvsp[-1].nodeval) : node((yyvsp[-1].nodeval), Node_case_list, (NODE *) NULL)),
2134 ((yyvsp[0].nodeval)->type == Node_case_list ? (yyvsp[0].nodeval) : node((yyvsp[0].nodeval), Node_case_list, (NODE *) NULL))
2135 );
2136 }
2137 yyerrok;
2138 }
2139 break;
2140
2141 case 59:
2142#line 635 "awkgram.y"
2143 { (yyval.nodeval) = NULL; }
2144 break;
2145
2146 case 60:
2147#line 640 "awkgram.y"
2148 { (yyval.nodeval) = node((yyvsp[-3].nodeval), Node_K_case, (yyvsp[0].nodeval)); }
2149 break;
2150
2151 case 61:
2152#line 642 "awkgram.y"
2153 { (yyval.nodeval) = node((NODE *) NULL, Node_K_default, (yyvsp[0].nodeval)); }
2154 break;
2155
2156 case 62:
2157#line 647 "awkgram.y"
2158 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2159 break;
2160
2161 case 63:
2162#line 649 "awkgram.y"
2163 {
2164 (yyvsp[0].nodeval)->numbr = -(force_number((yyvsp[0].nodeval)));
2165 (yyval.nodeval) = (yyvsp[0].nodeval);
2166 }
2167 break;
2168
2169 case 64:
2170#line 654 "awkgram.y"
2171 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2172 break;
2173
2174 case 65:
2175#line 656 "awkgram.y"
2176 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2177 break;
2178
2179 case 66:
2180#line 658 "awkgram.y"
2181 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2182 break;
2183
2184 case 70:
2185#line 673 "awkgram.y"
2186 { (yyval.nodeval) = node((yyvsp[-3].nodeval), Node_expression_list, (yyvsp[-1].nodeval)); }
2187 break;
2188
2189 case 71:
2190#line 678 "awkgram.y"
2191 {
2192 in_print = FALSE;
2193 in_parens = 0;
2194 (yyval.nodeval) = NULL;
2195 }
2196 break;
2197
2198 case 72:
2199#line 683 "awkgram.y"
2200 { in_print = FALSE; in_parens = 0; }
2201 break;
2202
2203 case 73:
2204#line 684 "awkgram.y"
2205 {
2206 (yyval.nodeval) = node((yyvsp[0].nodeval), (yyvsp[-2].nodetypeval), (NODE *) NULL);
2207 if ((yyvsp[-2].nodetypeval) == Node_redirect_twoway
2208 && (yyvsp[0].nodeval)->type == Node_K_getline
2209 && (yyvsp[0].nodeval)->rnode != NULL
2210 && (yyvsp[0].nodeval)->rnode->type == Node_redirect_twoway)
2211 yyerror(_("multistage two-way pipelines don't work"));
2212 }
2213 break;
2214
2215 case 74:
2216#line 696 "awkgram.y"
2217 {
2218 (yyval.nodeval) = node((yyvsp[-3].nodeval), Node_K_if,
2219 node((yyvsp[0].nodeval), Node_if_branches, (NODE *) NULL));
2220 }
2221 break;
2222
2223 case 75:
2224#line 702 "awkgram.y"
2225 { (yyval.nodeval) = node((yyvsp[-6].nodeval), Node_K_if,
2226 node((yyvsp[-3].nodeval), Node_if_branches, (yyvsp[0].nodeval))); }
2227 break;
2228
2229 case 80:
2230#line 718 "awkgram.y"
2231 { (yyval.nodeval) = NULL; }
2232 break;
2233
2234 case 81:
2235#line 720 "awkgram.y"
2236 { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_redirect_input, (NODE *) NULL); }
2237 break;
2238
2239 case 82:
2240#line 725 "awkgram.y"
2241 { (yyval.nodeval) = NULL; }
2242 break;
2243
2244 case 83:
2245#line 727 "awkgram.y"
2246 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2247 break;
2248
2249 case 84:
2250#line 732 "awkgram.y"
2251 { (yyval.nodeval) = make_param((yyvsp[0].sval)); }
2252 break;
2253
2254 case 85:
2255#line 734 "awkgram.y"
2256 { (yyval.nodeval) = append_right((yyvsp[-2].nodeval), make_param((yyvsp[0].sval))); yyerrok; }
2257 break;
2258
2259 case 86:
2260#line 736 "awkgram.y"
2261 { (yyval.nodeval) = NULL; }
2262 break;
2263
2264 case 87:
2265#line 738 "awkgram.y"
2266 { (yyval.nodeval) = NULL; }
2267 break;
2268
2269 case 88:
2270#line 740 "awkgram.y"
2271 { (yyval.nodeval) = NULL; }
2272 break;
2273
2274 case 89:
2275#line 746 "awkgram.y"
2276 { (yyval.nodeval) = NULL; }
2277 break;
2278
2279 case 90:
2280#line 748 "awkgram.y"
2281 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2282 break;
2283
2284 case 91:
2285#line 753 "awkgram.y"
2286 { (yyval.nodeval) = NULL; }
2287 break;
2288
2289 case 92:
2290#line 755 "awkgram.y"
2291 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2292 break;
2293
2294 case 93:
2295#line 760 "awkgram.y"
2296 { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_expression_list, (NODE *) NULL); }
2297 break;
2298
2299 case 94:
2300#line 762 "awkgram.y"
2301 {
2302 (yyval.nodeval) = append_right((yyvsp[-2].nodeval),
2303 node((yyvsp[0].nodeval), Node_expression_list, (NODE *) NULL));
2304 yyerrok;
2305 }
2306 break;
2307
2308 case 95:
2309#line 768 "awkgram.y"
2310 { (yyval.nodeval) = NULL; }
2311 break;
2312
2313 case 96:
2314#line 770 "awkgram.y"
2315 { (yyval.nodeval) = NULL; }
2316 break;
2317
2318 case 97:
2319#line 772 "awkgram.y"
2320 { (yyval.nodeval) = NULL; }
2321 break;
2322
2323 case 98:
2324#line 774 "awkgram.y"
2325 { (yyval.nodeval) = NULL; }
2326 break;
2327
2328 case 99:
2329#line 779 "awkgram.y"
2330 {
2331 if (do_lint && (yyvsp[0].nodeval)->type == Node_regex)
2332 lintwarn(_("regular expression on right of assignment"));
2333 /*
2334 * Optimization of `x = x y'. Can save lots of time
2335 * if done a lot.
2336 */
2337 if (( (yyvsp[-2].nodeval)->type == Node_var
2338 || (yyvsp[-2].nodeval)->type == Node_var_new
2339 || (yyvsp[-2].nodeval)->type == Node_param_list)
2340 && (yyvsp[-1].nodetypeval) == Node_assign
2341 && (yyvsp[0].nodeval)->type == Node_concat
2342 && (yyvsp[0].nodeval)->lnode == (yyvsp[-2].nodeval)) {
2343 (yyvsp[0].nodeval)->type = Node_assign_concat; /* Just change the type */
2344 (yyval.nodeval) = (yyvsp[0].nodeval); /* And use it directly */
2345 } else
2346 (yyval.nodeval) = node((yyvsp[-2].nodeval), (yyvsp[-1].nodetypeval), (yyvsp[0].nodeval));
2347 }
2348 break;
2349
2350 case 100:
2351#line 798 "awkgram.y"
2352 { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_and, (yyvsp[0].nodeval)); }
2353 break;
2354
2355 case 101:
2356#line 800 "awkgram.y"
2357 { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_or, (yyvsp[0].nodeval)); }
2358 break;
2359
2360 case 102:
2361#line 802 "awkgram.y"
2362 {
2363 if ((yyvsp[-2].nodeval)->type == Node_regex)
2364 warning(_("regular expression on left of `~' or `!~' operator"));
2365 (yyval.nodeval) = node((yyvsp[-2].nodeval), (yyvsp[-1].nodetypeval), mk_rexp((yyvsp[0].nodeval)));
2366 }
2367 break;
2368
2369 case 103:
2370#line 808 "awkgram.y"
2371 { (yyval.nodeval) = node(variable((yyvsp[0].sval), CAN_FREE, Node_var_array), Node_in_array, (yyvsp[-2].nodeval)); }
2372 break;
2373
2374 case 104:
2375#line 810 "awkgram.y"
2376 {
2377 if (do_lint && (yyvsp[0].nodeval)->type == Node_regex)
2378 lintwarn(_("regular expression on right of comparison"));
2379 (yyval.nodeval) = node((yyvsp[-2].nodeval), (yyvsp[-1].nodetypeval), (yyvsp[0].nodeval));
2380 }
2381 break;
2382
2383 case 105:
2384#line 816 "awkgram.y"
2385 { (yyval.nodeval) = node((yyvsp[-4].nodeval), Node_cond_exp, node((yyvsp[-2].nodeval), Node_if_branches, (yyvsp[0].nodeval)));}
2386 break;
2387
2388 case 106:
2389#line 818 "awkgram.y"
2390 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2391 break;
2392
2393 case 107:
2394#line 823 "awkgram.y"
2395 { (yyval.nodetypeval) = (yyvsp[0].nodetypeval); }
2396 break;
2397
2398 case 108:
2399#line 825 "awkgram.y"
2400 { (yyval.nodetypeval) = (yyvsp[0].nodetypeval); }
2401 break;
2402
2403 case 109:
2404#line 827 "awkgram.y"
2405 { (yyval.nodetypeval) = Node_assign_quotient; }
2406 break;
2407
2408 case 110:
2409#line 832 "awkgram.y"
2410 { (yyval.nodetypeval) = (yyvsp[0].nodetypeval); }
2411 break;
2412
2413 case 111:
2414#line 834 "awkgram.y"
2415 { (yyval.nodetypeval) = Node_less; }
2416 break;
2417
2418 case 113:
2419#line 839 "awkgram.y"
2420 { (yyval.nodetypeval) = Node_greater; }
2421 break;
2422
2423 case 114:
2424#line 844 "awkgram.y"
2425 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2426 break;
2427
2428 case 115:
2429#line 846 "awkgram.y"
2430 {
2431 (yyval.nodeval) = node(node(make_number(0.0),
2432 Node_field_spec,
2433 (NODE *) NULL),
2434 Node_nomatch,
2435 (yyvsp[0].nodeval));
2436 }
2437 break;
2438
2439 case 116:
2440#line 854 "awkgram.y"
2441 { (yyval.nodeval) = node(variable((yyvsp[0].sval), CAN_FREE, Node_var_array), Node_in_array, (yyvsp[-3].nodeval)); }
2442 break;
2443
2444 case 117:
2445#line 856 "awkgram.y"
2446 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2447 break;
2448
2449 case 118:
2450#line 858 "awkgram.y"
2451 { (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_concat, (yyvsp[0].nodeval)); }
2452 break;
2453
2454 case 120:
2455#line 865 "awkgram.y"
2456 { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_exp, (yyvsp[0].nodeval)); }
2457 break;
2458
2459 case 121:
2460#line 867 "awkgram.y"
2461 { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_times, (yyvsp[0].nodeval)); }
2462 break;
2463
2464 case 122:
2465#line 869 "awkgram.y"
2466 { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_quotient, (yyvsp[0].nodeval)); }
2467 break;
2468
2469 case 123:
2470#line 871 "awkgram.y"
2471 { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_mod, (yyvsp[0].nodeval)); }
2472 break;
2473
2474 case 124:
2475#line 873 "awkgram.y"
2476 { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_plus, (yyvsp[0].nodeval)); }
2477 break;
2478
2479 case 125:
2480#line 875 "awkgram.y"
2481 { (yyval.nodeval) = node((yyvsp[-2].nodeval), Node_minus, (yyvsp[0].nodeval)); }
2482 break;
2483
2484 case 126:
2485#line 877 "awkgram.y"
2486 {
2487 if (do_lint && parsing_end_rule && (yyvsp[0].nodeval) == NULL)
2488 lintwarn(_("non-redirected `getline' undefined inside END action"));
2489 (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_K_getline, (yyvsp[0].nodeval));
2490 }
2491 break;
2492
2493 case 127:
2494#line 883 "awkgram.y"
2495 {
2496 (yyval.nodeval) = node((yyvsp[0].nodeval), Node_K_getline,
2497 node((yyvsp[-3].nodeval), (yyvsp[-2].nodetypeval), (NODE *) NULL));
2498 }
2499 break;
2500
2501 case 128:
2502#line 888 "awkgram.y"
2503 { (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_postincrement, (NODE *) NULL); }
2504 break;
2505
2506 case 129:
2507#line 890 "awkgram.y"
2508 { (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_postdecrement, (NODE *) NULL); }
2509 break;
2510
2511 case 130:
2512#line 895 "awkgram.y"
2513 { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_not, (NODE *) NULL); }
2514 break;
2515
2516 case 131:
2517#line 897 "awkgram.y"
2518 { (yyval.nodeval) = (yyvsp[-1].nodeval); }
2519 break;
2520
2521 case 132:
2522#line 900 "awkgram.y"
2523 { (yyval.nodeval) = snode((yyvsp[-1].nodeval), Node_builtin, (int) (yyvsp[-3].lval)); }
2524 break;
2525
2526 case 133:
2527#line 902 "awkgram.y"
2528 { (yyval.nodeval) = snode((yyvsp[-1].nodeval), Node_builtin, (int) (yyvsp[-3].lval)); }
2529 break;
2530
2531 case 134:
2532#line 904 "awkgram.y"
2533 {
2534 if (do_lint)
2535 lintwarn(_("call of `length' without parentheses is not portable"));
2536 (yyval.nodeval) = snode((NODE *) NULL, Node_builtin, (int) (yyvsp[0].lval));
2537 if (do_posix)
2538 warning(_("call of `length' without parentheses is deprecated by POSIX"));
2539 }
2540 break;
2541
2542 case 135:
2543#line 912 "awkgram.y"
2544 {
2545 (yyval.nodeval) = node((yyvsp[-1].nodeval), Node_func_call, make_string((yyvsp[-3].sval), strlen((yyvsp[-3].sval))));
2546 (yyval.nodeval)->funcbody = NULL;
2547 func_use((yyvsp[-3].sval), FUNC_USE);
2548 param_sanity((yyvsp[-1].nodeval));
2549 free((yyvsp[-3].sval));
2550 }
2551 break;
2552
2553 case 137:
2554#line 921 "awkgram.y"
2555 { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_preincrement, (NODE *) NULL); }
2556 break;
2557
2558 case 138:
2559#line 923 "awkgram.y"
2560 { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_predecrement, (NODE *) NULL); }
2561 break;
2562
2563 case 139:
2564#line 925 "awkgram.y"
2565 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2566 break;
2567
2568 case 140:
2569#line 927 "awkgram.y"
2570 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2571 break;
2572
2573 case 141:
2574#line 930 "awkgram.y"
2575 {
2576 if ((yyvsp[0].nodeval)->type == Node_val && ((yyvsp[0].nodeval)->flags & (STRCUR|STRING)) == 0) {
2577 (yyvsp[0].nodeval)->numbr = -(force_number((yyvsp[0].nodeval)));
2578 (yyval.nodeval) = (yyvsp[0].nodeval);
2579 } else
2580 (yyval.nodeval) = node((yyvsp[0].nodeval), Node_unary_minus, (NODE *) NULL);
2581 }
2582 break;
2583
2584 case 142:
2585#line 938 "awkgram.y"
2586 {
2587 /*
2588 * was: $$ = $2
2589 * POSIX semantics: force a conversion to numeric type
2590 */
2591 (yyval.nodeval) = node (make_number(0.0), Node_plus, (yyvsp[0].nodeval));
2592 }
2593 break;
2594
2595 case 143:
2596#line 949 "awkgram.y"
2597 { (yyval.nodeval) = NULL; }
2598 break;
2599
2600 case 144:
2601#line 951 "awkgram.y"
2602 { (yyval.nodeval) = (yyvsp[0].nodeval); }
2603 break;
2604
2605 case 145:
2606#line 956 "awkgram.y"
2607 { (yyval.nodeval) = variable((yyvsp[0].sval), CAN_FREE, Node_var_new); }
2608 break;
2609
2610 case 146:
2611#line 958 "awkgram.y"
2612 {
2613 NODE *n;
2614
2615 if ((n = lookup((yyvsp[-3].sval))) != NULL && ! isarray(n))
2616 yyerror(_("use of non-array as array"));
2617 else if ((yyvsp[-1].nodeval) == NULL) {
2618 fatal(_("invalid subscript expression"));
2619 } else if ((yyvsp[-1].nodeval)->rnode == NULL) {
2620 (yyval.nodeval) = node(variable((yyvsp[-3].sval), CAN_FREE, Node_var_array), Node_subscript, (yyvsp[-1].nodeval)->lnode);
2621 freenode((yyvsp[-1].nodeval));
2622 } else
2623 (yyval.nodeval) = node(variable((yyvsp[-3].sval), CAN_FREE, Node_var_array), Node_subscript, (yyvsp[-1].nodeval));
2624 }
2625 break;
2626
2627 case 147:
2628#line 972 "awkgram.y"
2629 { (yyval.nodeval) = node((yyvsp[0].nodeval), Node_field_spec, (NODE *) NULL); }
2630 break;
2631
2632 case 149:
2633#line 986 "awkgram.y"
2634 { yyerrok; }
2635 break;
2636
2637 case 150:
2638#line 990 "awkgram.y"
2639 { yyerrok; }
2640 break;
2641
2642 case 153:
2643#line 999 "awkgram.y"
2644 { yyerrok; }
2645 break;
2646
2647 case 154:
2648#line 1003 "awkgram.y"
2649 { yyerrok; }
2650 break;
2651
2652 case 155:
2653#line 1006 "awkgram.y"
2654 { yyerrok; }
2655 break;
2656
2657
2658 }
2659
2660/* Line 1037 of yacc.c. */
2661#line 2661 "y.tab.c"
2662
2663
2664 yyvsp -= yylen;
2665 yyssp -= yylen;
2666
2667
2668 YY_STACK_PRINT (yyss, yyssp);
2669
2670 *++yyvsp = yyval;
2671
2672
2673 /* Now `shift' the result of the reduction. Determine what state
2674 that goes to, based on the state we popped back to and the rule
2675 number reduced by. */
2676
2677 yyn = yyr1[yyn];
2678
2679 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
2680 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
2681 yystate = yytable[yystate];
2682 else
2683 yystate = yydefgoto[yyn - YYNTOKENS];
2684
2685 goto yynewstate;
2686
2687
2688/*------------------------------------.
2689| yyerrlab -- here on detecting error |
2690`------------------------------------*/
2691yyerrlab:
2692 /* If not already recovering from an error, report this error. */
2693 if (!yyerrstatus)
2694 {
2695 ++yynerrs;
2696#if YYERROR_VERBOSE
2697 yyn = yypact[yystate];
2698
2699 if (YYPACT_NINF < yyn && yyn < YYLAST)
2700 {
2701 YYSIZE_T yysize = 0;
2702 int yytype = YYTRANSLATE (yychar);
2703 const char* yyprefix;
2704 char *yymsg;
2705 int yyx;
2706
2707 /* Start YYX at -YYN if negative to avoid negative indexes in
2708 YYCHECK. */
2709 int yyxbegin = yyn < 0 ? -yyn : 0;
2710
2711 /* Stay within bounds of both yycheck and yytname. */
2712 int yychecklim = YYLAST - yyn;
2713 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
2714 int yycount = 0;
2715
2716 yyprefix = ", expecting ";
2717 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
2718 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
2719 {
2720 yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
2721 yycount += 1;
2722 if (yycount == 5)
2723 {
2724 yysize = 0;
2725 break;
2726 }
2727 }
2728 yysize += (sizeof ("syntax error, unexpected ")
2729 + yystrlen (yytname[yytype]));
2730 yymsg = (char *) YYSTACK_ALLOC (yysize);
2731 if (yymsg != 0)
2732 {
2733 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
2734 yyp = yystpcpy (yyp, yytname[yytype]);
2735
2736 if (yycount < 5)
2737 {
2738 yyprefix = ", expecting ";
2739 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
2740 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
2741 {
2742 yyp = yystpcpy (yyp, yyprefix);
2743 yyp = yystpcpy (yyp, yytname[yyx]);
2744 yyprefix = " or ";
2745 }
2746 }
2747 yyerror (yymsg);
2748 YYSTACK_FREE (yymsg);
2749 }
2750 else
2751 yyerror ("syntax error; also virtual memory exhausted");
2752 }
2753 else
2754#endif /* YYERROR_VERBOSE */
2755 yyerror ("syntax error");
2756 }
2757
2758
2759
2760 if (yyerrstatus == 3)
2761 {
2762 /* If just tried and failed to reuse look-ahead token after an
2763 error, discard it. */
2764
2765 if (yychar <= YYEOF)
2766 {
2767 /* If at end of input, pop the error token,
2768 then the rest of the stack, then return failure. */
2769 if (yychar == YYEOF)
2770 for (;;)
2771 {
2772
2773 YYPOPSTACK;
2774 if (yyssp == yyss)
2775 YYABORT;
2776 yydestruct ("Error: popping",
2777 yystos[*yyssp], yyvsp);
2778 }
2779 }
2780 else
2781 {
2782 yydestruct ("Error: discarding", yytoken, &yylval);
2783 yychar = YYEMPTY;
2784 }
2785 }
2786
2787 /* Else will try to reuse look-ahead token after shifting the error
2788 token. */
2789 goto yyerrlab1;
2790
2791
2792/*---------------------------------------------------.
2793| yyerrorlab -- error raised explicitly by YYERROR. |
2794`---------------------------------------------------*/
2795yyerrorlab:
2796
2797#ifdef __GNUC__
2798 /* Pacify GCC when the user code never invokes YYERROR and the label
2799 yyerrorlab therefore never appears in user code. */
2800 if (0)
2801 goto yyerrorlab;
2802#endif
2803
2804yyvsp -= yylen;
2805 yyssp -= yylen;
2806 yystate = *yyssp;
2807 goto yyerrlab1;
2808
2809
2810/*-------------------------------------------------------------.
2811| yyerrlab1 -- common code for both syntax error and YYERROR. |
2812`-------------------------------------------------------------*/
2813yyerrlab1:
2814 yyerrstatus = 3; /* Each real token shifted decrements this. */
2815
2816 for (;;)
2817 {
2818 yyn = yypact[yystate];
2819 if (yyn != YYPACT_NINF)
2820 {
2821 yyn += YYTERROR;
2822 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
2823 {
2824 yyn = yytable[yyn];
2825 if (0 < yyn)
2826 break;
2827 }
2828 }
2829
2830 /* Pop the current state because it cannot handle the error token. */
2831 if (yyssp == yyss)
2832 YYABORT;
2833
2834
2835 yydestruct ("Error: popping", yystos[yystate], yyvsp);
2836 YYPOPSTACK;
2837 yystate = *yyssp;
2838 YY_STACK_PRINT (yyss, yyssp);
2839 }
2840
2841 if (yyn == YYFINAL)
2842 YYACCEPT;
2843
2844 *++yyvsp = yylval;
2845
2846
2847 /* Shift the error token. */
2848 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
2849
2850 yystate = yyn;
2851 goto yynewstate;
2852
2853
2854/*-------------------------------------.
2855| yyacceptlab -- YYACCEPT comes here. |
2856`-------------------------------------*/
2857yyacceptlab:
2858 yyresult = 0;
2859 goto yyreturn;
2860
2861/*-----------------------------------.
2862| yyabortlab -- YYABORT comes here. |
2863`-----------------------------------*/
2864yyabortlab:
2865 yydestruct ("Error: discarding lookahead",
2866 yytoken, &yylval);
2867 yychar = YYEMPTY;
2868 yyresult = 1;
2869 goto yyreturn;
2870
2871#ifndef yyoverflow
2872/*----------------------------------------------.
2873| yyoverflowlab -- parser overflow comes here. |
2874`----------------------------------------------*/
2875yyoverflowlab:
2876 yyerror ("parser stack overflow");
2877 yyresult = 2;
2878 /* Fall through. */
2879#endif
2880
2881yyreturn:
2882#ifndef yyoverflow
2883 if (yyss != yyssa)
2884 YYSTACK_FREE (yyss);
2885#endif
2886 return yyresult;
2887}
2888
2889
2890#line 1009 "awkgram.y"
2891
2892
2893struct token {
2894 const char *operator; /* text to match */
2895 NODETYPE value; /* node type */
2896 int class; /* lexical class */
2897 unsigned flags; /* # of args. allowed and compatability */
2898# define ARGS 0xFF /* 0, 1, 2, 3 args allowed (any combination */
2899# define A(n) (1<<(n))
2900# define VERSION_MASK 0xFF00 /* old awk is zero */
2901# define NOT_OLD 0x0100 /* feature not in old awk */
2902# define NOT_POSIX 0x0200 /* feature not in POSIX */
2903# define GAWKX 0x0400 /* gawk extension */
2904# define RESX 0x0800 /* Bell Labs Research extension */
2905 NODE *(*ptr) P((NODE *)); /* function that implements this keyword */
2906};
2907
2908/* Tokentab is sorted ascii ascending order, so it can be binary searched. */
2909/* Function pointers come from declarations in awk.h. */
2910
2911static const struct token tokentab[] = {
2912{"BEGIN", Node_illegal, LEX_BEGIN, 0, 0},
2913{"END", Node_illegal, LEX_END, 0, 0},
2914#ifdef ARRAYDEBUG
2915{"adump", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump},
2916#endif
2917{"and", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_and},
2918{"asort", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_asort},
2919{"asorti", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_asorti},
2920{"atan2", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2},
2921{"bindtextdomain", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain},
2922{"break", Node_K_break, LEX_BREAK, 0, 0},
2923#ifdef ALLOW_SWITCH
2924{"case", Node_K_case, LEX_CASE, GAWKX, 0},
2925#endif
2926{"close", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close},
2927{"compl", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl},
2928{"continue", Node_K_continue, LEX_CONTINUE, 0, 0},
2929{"cos", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos},
2930{"dcgettext", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext},
2931{"dcngettext", Node_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext},
2932#ifdef ALLOW_SWITCH
2933{"default", Node_K_default, LEX_DEFAULT, GAWKX, 0},
2934#endif
2935{"delete", Node_K_delete, LEX_DELETE, NOT_OLD, 0},
2936{"do", Node_K_do, LEX_DO, NOT_OLD, 0},
2937{"else", Node_illegal, LEX_ELSE, 0, 0},
2938{"exit", Node_K_exit, LEX_EXIT, 0, 0},
2939{"exp", Node_builtin, LEX_BUILTIN, A(1), do_exp},
2940{"extension", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext},
2941{"fflush", Node_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush},
2942{"for", Node_K_for, LEX_FOR, 0, 0},
2943{"func", Node_K_function, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0},
2944{"function", Node_K_function, LEX_FUNCTION, NOT_OLD, 0},
2945{"gensub", Node_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), do_gensub},
2946{"getline", Node_K_getline, LEX_GETLINE, NOT_OLD, 0},
2947{"gsub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_gsub},
2948{"if", Node_K_if, LEX_IF, 0, 0},
2949{"in", Node_illegal, LEX_IN, 0, 0},
2950{"index", Node_builtin, LEX_BUILTIN, A(2), do_index},
2951{"int", Node_builtin, LEX_BUILTIN, A(1), do_int},
2952{"length", Node_builtin, LEX_LENGTH, A(0)|A(1), do_length},
2953{"log", Node_builtin, LEX_BUILTIN, A(1), do_log},
2954{"lshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift},
2955{"match", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match},
2956{"mktime", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime},
2957{"next", Node_K_next, LEX_NEXT, 0, 0},
2958{"nextfile", Node_K_nextfile, LEX_NEXTFILE, GAWKX, 0},
2959{"or", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_or},
2960{"print", Node_K_print, LEX_PRINT, 0, 0},
2961{"printf", Node_K_printf, LEX_PRINTF, 0, 0},
2962{"rand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand},
2963{"return", Node_K_return, LEX_RETURN, NOT_OLD, 0},
2964{"rshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift},
2965{"sin", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin},
2966{"split", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_split},
2967{"sprintf", Node_builtin, LEX_BUILTIN, 0, do_sprintf},
2968{"sqrt", Node_builtin, LEX_BUILTIN, A(1), do_sqrt},
2969{"srand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand},
2970#if defined(GAWKDEBUG) || defined(ARRAYDEBUG) /* || ... */
2971{"stopme", Node_builtin, LEX_BUILTIN, GAWKX|A(0), stopme},
2972#endif
2973{"strftime", Node_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2), do_strftime},
2974{"strtonum", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum},
2975{"sub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_sub},
2976{"substr", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_substr},
2977#ifdef ALLOW_SWITCH
2978{"switch", Node_K_switch, LEX_SWITCH, GAWKX, 0},
2979#endif
2980{"system", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system},
2981{"systime", Node_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime},
2982{"tolower", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower},
2983{"toupper", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper},
2984{"while", Node_K_while, LEX_WHILE, 0, 0},
2985{"xor", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor},
2986};
2987
2988#ifdef MBS_SUPPORT
2989/* Variable containing the current shift state. */
2990static mbstate_t cur_mbstate;
2991/* Ring buffer containing current characters. */
2992#define MAX_CHAR_IN_RING_BUFFER 8
2993#define RING_BUFFER_SIZE (MAX_CHAR_IN_RING_BUFFER * MB_LEN_MAX)
2994static char cur_char_ring[RING_BUFFER_SIZE];
2995/* Index for ring buffers. */
2996static int cur_ring_idx;
2997/* This macro means that last nextc() return a singlebyte character
2998 or 1st byte of a multibyte character. */
2999#define nextc_is_1stbyte (cur_char_ring[cur_ring_idx] == 1)
3000#else /* MBS_SUPPORT */
3001/* a dummy */
3002#define nextc_is_1stbyte 1
3003#endif /* MBS_SUPPORT */
3004
3005/* getfname --- return name of a builtin function (for pretty printing) */
3006
3007const char *
3008getfname(register NODE *(*fptr)(NODE *))
3009{
3010 register int i, j;
3011
3012 j = sizeof(tokentab) / sizeof(tokentab[0]);
3013 /* linear search, no other way to do it */
3014 for (i = 0; i < j; i++)
3015 if (tokentab[i].ptr == fptr)
3016 return tokentab[i].operator;
3017
3018 return NULL;
3019}
3020
3021/* yyerror --- print a syntax error message, show where */
3022
3023/*
3024 * Function identifier purposely indented to avoid mangling
3025 * by ansi2knr. Sigh.
3026 */
3027
3028static void
3029#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
3030 yyerror(const char *m, ...)
3031#else
3032/* VARARGS0 */
3033 yyerror(va_alist)
3034 va_dcl
3035#endif
3036{
3037 va_list args;
3038 const char *mesg = NULL;
3039 register char *bp, *cp;
3040 char *scan;
3041 char *buf;
3042 int count;
3043 static char end_of_file_line[] = "(END OF FILE)";
3044 char save;
3045
3046 errcount++;
3047 /* Find the current line in the input file */
3048 if (lexptr && lexeme) {
3049 if (thisline == NULL) {
3050 cp = lexeme;
3051 if (*cp == '\n') {
3052 cp--;
3053 mesg = _("unexpected newline or end of string");
3054 }
3055 for (; cp != lexptr_begin && *cp != '\n'; --cp)
3056 continue;
3057 if (*cp == '\n')
3058 cp++;
3059 thisline = cp;
3060 }
3061 /* NL isn't guaranteed */
3062 bp = lexeme;
3063 while (bp < lexend && *bp && *bp != '\n')
3064 bp++;
3065 } else {
3066 thisline = end_of_file_line;
3067 bp = thisline + strlen(thisline);
3068 }
3069
3070 /*
3071 * Saving and restoring *bp keeps valgrind happy,
3072 * since the guts of glibc uses strlen, even though
3073 * we're passing an explict precision. Sigh.
3074 *
3075 * 8/2003: We may not need this anymore.
3076 */
3077 save = *bp;
3078 *bp = '\0';
3079
3080 msg("%.*s", (int) (bp - thisline), thisline);
3081
3082 *bp = save;
3083
3084#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
3085 va_start(args, m);
3086 if (mesg == NULL)
3087 mesg = m;
3088#else
3089 va_start(args);
3090 if (mesg == NULL)
3091 mesg = va_arg(args, char *);
3092#endif
3093 count = (bp - thisline) + strlen(mesg) + 2 + 1;
3094 emalloc(buf, char *, count, "yyerror");
3095
3096 bp = buf;
3097
3098 if (lexptr != NULL) {
3099 scan = thisline;
3100 while (scan < lexeme)
3101 if (*scan++ == '\t')
3102 *bp++ = '\t';
3103 else
3104 *bp++ = ' ';
3105 *bp++ = '^';
3106 *bp++ = ' ';
3107 }
3108 strcpy(bp, mesg);
3109 err("", buf, args);
3110 va_end(args);
3111 free(buf);
3112}
3113
3114/* get_src_buf --- read the next buffer of source program */
3115
3116static char *
3117get_src_buf()
3118{
3119 static int samefile = FALSE;
3120 static int nextfile = 0;
3121 static char *buf = NULL;
3122 static size_t buflen = 0;
3123 static int fd;
3124
3125 int n;
3126 register char *scan;
3127 int newfile;
3128 struct stat sbuf;
3129 int readcount = 0;
3130 int l;
3131 char *readloc;
3132
3133again:
3134 newfile = FALSE;
3135 if (nextfile > numfiles)
3136 return NULL;
3137
3138 if (srcfiles[nextfile].stype == CMDLINE) {
3139 if ((l = strlen(srcfiles[nextfile].val)) == 0) {
3140 /*
3141 * Yet Another Special case:
3142 * gawk '' /path/name
3143 * Sigh.
3144 */
3145 static int warned = FALSE;
3146
3147 if (do_lint && ! warned) {
3148 warned = TRUE;
3149 lintwarn(_("empty program text on command line"));
3150 }
3151 ++nextfile;
3152 goto again;
3153 }
3154 if (srcfiles[nextfile].val[l-1] == '\n') {
3155 /* has terminating newline, can use it directly */
3156 sourceline = 1;
3157 lexptr = lexptr_begin = srcfiles[nextfile].val;
3158 /* fall through to pointer adjustment and return, below */
3159 } else {
3160 /* copy it into static buffer */
3161
3162 /* make sure buffer exists and has room */
3163 if (buflen == 0) {
3164 emalloc(buf, char *, l+2, "get_src_buf");
3165 buflen = l + 2;
3166 } else if (l+2 > buflen) {
3167 erealloc(buf, char *, l+2, "get_src_buf");
3168 buflen = l + 2;
3169 } /* else
3170 buffer has room, just use it */
3171
3172 /* copy in data */
3173 memcpy(buf, srcfiles[nextfile].val, l);
3174 buf[l] = '\n';
3175 buf[++l] = '\0';
3176
3177 /* set vars and return */
3178 lexptr = lexptr_begin = buf;
3179 }
3180 lexend = lexptr + l;
3181 nextfile++; /* for next entry to this routine */
3182 return lexptr;
3183 }
3184
3185 if (! samefile) {
3186 source = srcfiles[nextfile].val;
3187 if (source == NULL) { /* read all the source files, all done */
3188 if (buf != NULL) {
3189 free(buf);
3190 buf = NULL;
3191 }
3192 buflen = 0;
3193 return lexeme = lexptr = lexptr_begin = NULL;
3194 }
3195 fd = pathopen(source);
3196 if (fd <= INVALID_HANDLE) {
3197 char *in;
3198
3199 /* suppress file name and line no. in error mesg */
3200 in = source;
3201 source = NULL;
3202 fatal(_("can't open source file `%s' for reading (%s)"),
3203 in, strerror(errno));
3204 }
3205 l = optimal_bufsize(fd, & sbuf);
3206 /*
3207 * Make sure that something silly like
3208 * AWKBUFSIZE=8 make check
3209 * works ok.
3210 */
3211#define A_DECENT_BUFFER_SIZE 128
3212 if (l < A_DECENT_BUFFER_SIZE)
3213 l = A_DECENT_BUFFER_SIZE;
3214#undef A_DECENT_BUFFER_SIZE
3215
3216 newfile = TRUE;
3217
3218 /* make sure buffer exists and has room */
3219 if (buflen == 0) {
3220 emalloc(buf, char *, l+2, "get_src_buf");
3221 buflen = l + 2;
3222 } else if (l+2 > buflen) {
3223 erealloc(buf, char *, l+2, "get_src_buf");
3224 buflen = l + 2;
3225 } /* else
3226 buffer has room, just use it */
3227
3228 readcount = l;
3229 readloc = lexeme = lexptr = lexptr_begin = buf;
3230 samefile = TRUE;
3231 sourceline = 1;
3232 } else {
3233 /*
3234 * In same file, ran off edge of buffer.
3235 * Shift current line down to front, adjust
3236 * pointers and fill in the rest of the buffer.
3237 */
3238
3239 int lexeme_offset = lexeme - lexptr_begin;
3240 int lexptr_offset = lexptr - lexptr_begin;
3241 int lexend_offset = lexend - lexptr_begin;
3242
3243 /* find beginning of current line */
3244 for (scan = lexeme; scan >= lexptr_begin; scan--) {
3245 if (*scan == '\n') {
3246 scan++;
3247 break;
3248 }
3249 }
3250
3251 if (scan <= buf) {
3252 /* have to grow the buffer */
3253 buflen *= 2;
3254 erealloc(buf, char *, buflen, "get_src_buf");
3255 } else {
3256 /* shift things down */
3257 memmove(buf, scan, lexend - scan);
3258 /*
3259 * make offsets relative to start of line,
3260 * not start of buffer.
3261 */
3262 lexend_offset = lexend - scan;
3263 lexeme_offset = lexeme - scan;
3264 lexptr_offset = lexptr - scan;
3265 }
3266
3267 /* adjust pointers */
3268 lexeme = buf + lexeme_offset;
3269 lexptr = buf + lexptr_offset;
3270 lexend = buf + lexend_offset;
3271 lexptr_begin = buf;
3272 readcount = buflen - (lexend - buf);
3273 readloc = lexend;
3274 }
3275
3276 /* add more data to buffer */
3277 n = read(fd, readloc, readcount);
3278 if (n == -1)
3279 fatal(_("can't read sourcefile `%s' (%s)"),
3280 source, strerror(errno));
3281 if (n == 0) {
3282 if (newfile) {
3283 static int warned = FALSE;
3284
3285 if (do_lint && ! warned) {
3286 warned = TRUE;
3287 lintwarn(_("source file `%s' is empty"), source);
3288 }
3289 }
3290 if (fd != fileno(stdin)) /* safety */
3291 close(fd);
3292 samefile = FALSE;
3293 nextfile++;
3294 goto again;
3295 }
3296 lexend = lexptr + n;
3297 return lexptr;
3298}
3299
3300/* tokadd --- add a character to the token buffer */
3301
3302#define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok)
3303
3304/* tokexpand --- grow the token buffer */
3305
3306char *
3307tokexpand()
3308{
3309 static int toksize = 60;
3310 int tokoffset;
3311
3312 tokoffset = tok - tokstart;
3313 toksize *= 2;
3314 if (tokstart != NULL)
3315 erealloc(tokstart, char *, toksize, "tokexpand");
3316 else
3317 emalloc(tokstart, char *, toksize, "tokexpand");
3318 tokend = tokstart + toksize;
3319 tok = tokstart + tokoffset;
3320 return tok;
3321}
3322
3323/* nextc --- get the next input character */
3324
3325#ifdef MBS_SUPPORT
3326
3327static int
3328nextc(void)
3329{
3330 if (gawk_mb_cur_max > 1) {
3331 if (!lexptr || lexptr >= lexend) {
3332 if (! get_src_buf())
3333 return EOF;
3334 }
3335
3336 /* Update the buffer index. */
3337 cur_ring_idx = (cur_ring_idx == RING_BUFFER_SIZE - 1)? 0 :
3338 cur_ring_idx + 1;
3339
3340 /* Did we already check the current character? */
3341 if (cur_char_ring[cur_ring_idx] == 0) {
3342 /* No, we need to check the next character on the buffer. */
3343 int idx, work_ring_idx = cur_ring_idx;
3344 mbstate_t tmp_state;
3345 size_t mbclen;
3346
3347 for (idx = 0 ; lexptr + idx < lexend ; idx++) {
3348 tmp_state = cur_mbstate;
3349 mbclen = mbrlen(lexptr, idx + 1, &tmp_state);
3350
3351 if (mbclen == 1 || mbclen == (size_t)-1 || mbclen == 0) {
3352 /* It is a singlebyte character, non-complete multibyte
3353 character or EOF. We treat it as a singlebyte
3354 character. */
3355 cur_char_ring[work_ring_idx] = 1;
3356 break;
3357 } else if (mbclen == (size_t)-2) {
3358 /* It is not a complete multibyte character. */
3359 cur_char_ring[work_ring_idx] = idx + 1;
3360 } else {
3361 /* mbclen > 1 */
3362 cur_char_ring[work_ring_idx] = mbclen;
3363 break;
3364 }
3365 work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
3366 0 : work_ring_idx + 1;
3367 }
3368 cur_mbstate = tmp_state;
3369
3370 /* Put a mark on the position on which we write next character. */
3371 work_ring_idx = (work_ring_idx == RING_BUFFER_SIZE - 1)?
3372 0 : work_ring_idx + 1;
3373 cur_char_ring[work_ring_idx] = 0;
3374 }
3375
3376 return (int) (unsigned char) *lexptr++;
3377 }
3378 else {
3379 int c;
3380
3381 if (lexptr && lexptr < lexend)
3382 c = (int) (unsigned char) *lexptr++;
3383 else if (get_src_buf())
3384 c = (int) (unsigned char) *lexptr++;
3385 else
3386 c = EOF;
3387
3388 return c;
3389 }
3390}
3391
3392#else /* MBS_SUPPORT */
3393
3394#if GAWKDEBUG
3395int
3396nextc(void)
3397{
3398 int c;
3399
3400 if (lexptr && lexptr < lexend)
3401 c = (int) (unsigned char) *lexptr++;
3402 else if (get_src_buf())
3403 c = (int) (unsigned char) *lexptr++;
3404 else
3405 c = EOF;
3406
3407 return c;
3408}
3409#else
3410#define nextc() ((lexptr && lexptr < lexend) ? \
3411 ((int) (unsigned char) *lexptr++) : \
3412 (get_src_buf() ? ((int) (unsigned char) *lexptr++) : EOF) \
3413 )
3414#endif
3415
3416#endif /* MBS_SUPPORT */
3417
3418/* pushback --- push a character back on the input */
3419
3420static inline void
3421pushback(void)
3422{
3423#ifdef MBS_SUPPORT
3424 if (gawk_mb_cur_max > 1)
3425 cur_ring_idx = (cur_ring_idx == 0)? RING_BUFFER_SIZE - 1 :
3426 cur_ring_idx - 1;
3427#endif
3428 (lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr);
3429}
3430
3431
3432/* allow_newline --- allow newline after &&, ||, ? and : */
3433
3434static void
3435allow_newline(void)
3436{
3437 int c;
3438
3439 for (;;) {
3440 c = nextc();
3441 if (c == EOF)
3442 break;
3443 if (c == '#') {
3444 while ((c = nextc()) != '\n' && c != EOF)
3445 continue;
3446 if (c == EOF)
3447 break;
3448 }
3449 if (c == '\n')
3450 sourceline++;
3451 if (! ISSPACE(c)) {
3452 pushback();
3453 break;
3454 }
3455 }
3456}
3457
3458/* yylex --- Read the input and turn it into tokens. */
3459
3460static int
3461yylex(void)
3462{
3463 register int c;
3464 int seen_e = FALSE; /* These are for numbers */
3465 int seen_point = FALSE;
3466 int esc_seen; /* for literal strings */
3467 int mid;
3468 static int did_newline = FALSE;
3469 char *tokkey;
3470 static int lasttok = 0, eof_warned = FALSE;
3471 int inhex = FALSE;
3472 int intlstr = FALSE;
3473
3474 if (nextc() == EOF) {
3475 if (lasttok != NEWLINE) {
3476 lasttok = NEWLINE;
3477 if (do_lint && ! eof_warned) {
3478 lintwarn(_("source file does not end in newline"));
3479 eof_warned = TRUE;
3480 }
3481 return NEWLINE; /* fake it */
3482 }
3483 return 0;
3484 }
3485 pushback();
3486#if defined OS2 || defined __EMX__
3487 /*
3488 * added for OS/2's extproc feature of cmd.exe
3489 * (like #! in BSD sh)
3490 */
3491 if (strncasecmp(lexptr, "extproc ", 8) == 0) {
3492 while (*lexptr && *lexptr != '\n')
3493 lexptr++;
3494 }
3495#endif
3496 lexeme = lexptr;
3497 thisline = NULL;
3498 if (want_regexp) {
3499 int in_brack = 0; /* count brackets, [[:alnum:]] allowed */
3500 /*
3501 * Counting brackets is non-trivial. [[] is ok,
3502 * and so is [\]], with a point being that /[/]/ as a regexp
3503 * constant has to work.
3504 *
3505 * Do not count [ or ] if either one is preceded by a \.
3506 * A `[' should be counted if
3507 * a) it is the first one so far (in_brack == 0)
3508 * b) it is the `[' in `[:'
3509 * A ']' should be counted if not preceded by a \, since
3510 * it is either closing `:]' or just a plain list.
3511 * According to POSIX, []] is how you put a ] into a set.
3512 * Try to handle that too.
3513 *
3514 * The code for \ handles \[ and \].
3515 */
3516
3517 want_regexp = FALSE;
3518 tok = tokstart;
3519 for (;;) {
3520 c = nextc();
3521
3522 if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
3523 case '[':
3524 /* one day check for `.' and `=' too */
3525 if (nextc() == ':' || in_brack == 0)
3526 in_brack++;
3527 pushback();
3528 break;
3529 case ']':
3530 if (tokstart[0] == '['
3531 && (tok == tokstart + 1
3532 || (tok == tokstart + 2
3533 && tokstart[1] == '^')))
3534 /* do nothing */;
3535 else
3536 in_brack--;
3537 break;
3538 case '\\':
3539 if ((c = nextc()) == EOF) {
3540 yyerror(_("unterminated regexp ends with `\\' at end of file"));
3541 goto end_regexp; /* kludge */
3542 } else if (c == '\n') {
3543 sourceline++;
3544 continue;
3545 } else {
3546 tokadd('\\');
3547 tokadd(c);
3548 continue;
3549 }
3550 break;
3551 case '/': /* end of the regexp */
3552 if (in_brack > 0)
3553 break;
3554end_regexp:
3555 tokadd('\0');
3556 yylval.sval = tokstart;
3557 if (do_lint) {
3558 int peek = nextc();
3559
3560 pushback();
3561 if (peek == 'i' || peek == 's') {
3562 if (source)
3563 lintwarn(
3564 _("%s: %d: tawk regex modifier `/.../%c' doesn't work in gawk"),
3565 source, sourceline, peek);
3566 else
3567 lintwarn(
3568 _("tawk regex modifier `/.../%c' doesn't work in gawk"),
3569 peek);
3570 }
3571 }
3572 return lasttok = REGEXP;
3573 case '\n':
3574 pushback();
3575 yyerror(_("unterminated regexp"));
3576 goto end_regexp; /* kludge */
3577 case EOF:
3578 yyerror(_("unterminated regexp at end of file"));
3579 goto end_regexp; /* kludge */
3580 }
3581 tokadd(c);
3582 }
3583 }
3584retry:
3585
3586 /* skipping \r is a hack, but windows is just too pervasive. sigh. */
3587 while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
3588 continue;
3589
3590 lexeme = lexptr ? lexptr - 1 : lexptr;
3591 thisline = NULL;
3592 tok = tokstart;
3593 yylval.nodetypeval = Node_illegal;
3594
3595 if (gawk_mb_cur_max == 1 || nextc_is_1stbyte) switch (c) {
3596 case EOF:
3597 if (lasttok != NEWLINE) {
3598 lasttok = NEWLINE;
3599 if (do_lint && ! eof_warned) {
3600 lintwarn(_("source file does not end in newline"));
3601 eof_warned = TRUE;
3602 }
3603 return NEWLINE; /* fake it */
3604 }
3605 return 0;
3606
3607 case '\n':
3608 sourceline++;
3609 return lasttok = NEWLINE;
3610
3611 case '#': /* it's a comment */
3612 while ((c = nextc()) != '\n') {
3613 if (c == EOF) {
3614 if (lasttok != NEWLINE) {
3615 lasttok = NEWLINE;
3616 if (do_lint && ! eof_warned) {
3617 lintwarn(
3618 _("source file does not end in newline"));
3619 eof_warned = TRUE;
3620 }
3621 return NEWLINE; /* fake it */
3622 }
3623 return 0;
3624 }
3625 }
3626 sourceline++;
3627 return lasttok = NEWLINE;
3628
3629 case '\\':
3630#ifdef RELAXED_CONTINUATION
3631 /*
3632 * This code puports to allow comments and/or whitespace
3633 * after the `\' at the end of a line used for continuation.
3634 * Use it at your own risk. We think it's a bad idea, which
3635 * is why it's not on by default.
3636 */
3637 if (! do_traditional) {
3638 /* strip trailing white-space and/or comment */
3639 while ((c = nextc()) == ' ' || c == '\t' || c == '\r')
3640 continue;
3641 if (c == '#') {
3642 if (do_lint)
3643 lintwarn(
3644 _("use of `\\ #...' line continuation is not portable"));
3645 while ((c = nextc()) != '\n')
3646 if (c == EOF)
3647 break;
3648 }
3649 pushback();
3650 }
3651#endif /* RELAXED_CONTINUATION */
3652 if (nextc() == '\n') {
3653 sourceline++;
3654 goto retry;
3655 } else {
3656 yyerror(_("backslash not last character on line"));
3657 exit(1);
3658 }
3659 break;
3660
3661 case ':':
3662 case '?':
3663 if (! do_posix)
3664 allow_newline();
3665 return lasttok = c;
3666
3667 /*
3668 * in_parens is undefined unless we are parsing a print
3669 * statement (in_print), but why bother with a check?
3670 */
3671 case ')':
3672 in_parens--;
3673 return lasttok = c;
3674
3675 case '(':
3676 in_parens++;
3677 /* FALL THROUGH */
3678 case '$':
3679 case ';':
3680 case '{':
3681 case ',':
3682 case '[':
3683 case ']':
3684 return lasttok = c;
3685
3686 case '*':
3687 if ((c = nextc()) == '=') {
3688 yylval.nodetypeval = Node_assign_times;
3689 return lasttok = ASSIGNOP;
3690 } else if (do_posix) {
3691 pushback();
3692 return lasttok = '*';
3693 } else if (c == '*') {
3694 /* make ** and **= aliases for ^ and ^= */
3695 static int did_warn_op = FALSE, did_warn_assgn = FALSE;
3696
3697 if (nextc() == '=') {
3698 if (! did_warn_assgn) {
3699 did_warn_assgn = TRUE;
3700 if (do_lint)
3701 lintwarn(_("POSIX does not allow operator `**='"));
3702 if (do_lint_old)
3703 warning(_("old awk does not support operator `**='"));
3704 }
3705 yylval.nodetypeval = Node_assign_exp;
3706 return ASSIGNOP;
3707 } else {
3708 pushback();
3709 if (! did_warn_op) {
3710 did_warn_op = TRUE;
3711 if (do_lint)
3712 lintwarn(_("POSIX does not allow operator `**'"));
3713 if (do_lint_old)
3714 warning(_("old awk does not support operator `**'"));
3715 }
3716 return lasttok = '^';
3717 }
3718 }
3719 pushback();
3720 return lasttok = '*';
3721
3722 case '/':
3723 if (nextc() == '=') {
3724 pushback();
3725 return lasttok = SLASH_BEFORE_EQUAL;
3726 }
3727 pushback();
3728 return lasttok = '/';
3729
3730 case '%':
3731 if (nextc() == '=') {
3732 yylval.nodetypeval = Node_assign_mod;
3733 return lasttok = ASSIGNOP;
3734 }
3735 pushback();
3736 return lasttok = '%';
3737
3738 case '^':
3739 {
3740 static int did_warn_op = FALSE, did_warn_assgn = FALSE;
3741
3742 if (nextc() == '=') {
3743 if (do_lint_old && ! did_warn_assgn) {
3744 did_warn_assgn = TRUE;
3745 warning(_("operator `^=' is not supported in old awk"));
3746 }
3747 yylval.nodetypeval = Node_assign_exp;
3748 return lasttok = ASSIGNOP;
3749 }
3750 pushback();
3751 if (do_lint_old && ! did_warn_op) {
3752 did_warn_op = TRUE;
3753 warning(_("operator `^' is not supported in old awk"));
3754 }
3755 return lasttok = '^';
3756 }
3757
3758 case '+':
3759 if ((c = nextc()) == '=') {
3760 yylval.nodetypeval = Node_assign_plus;
3761 return lasttok = ASSIGNOP;
3762 }
3763 if (c == '+')
3764 return lasttok = INCREMENT;
3765 pushback();
3766 return lasttok = '+';
3767
3768 case '!':
3769 if ((c = nextc()) == '=') {
3770 yylval.nodetypeval = Node_notequal;
3771 return lasttok = RELOP;
3772 }
3773 if (c == '~') {
3774 yylval.nodetypeval = Node_nomatch;
3775 return lasttok = MATCHOP;
3776 }
3777 pushback();
3778 return lasttok = '!';
3779
3780 case '<':
3781 if (nextc() == '=') {
3782 yylval.nodetypeval = Node_leq;
3783 return lasttok = RELOP;
3784 }
3785 yylval.nodetypeval = Node_less;
3786 pushback();
3787 return lasttok = '<';
3788
3789 case '=':
3790 if (nextc() == '=') {
3791 yylval.nodetypeval = Node_equal;
3792 return lasttok = RELOP;
3793 }
3794 yylval.nodetypeval = Node_assign;
3795 pushback();
3796 return lasttok = ASSIGN;
3797
3798 case '>':
3799 if ((c = nextc()) == '=') {
3800 yylval.nodetypeval = Node_geq;
3801 return lasttok = RELOP;
3802 } else if (c == '>') {
3803 yylval.nodetypeval = Node_redirect_append;
3804 return lasttok = IO_OUT;
3805 }
3806 pushback();
3807 if (in_print && in_parens == 0) {
3808 yylval.nodetypeval = Node_redirect_output;
3809 return lasttok = IO_OUT;
3810 }
3811 yylval.nodetypeval = Node_greater;
3812 return lasttok = '>';
3813
3814 case '~':
3815 yylval.nodetypeval = Node_match;
3816 return lasttok = MATCHOP;
3817
3818 case '}':
3819 /*
3820 * Added did newline stuff. Easier than
3821 * hacking the grammar.
3822 */
3823 if (did_newline) {
3824 did_newline = FALSE;
3825 return lasttok = c;
3826 }
3827 did_newline++;
3828 --lexptr; /* pick up } next time */
3829 return lasttok = NEWLINE;
3830
3831 case '"':
3832 string:
3833 esc_seen = FALSE;
3834 while ((c = nextc()) != '"') {
3835 if (c == '\n') {
3836 pushback();
3837 yyerror(_("unterminated string"));
3838 exit(1);
3839 }
3840 if ((gawk_mb_cur_max == 1 || nextc_is_1stbyte) &&
3841 c == '\\') {
3842 c = nextc();
3843 if (c == '\n') {
3844 sourceline++;
3845 continue;
3846 }
3847 esc_seen = TRUE;
3848 tokadd('\\');
3849 }
3850 if (c == EOF) {
3851 pushback();
3852 yyerror(_("unterminated string"));
3853 exit(1);
3854 }
3855 tokadd(c);
3856 }
3857 yylval.nodeval = make_str_node(tokstart,
3858 tok - tokstart, esc_seen ? SCAN : 0);
3859 yylval.nodeval->flags |= PERM;
3860 if (intlstr) {
3861 yylval.nodeval->flags |= INTLSTR;
3862 intlstr = FALSE;
3863 if (do_intl)
3864 dumpintlstr(yylval.nodeval->stptr,
3865 yylval.nodeval->stlen);
3866 }
3867 return lasttok = YSTRING;
3868
3869 case '-':
3870 if ((c = nextc()) == '=') {
3871 yylval.nodetypeval = Node_assign_minus;
3872 return lasttok = ASSIGNOP;
3873 }
3874 if (c == '-')
3875 return lasttok = DECREMENT;
3876 pushback();
3877 return lasttok = '-';
3878
3879 case '.':
3880 c = nextc();
3881 pushback();
3882 if (! ISDIGIT(c))
3883 return lasttok = '.';
3884 else
3885 c = '.';
3886 /* FALL THROUGH */
3887 case '0':
3888 case '1':
3889 case '2':
3890 case '3':
3891 case '4':
3892 case '5':
3893 case '6':
3894 case '7':
3895 case '8':
3896 case '9':
3897 /* It's a number */
3898 for (;;) {
3899 int gotnumber = FALSE;
3900
3901 tokadd(c);
3902 switch (c) {
3903 case 'x':
3904 case 'X':
3905 if (do_traditional)
3906 goto done;
3907 if (tok == tokstart + 2) {
3908 int peek = nextc();
3909
3910 if (ISXDIGIT(peek)) {
3911 inhex = TRUE;
3912 pushback(); /* following digit */
3913 } else {
3914 pushback(); /* x or X */
3915 goto done;
3916 }
3917 }
3918 break;
3919 case '.':
3920 /* period ends exponent part of floating point number */
3921 if (seen_point || seen_e) {
3922 gotnumber = TRUE;
3923 break;
3924 }
3925 seen_point = TRUE;
3926 break;
3927 case 'e':
3928 case 'E':
3929 if (inhex)
3930 break;
3931 if (seen_e) {
3932 gotnumber = TRUE;
3933 break;
3934 }
3935 seen_e = TRUE;
3936 if ((c = nextc()) == '-' || c == '+') {
3937 int c2 = nextc();
3938
3939 if (ISDIGIT(c2)) {
3940 tokadd(c);
3941 tokadd(c2);
3942 } else {
3943 pushback(); /* non-digit after + or - */
3944 pushback(); /* + or - */
3945 pushback(); /* e or E */
3946 }
3947 } else if (! ISDIGIT(c)) {
3948 pushback(); /* character after e or E */
3949 pushback(); /* e or E */
3950 } else {
3951 pushback(); /* digit */
3952 }
3953 break;
3954 case 'a':
3955 case 'A':
3956 case 'b':
3957 case 'B':
3958 case 'c':
3959 case 'C':
3960 case 'D':
3961 case 'd':
3962 case 'f':
3963 case 'F':
3964 if (do_traditional || ! inhex)
3965 goto done;
3966 /* fall through */
3967 case '0':
3968 case '1':
3969 case '2':
3970 case '3':
3971 case '4':
3972 case '5':
3973 case '6':
3974 case '7':
3975 case '8':
3976 case '9':
3977 break;
3978 default:
3979 done:
3980 gotnumber = TRUE;
3981 }
3982 if (gotnumber)
3983 break;
3984 c = nextc();
3985 }
3986 if (c != EOF)
3987 pushback();
3988 else if (do_lint && ! eof_warned) {
3989 lintwarn(_("source file does not end in newline"));
3990 eof_warned = TRUE;
3991 }
3992 tokadd('\0');
3993 if (! do_traditional && isnondecimal(tokstart, FALSE)) {
3994 if (do_lint) {
3995 if (ISDIGIT(tokstart[1])) /* not an 'x' or 'X' */
3996 lintwarn("numeric constant `%.*s' treated as octal",
3997 (int) strlen(tokstart)-1, tokstart);
3998 else if (tokstart[1] == 'x' || tokstart[1] == 'X')
3999 lintwarn("numeric constant `%.*s' treated as hexadecimal",
4000 (int) strlen(tokstart)-1, tokstart);
4001 }
4002 yylval.nodeval = make_number(nondec2awknum(tokstart, strlen(tokstart)));
4003 } else
4004 yylval.nodeval = make_number(atof(tokstart));
4005 yylval.nodeval->flags |= PERM;
4006 return lasttok = YNUMBER;
4007
4008 case '&':
4009 if ((c = nextc()) == '&') {
4010 yylval.nodetypeval = Node_and;
4011 allow_newline();
4012 return lasttok = LEX_AND;
4013 }
4014 pushback();
4015 return lasttok = '&';
4016
4017 case '|':
4018 if ((c = nextc()) == '|') {
4019 yylval.nodetypeval = Node_or;
4020 allow_newline();
4021 return lasttok = LEX_OR;
4022 } else if (! do_traditional && c == '&') {
4023 yylval.nodetypeval = Node_redirect_twoway;
4024 return lasttok = (in_print && in_parens == 0 ? IO_OUT : IO_IN);
4025 }
4026 pushback();
4027 if (in_print && in_parens == 0) {
4028 yylval.nodetypeval = Node_redirect_pipe;
4029 return lasttok = IO_OUT;
4030 } else {
4031 yylval.nodetypeval = Node_redirect_pipein;
4032 return lasttok = IO_IN;
4033 }
4034 }
4035
4036 if (c != '_' && ! ISALPHA(c)) {
4037 yyerror(_("invalid char '%c' in expression"), c);
4038 exit(1);
4039 }
4040
4041 /*
4042 * Lots of fog here. Consider:
4043 *
4044 * print "xyzzy"$_"foo"
4045 *
4046 * Without the check for ` lasttok != '$' ', this is parsed as
4047 *
4048 * print "xxyzz" $(_"foo")
4049 *
4050 * With the check, it is "correctly" parsed as three
4051 * string concatenations. Sigh. This seems to be
4052 * "more correct", but this is definitely one of those
4053 * occasions where the interactions are funny.
4054 */
4055 if (! do_traditional && c == '_' && lasttok != '$') {
4056 if ((c = nextc()) == '"') {
4057 intlstr = TRUE;
4058 goto string;
4059 }
4060 pushback();
4061 c = '_';
4062 }
4063
4064 /* it's some type of name-type-thing. Find its length. */
4065 tok = tokstart;
4066 while (is_identchar(c)) {
4067 tokadd(c);
4068 c = nextc();
4069 }
4070 tokadd('\0');
4071 emalloc(tokkey, char *, tok - tokstart, "yylex");
4072 memcpy(tokkey, tokstart, tok - tokstart);
4073 if (c != EOF)
4074 pushback();
4075 else if (do_lint && ! eof_warned) {
4076 lintwarn(_("source file does not end in newline"));
4077 eof_warned = TRUE;
4078 }
4079
4080 /* See if it is a special token. */
4081
4082 if ((mid = check_special(tokstart)) >= 0) {
4083 if (do_lint) {
4084 if (tokentab[mid].flags & GAWKX)
4085 lintwarn(_("`%s' is a gawk extension"),
4086 tokentab[mid].operator);
4087 if (tokentab[mid].flags & RESX)
4088 lintwarn(_("`%s' is a Bell Labs extension"),
4089 tokentab[mid].operator);
4090 if (tokentab[mid].flags & NOT_POSIX)
4091 lintwarn(_("POSIX does not allow `%s'"),
4092 tokentab[mid].operator);
4093 }
4094 if (do_lint_old && (tokentab[mid].flags & NOT_OLD))
4095 warning(_("`%s' is not supported in old awk"),
4096 tokentab[mid].operator);
4097 if ((do_traditional && (tokentab[mid].flags & GAWKX))
4098 || (do_posix && (tokentab[mid].flags & NOT_POSIX)))
4099 ;
4100 else {
4101 if (tokentab[mid].class == LEX_BUILTIN
4102 || tokentab[mid].class == LEX_LENGTH)
4103 yylval.lval = mid;
4104 else
4105 yylval.nodetypeval = tokentab[mid].value;
4106 free(tokkey);
4107 return lasttok = tokentab[mid].class;
4108 }
4109 }
4110
4111 yylval.sval = tokkey;
4112 if (*lexptr == '(')
4113 return lasttok = FUNC_CALL;
4114 else {
4115 static short goto_warned = FALSE;
4116
4117#define SMART_ALECK 1
4118 if (SMART_ALECK && do_lint
4119 && ! goto_warned && strcasecmp(tokkey, "goto") == 0) {
4120 goto_warned = TRUE;
4121 lintwarn(_("`goto' considered harmful!\n"));
4122 }
4123 return lasttok = NAME;
4124 }
4125}
4126
4127/* node_common --- common code for allocating a new node */
4128
4129static NODE *
4130node_common(NODETYPE op)
4131{
4132 register NODE *r;
4133
4134 getnode(r);
4135 r->type = op;
4136 r->flags = MALLOC;
4137 /* if lookahead is a NL, lineno is 1 too high */
4138 if (lexeme && lexeme >= lexptr_begin && *lexeme == '\n')
4139 r->source_line = sourceline - 1;
4140 else
4141 r->source_line = sourceline;
4142 r->source_file = source;
4143 return r;
4144}
4145
4146/* node --- allocates a node with defined lnode and rnode. */
4147
4148NODE *
4149node(NODE *left, NODETYPE op, NODE *right)
4150{
4151 register NODE *r;
4152
4153 r = node_common(op);
4154 r->lnode = left;
4155 r->rnode = right;
4156 return r;
4157}
4158
4159/* snode --- allocate a node with defined subnode and builtin for builtin
4160 functions. Checks for arg. count and supplies defaults where
4161 possible. */
4162
4163static NODE *
4164snode(NODE *subn, NODETYPE op, int idx)
4165{
4166 register NODE *r;
4167 register NODE *n;
4168 int nexp = 0;
4169 int args_allowed;
4170
4171 r = node_common(op);
4172
4173 /* traverse expression list to see how many args. given */
4174 for (n = subn; n != NULL; n = n->rnode) {
4175 nexp++;
4176 if (nexp > 5)
4177 break;
4178 }
4179
4180 /* check against how many args. are allowed for this builtin */
4181 args_allowed = tokentab[idx].flags & ARGS;
4182 if (args_allowed && (args_allowed & A(nexp)) == 0)
4183 fatal(_("%d is invalid as number of arguments for %s"),
4184 nexp, tokentab[idx].operator);
4185
4186 r->builtin = tokentab[idx].ptr;
4187
4188 /* special case processing for a few builtins */
4189 if (nexp == 0 && r->builtin == do_length) {
4190 subn = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL),
4191 Node_expression_list,
4192 (NODE *) NULL);
4193 } else if (r->builtin == do_match) {
4194 static short warned = FALSE;
4195
4196 if (subn->rnode->lnode->type != Node_regex)
4197 subn->rnode->lnode = mk_rexp(subn->rnode->lnode);
4198
4199 if (subn->rnode->rnode != NULL) { /* 3rd argument there */
4200 if (do_lint && ! warned) {
4201 warned = TRUE;
4202 lintwarn(_("match: third argument is a gawk extension"));
4203 }
4204 if (do_traditional)
4205 fatal(_("match: third argument is a gawk extension"));
4206 }
4207 } else if (r->builtin == do_sub || r->builtin == do_gsub) {
4208 if (subn->lnode->type != Node_regex)
4209 subn->lnode = mk_rexp(subn->lnode);
4210 if (nexp == 2)
4211 append_right(subn, node(node(make_number(0.0),
4212 Node_field_spec,
4213 (NODE *) NULL),
4214 Node_expression_list,
4215 (NODE *) NULL));
4216 else if (subn->rnode->rnode->lnode->type == Node_val) {
4217 if (do_lint)
4218 lintwarn(_("%s: string literal as last arg of substitute has no effect"),
4219 (r->builtin == do_sub) ? "sub" : "gsub");
4220 } else if (! isassignable(subn->rnode->rnode->lnode)) {
4221 yyerror(_("%s third parameter is not a changeable object"),
4222 (r->builtin == do_sub) ? "sub" : "gsub");
4223 }
4224 } else if (r->builtin == do_gensub) {
4225 if (subn->lnode->type != Node_regex)
4226 subn->lnode = mk_rexp(subn->lnode);
4227 if (nexp == 3)
4228 append_right(subn, node(node(make_number(0.0),
4229 Node_field_spec,
4230 (NODE *) NULL),
4231 Node_expression_list,
4232 (NODE *) NULL));
4233 } else if (r->builtin == do_split) {
4234 if (nexp == 2)
4235 append_right(subn,
4236 node(FS_node, Node_expression_list, (NODE *) NULL));
4237 n = subn->rnode->rnode->lnode;
4238 if (n->type != Node_regex)
4239 subn->rnode->rnode->lnode = mk_rexp(n);
4240 if (nexp == 2)
4241 subn->rnode->rnode->lnode->re_flags |= FS_DFLT;
4242 } else if (r->builtin == do_close) {
4243 static short warned = FALSE;
4244
4245 if ( nexp == 2) {
4246 if (do_lint && nexp == 2 && ! warned) {
4247 warned = TRUE;
4248 lintwarn(_("close: second argument is a gawk extension"));
4249 }
4250 if (do_traditional)
4251 fatal(_("close: second argument is a gawk extension"));
4252 }
4253 } else if (do_intl /* --gen-po */
4254 && r->builtin == do_dcgettext /* dcgettext(...) */
4255 && subn->lnode->type == Node_val /* 1st arg is constant */
4256 && (subn->lnode->flags & STRCUR) != 0) { /* it's a string constant */
4257 /* ala xgettext, dcgettext("some string" ...) dumps the string */
4258 NODE *str = subn->lnode;
4259
4260 if ((str->flags & INTLSTR) != 0)
4261 warning(_("use of dcgettext(_\"...\") is incorrect: remove leading underscore"));
4262 /* don't dump it, the lexer already did */
4263 else
4264 dumpintlstr(str->stptr, str->stlen);
4265 } else if (do_intl /* --gen-po */
4266 && r->builtin == do_dcngettext /* dcngettext(...) */
4267 && subn->lnode->type == Node_val /* 1st arg is constant */
4268 && (subn->lnode->flags & STRCUR) != 0 /* it's a string constant */
4269 && subn->rnode->lnode->type == Node_val /* 2nd arg is constant too */
4270 && (subn->rnode->lnode->flags & STRCUR) != 0) { /* it's a string constant */
4271 /* ala xgettext, dcngettext("some string", "some plural" ...) dumps the string */
4272 NODE *str1 = subn->lnode;
4273 NODE *str2 = subn->rnode->lnode;
4274
4275 if (((str1->flags | str2->flags) & INTLSTR) != 0)
4276 warning(_("use of dcngettext(_\"...\") is incorrect: remove leading underscore"));
4277 else
4278 dumpintlstr2(str1->stptr, str1->stlen, str2->stptr, str2->stlen);
4279 }
4280
4281 r->subnode = subn;
4282 if (r->builtin == do_sprintf) {
4283 count_args(r);
4284 r->lnode->printf_count = r->printf_count; /* hack */
4285 }
4286 return r;
4287}
4288
4289/* make_for_loop --- build a for loop */
4290
4291static NODE *
4292make_for_loop(NODE *init, NODE *cond, NODE *incr)
4293{
4294 register FOR_LOOP_HEADER *r;
4295 NODE *n;
4296
4297 emalloc(r, FOR_LOOP_HEADER *, sizeof(FOR_LOOP_HEADER), "make_for_loop");
4298 getnode(n);
4299 n->type = Node_illegal;
4300 r->init = init;
4301 r->cond = cond;
4302 r->incr = incr;
4303 n->sub.nodep.r.hd = r;
4304 return n;
4305}
4306
4307/* dup_parms --- return TRUE if there are duplicate parameters */
4308
4309static int
4310dup_parms(NODE *func)
4311{
4312 register NODE *np;
4313 const char *fname, **names;
4314 int count, i, j, dups;
4315 NODE *params;
4316
4317 if (func == NULL) /* error earlier */
4318 return TRUE;
4319
4320 fname = func->param;
4321 count = func->param_cnt;
4322 params = func->rnode;
4323
4324 if (count == 0) /* no args, no problem */
4325 return FALSE;
4326
4327 if (params == NULL) /* error earlier */
4328 return TRUE;
4329
4330 emalloc(names, const char **, count * sizeof(char *), "dup_parms");
4331
4332 i = 0;
4333 for (np = params; np != NULL; np = np->rnode) {
4334 if (np->param == NULL) { /* error earlier, give up, go home */
4335 free(names);
4336 return TRUE;
4337 }
4338 names[i++] = np->param;
4339 }
4340
4341 dups = 0;
4342 for (i = 1; i < count; i++) {
4343 for (j = 0; j < i; j++) {
4344 if (strcmp(names[i], names[j]) == 0) {
4345 dups++;
4346 error(
4347 _("function `%s': parameter #%d, `%s', duplicates parameter #%d"),
4348 fname, i+1, names[j], j+1);
4349 }
4350 }
4351 }
4352
4353 free(names);
4354 return (dups > 0 ? TRUE : FALSE);
4355}
4356
4357/* parms_shadow --- check if parameters shadow globals */
4358
4359static int
4360parms_shadow(const char *fname, NODE *func)
4361{
4362 int count, i;
4363 int ret = FALSE;
4364
4365 if (fname == NULL || func == NULL) /* error earlier */
4366 return FALSE;
4367
4368 count = func->lnode->param_cnt;
4369
4370 if (count == 0) /* no args, no problem */
4371 return FALSE;
4372
4373 /*
4374 * Use warning() and not lintwarn() so that can warn
4375 * about all shadowed parameters.
4376 */
4377 for (i = 0; i < count; i++) {
4378 if (lookup(func->parmlist[i]) != NULL) {
4379 warning(
4380 _("function `%s': parameter `%s' shadows global variable"),
4381 fname, func->parmlist[i]);
4382 ret = TRUE;
4383 }
4384 }
4385
4386 return ret;
4387}
4388
4389/*
4390 * install:
4391 * Install a name in the symbol table, even if it is already there.
4392 * Caller must check against redefinition if that is desired.
4393 */
4394
4395NODE *
4396install(char *name, NODE *value)
4397{
4398 register NODE *hp;
4399 register size_t len;
4400 register int bucket;
4401
4402 var_count++;
4403 len = strlen(name);
4404 bucket = hash(name, len, (unsigned long) HASHSIZE);
4405 getnode(hp);
4406 hp->type = Node_hashnode;
4407 hp->hnext = variables[bucket];
4408 variables[bucket] = hp;
4409 hp->hlength = len;
4410 hp->hvalue = value;
4411 hp->hname = name;
4412 hp->hvalue->vname = name;
4413 return hp->hvalue;
4414}
4415
4416/* lookup --- find the most recent hash node for name installed by install */
4417
4418NODE *
4419lookup(const char *name)
4420{
4421 register NODE *bucket;
4422 register size_t len;
4423
4424 len = strlen(name);
4425 for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE)];
4426 bucket != NULL; bucket = bucket->hnext)
4427 if (bucket->hlength == len && STREQN(bucket->hname, name, len))
4428 return bucket->hvalue;
4429
4430 return NULL;
4431}
4432
4433/* var_comp --- compare two variable names */
4434
4435static int
4436var_comp(const void *v1, const void *v2)
4437{
4438 const NODE *const *npp1, *const *npp2;
4439 const NODE *n1, *n2;
4440 int minlen;
4441
4442 npp1 = (const NODE *const *) v1;
4443 npp2 = (const NODE *const *) v2;
4444 n1 = *npp1;
4445 n2 = *npp2;
4446
4447 if (n1->hlength > n2->hlength)
4448 minlen = n1->hlength;
4449 else
4450 minlen = n2->hlength;
4451
4452 return strncmp(n1->hname, n2->hname, minlen);
4453}
4454
4455/* valinfo --- dump var info */
4456
4457static void
4458valinfo(NODE *n, FILE *fp)
4459{
4460 if (n->flags & STRING) {
4461 fprintf(fp, "string (");
4462 pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE);
4463 fprintf(fp, ")\n");
4464 } else if (n->flags & NUMBER)
4465 fprintf(fp, "number (%.17g)\n", n->numbr);
4466 else if (n->flags & STRCUR) {
4467 fprintf(fp, "string value (");
4468 pp_string_fp(fp, n->stptr, n->stlen, '"', FALSE);
4469 fprintf(fp, ")\n");
4470 } else if (n->flags & NUMCUR)
4471 fprintf(fp, "number value (%.17g)\n", n->numbr);
4472 else
4473 fprintf(fp, "?? flags %s\n", flags2str(n->flags));
4474}
4475
4476
4477/* dump_vars --- dump the symbol table */
4478
4479void
4480dump_vars(const char *fname)
4481{
4482 int i, j;
4483 NODE **table;
4484 NODE *p;
4485 FILE *fp;
4486
4487 emalloc(table, NODE **, var_count * sizeof(NODE *), "dump_vars");
4488
4489 if (fname == NULL)
4490 fp = stderr;
4491 else if ((fp = fopen(fname, "w")) == NULL) {
4492 warning(_("could not open `%s' for writing (%s)"), fname, strerror(errno));
4493 warning(_("sending profile to standard error"));
4494 fp = stderr;
4495 }
4496
4497 for (i = j = 0; i < HASHSIZE; i++)
4498 for (p = variables[i]; p != NULL; p = p->hnext)
4499 table[j++] = p;
4500
4501 assert(j == var_count);
4502
4503 /* Shazzam! */
4504 qsort(table, j, sizeof(NODE *), var_comp);
4505
4506 for (i = 0; i < j; i++) {
4507 p = table[i];
4508 if (p->hvalue->type == Node_func)
4509 continue;
4510 fprintf(fp, "%.*s: ", (int) p->hlength, p->hname);
4511 if (p->hvalue->type == Node_var_array)
4512 fprintf(fp, "array, %ld elements\n", p->hvalue->table_size);
4513 else if (p->hvalue->type == Node_var_new)
4514 fprintf(fp, "unused variable\n");
4515 else if (p->hvalue->type == Node_var)
4516 valinfo(p->hvalue->var_value, fp);
4517 else {
4518 NODE **lhs = get_lhs(p->hvalue, NULL, FALSE);
4519
4520 valinfo(*lhs, fp);
4521 }
4522 }
4523
4524 if (fp != stderr && fclose(fp) != 0)
4525 warning(_("%s: close failed (%s)"), fname, strerror(errno));
4526
4527 free(table);
4528}
4529
4530/* release_all_vars --- free all variable memory */
4531
4532void
4533release_all_vars()
4534{
4535 int i;
4536 NODE *p, *next;
4537
4538 for (i = 0; i < HASHSIZE; i++)
4539 for (p = variables[i]; p != NULL; p = next) {
4540 next = p->hnext;
4541
4542 if (p->hvalue->type == Node_func)
4543 continue;
4544 else if (p->hvalue->type == Node_var_array)
4545 assoc_clear(p->hvalue);
4546 else if (p->hvalue->type != Node_var_new) {
4547 NODE **lhs = get_lhs(p->hvalue, NULL, FALSE);
4548
4549 unref(*lhs);
4550 }
4551 unref(p);
4552 }
4553}
4554
4555/* finfo --- for use in comparison and sorting of function names */
4556
4557struct finfo {
4558 const char *name;
4559 size_t nlen;
4560 NODE *func;
4561};
4562
4563/* fcompare --- comparison function for qsort */
4564
4565static int
4566fcompare(const void *p1, const void *p2)
4567{
4568 const struct finfo *f1, *f2;
4569 int minlen;
4570
4571 f1 = (const struct finfo *) p1;
4572 f2 = (const struct finfo *) p2;
4573
4574 if (f1->nlen > f2->nlen)
4575 minlen = f2->nlen;
4576 else
4577 minlen = f1->nlen;
4578
4579 return strncmp(f1->name, f2->name, minlen);
4580}
4581
4582/* dump_funcs --- print all functions */
4583
4584void
4585dump_funcs()
4586{
4587 int i, j;
4588 NODE *p;
4589 struct finfo *tab = NULL;
4590
4591 /*
4592 * Walk through symbol table countng functions.
4593 * Could be more than func_count if there are
4594 * extension functions.
4595 */
4596 for (i = j = 0; i < HASHSIZE; i++) {
4597 for (p = variables[i]; p != NULL; p = p->hnext) {
4598 if (p->hvalue->type == Node_func) {
4599 j++;
4600 }
4601 }
4602 }
4603
4604 if (j == 0)
4605 return;
4606
4607 emalloc(tab, struct finfo *, j * sizeof(struct finfo), "dump_funcs");
4608
4609 /* now walk again, copying info */
4610 for (i = j = 0; i < HASHSIZE; i++) {
4611 for (p = variables[i]; p != NULL; p = p->hnext) {
4612 if (p->hvalue->type == Node_func) {
4613 tab[j].name = p->hname;
4614 tab[j].nlen = p->hlength;
4615 tab[j].func = p->hvalue;
4616 j++;
4617 }
4618 }
4619 }
4620
4621
4622 /* Shazzam! */
4623 qsort(tab, j, sizeof(struct finfo), fcompare);
4624
4625 for (i = 0; i < j; i++)
4626 pp_func(tab[i].name, tab[i].nlen, tab[i].func);
4627
4628 free(tab);
4629}
4630
4631/* shadow_funcs --- check all functions for parameters that shadow globals */
4632
4633void
4634shadow_funcs()
4635{
4636 int i, j;
4637 NODE *p;
4638 struct finfo *tab;
4639 static int calls = 0;
4640 int shadow = FALSE;
4641
4642 if (func_count == 0)
4643 return;
4644
4645 if (calls++ != 0)
4646 fatal(_("shadow_funcs() called twice!"));
4647
4648 emalloc(tab, struct finfo *, func_count * sizeof(struct finfo), "shadow_funcs");
4649
4650 for (i = j = 0; i < HASHSIZE; i++) {
4651 for (p = variables[i]; p != NULL; p = p->hnext) {
4652 if (p->hvalue->type == Node_func) {
4653 tab[j].name = p->hname;
4654 tab[j].nlen = p->hlength;
4655 tab[j].func = p->hvalue;
4656 j++;
4657 }
4658 }
4659 }
4660
4661 assert(j == func_count);
4662
4663 /* Shazzam! */
4664 qsort(tab, func_count, sizeof(struct finfo), fcompare);
4665
4666 for (i = 0; i < j; i++)
4667 shadow |= parms_shadow(tab[i].name, tab[i].func);
4668
4669 free(tab);
4670
4671 /* End with fatal if the user requested it. */
4672 if (shadow && lintfunc != warning)
4673 lintwarn(_("there were shadowed variables."));
4674}
4675
4676/*
4677 * append_right:
4678 * Add new to the rightmost branch of LIST. This uses n^2 time, so we make
4679 * a simple attempt at optimizing it.
4680 */
4681
4682static NODE *
4683append_right(NODE *list, NODE *new)
4684{
4685 register NODE *oldlist;
4686 static NODE *savefront = NULL, *savetail = NULL;
4687
4688 if (list == NULL || new == NULL)
4689 return list;
4690
4691 oldlist = list;
4692 if (savefront == oldlist)
4693 list = savetail; /* Be careful: maybe list->rnode != NULL */
4694 else
4695 savefront = oldlist;
4696
4697 while (list->rnode != NULL)
4698 list = list->rnode;
4699 savetail = list->rnode = new;
4700 return oldlist;
4701}
4702
4703/*
4704 * append_pattern:
4705 * A wrapper around append_right, used for rule lists.
4706 */
4707static inline NODE *
4708append_pattern(NODE **list, NODE *patt)
4709{
4710 NODE *n = node(patt, Node_rule_node, (NODE *) NULL);
4711
4712 if (*list == NULL)
4713 *list = n;
4714 else {
4715 NODE *n1 = node(n, Node_rule_list, (NODE *) NULL);
4716 if ((*list)->type != Node_rule_list)
4717 *list = node(*list, Node_rule_list, n1);
4718 else
4719 (void) append_right(*list, n1);
4720 }
4721 return n;
4722}
4723
4724/*
4725 * func_install:
4726 * check if name is already installed; if so, it had better have Null value,
4727 * in which case def is added as the value. Otherwise, install name with def
4728 * as value.
4729 *
4730 * Extra work, build up and save a list of the parameter names in a table
4731 * and hang it off params->parmlist. This is used to set the `vname' field
4732 * of each function parameter during a function call. See eval.c.
4733 */
4734
4735static void
4736func_install(NODE *params, NODE *def)
4737{
4738 NODE *r, *n, *thisfunc;
4739 char **pnames, *names, *sp;
4740 size_t pcount = 0, space = 0;
4741 int i;
4742
4743 /* check for function foo(foo) { ... }. bleah. */
4744 for (n = params->rnode; n != NULL; n = n->rnode) {
4745 if (strcmp(n->param, params->param) == 0)
4746 fatal(_("function `%s': can't use function name as parameter name"),
4747 params->param);
4748 }
4749
4750 thisfunc = NULL; /* turn off warnings */
4751
4752 /* symbol table managment */
4753 pop_var(params, FALSE);
4754 r = lookup(params->param);
4755 if (r != NULL) {
4756 fatal(_("function name `%s' previously defined"), params->param);
4757 } else if (params->param == builtin_func) /* not a valid function name */
4758 goto remove_params;
4759
4760 /* install the function */
4761 thisfunc = node(params, Node_func, def);
4762 (void) install(params->param, thisfunc);
4763
4764 /* figure out amount of space to allocate for variable names */
4765 for (n = params->rnode; n != NULL; n = n->rnode) {
4766 pcount++;
4767 space += strlen(n->param) + 1;
4768 }
4769
4770 /* allocate it and fill it in */
4771 if (pcount != 0) {
4772 emalloc(names, char *, space, "func_install");
4773 emalloc(pnames, char **, pcount * sizeof(char *), "func_install");
4774 sp = names;
4775 for (i = 0, n = params->rnode; i < pcount; i++, n = n->rnode) {
4776 pnames[i] = sp;
4777 strcpy(sp, n->param);
4778 sp += strlen(n->param) + 1;
4779 }
4780 thisfunc->parmlist = pnames;
4781 } else {
4782 thisfunc->parmlist = NULL;
4783 }
4784
4785 /* update lint table info */
4786 func_use(params->param, FUNC_DEFINE);
4787
4788 func_count++; /* used by profiling / pretty printer */
4789
4790remove_params:
4791 /* remove params from symbol table */
4792 pop_params(params->rnode);
4793}
4794
4795/* pop_var --- remove a variable from the symbol table */
4796
4797static void
4798pop_var(NODE *np, int freeit)
4799{
4800 register NODE *bucket, **save;
4801 register size_t len;
4802 char *name;
4803
4804 name = np->param;
4805 len = strlen(name);
4806 save = &(variables[hash(name, len, (unsigned long) HASHSIZE)]);
4807 for (bucket = *save; bucket != NULL; bucket = bucket->hnext) {
4808 if (len == bucket->hlength && STREQN(bucket->hname, name, len)) {
4809 var_count--;
4810 *save = bucket->hnext;
4811 freenode(bucket);
4812 if (freeit)
4813 free(np->param);
4814 return;
4815 }
4816 save = &(bucket->hnext);
4817 }
4818}
4819
4820/* pop_params --- remove list of function parameters from symbol table */
4821
4822/*
4823 * pop parameters out of the symbol table. do this in reverse order to
4824 * avoid reading freed memory if there were duplicated parameters.
4825 */
4826static void
4827pop_params(NODE *params)
4828{
4829 if (params == NULL)
4830 return;
4831 pop_params(params->rnode);
4832 pop_var(params, TRUE);
4833}
4834
4835/* make_param --- make NAME into a function parameter */
4836
4837static NODE *
4838make_param(char *name)
4839{
4840 NODE *r;
4841
4842 getnode(r);
4843 r->type = Node_param_list;
4844 r->rnode = NULL;
4845 r->param = name;
4846 r->param_cnt = param_counter++;
4847 return (install(name, r));
4848}
4849
4850static struct fdesc {
4851 char *name;
4852 short used;
4853 short defined;
4854 struct fdesc *next;
4855} *ftable[HASHSIZE];
4856
4857/* func_use --- track uses and definitions of functions */
4858
4859static void
4860func_use(const char *name, enum defref how)
4861{
4862 struct fdesc *fp;
4863 int len;
4864 int ind;
4865
4866 len = strlen(name);
4867 ind = hash(name, len, HASHSIZE);
4868
4869 for (fp = ftable[ind]; fp != NULL; fp = fp->next) {
4870 if (strcmp(fp->name, name) == 0) {
4871 if (how == FUNC_DEFINE)
4872 fp->defined++;
4873 else
4874 fp->used++;
4875 return;
4876 }
4877 }
4878
4879 /* not in the table, fall through to allocate a new one */
4880
4881 emalloc(fp, struct fdesc *, sizeof(struct fdesc), "func_use");
4882 memset(fp, '\0', sizeof(struct fdesc));
4883 emalloc(fp->name, char *, len + 1, "func_use");
4884 strcpy(fp->name, name);
4885 if (how == FUNC_DEFINE)
4886 fp->defined++;
4887 else
4888 fp->used++;
4889 fp->next = ftable[ind];
4890 ftable[ind] = fp;
4891}
4892
4893/* check_funcs --- verify functions that are called but not defined */
4894
4895static void
4896check_funcs()
4897{
4898 struct fdesc *fp, *next;
4899 int i;
4900
4901 for (i = 0; i < HASHSIZE; i++) {
4902 for (fp = ftable[i]; fp != NULL; fp = fp->next) {
4903#ifdef REALLYMEAN
4904 /* making this the default breaks old code. sigh. */
4905 if (fp->defined == 0) {
4906 error(
4907 _("function `%s' called but never defined"), fp->name);
4908 errcount++;
4909 }
4910#else
4911 if (do_lint && fp->defined == 0)
4912 lintwarn(
4913 _("function `%s' called but never defined"), fp->name);
4914#endif
4915 if (do_lint && fp->used == 0) {
4916 lintwarn(_("function `%s' defined but never called"),
4917 fp->name);
4918 }
4919 }
4920 }
4921
4922 /* now let's free all the memory */
4923 for (i = 0; i < HASHSIZE; i++) {
4924 for (fp = ftable[i]; fp != NULL; fp = next) {
4925 next = fp->next;
4926 free(fp->name);
4927 free(fp);
4928 }
4929 }
4930}
4931
4932/* param_sanity --- look for parameters that are regexp constants */
4933
4934static void
4935param_sanity(NODE *arglist)
4936{
4937 NODE *argp, *arg;
4938 int i;
4939
4940 for (i = 1, argp = arglist; argp != NULL; argp = argp->rnode, i++) {
4941 arg = argp->lnode;
4942 if (arg->type == Node_regex)
4943 warning(_("regexp constant for parameter #%d yields boolean value"), i);
4944 }
4945}
4946
4947/* deferred varibles --- those that are only defined if needed. */
4948
4949/*
4950 * Is there any reason to use a hash table for deferred variables? At the
4951 * moment, there are only 1 to 3 such variables, so it may not be worth
4952 * the overhead. If more modules start using this facility, it should
4953 * probably be converted into a hash table.
4954 */
4955
4956static struct deferred_variable {
4957 NODE *(*load_func)(void);
4958 struct deferred_variable *next;
4959 char name[1]; /* variable-length array */
4960} *deferred_variables;
4961
4962/* register_deferred_variable --- add a var name and loading function to the list */
4963
4964void
4965register_deferred_variable(const char *name, NODE *(*load_func)(void))
4966{
4967 struct deferred_variable *dv;
4968 size_t sl = strlen(name);
4969
4970 emalloc(dv, struct deferred_variable *, sizeof(*dv)+sl,
4971 "register_deferred_variable");
4972 dv->load_func = load_func;
4973 dv->next = deferred_variables;
4974 memcpy(dv->name, name, sl+1);
4975 deferred_variables = dv;
4976}
4977
4978/* variable --- make sure NAME is in the symbol table */
4979
4980NODE *
4981variable(char *name, int can_free, NODETYPE type)
4982{
4983 register NODE *r;
4984
4985 if ((r = lookup(name)) != NULL) {
4986 if (r->type == Node_func)
4987 fatal(_("function `%s' called with space between name and `(',\nor used as a variable or an array"),
4988 r->vname);
4989
4990 } else {
4991 /* not found */
4992 struct deferred_variable *dv;
4993
4994 for (dv = deferred_variables; TRUE; dv = dv->next) {
4995 if (dv == NULL) {
4996 /*
4997 * This is the only case in which we may not
4998 * free the string.
4999 */
5000 NODE *n;
5001
5002 if (type == Node_var_array)
5003 n = node(NULL, type, NULL);
5004 else
5005 n = node(Nnull_string, type, NULL);
5006
5007 return install(name, n);
5008 }
5009 if (STREQ(name, dv->name)) {
5010 r = (*dv->load_func)();
5011 break;
5012 }
5013 }
5014 }
5015 if (can_free)
5016 free(name);
5017 return r;
5018}
5019
5020/* mk_rexp --- make a regular expression constant */
5021
5022static NODE *
5023mk_rexp(NODE *exp)
5024{
5025 NODE *n;
5026
5027 if (exp->type == Node_regex)
5028 return exp;
5029
5030 getnode(n);
5031 n->type = Node_dynregex;
5032 n->re_exp = exp;
5033 n->re_text = NULL;
5034 n->re_reg = NULL;
5035 n->re_flags = 0;
5036 n->re_cnt = 1;
5037 return n;
5038}
5039
5040/* isnoeffect --- when used as a statement, has no side effects */
5041
5042/*
5043 * To be completely general, we should recursively walk the parse
5044 * tree, to make sure that all the subexpressions also have no effect.
5045 * Instead, we just weaken the actual warning that's printed, up above
5046 * in the grammar.
5047 */
5048
5049static int
5050isnoeffect(NODETYPE type)
5051{
5052 switch (type) {
5053 case Node_times:
5054 case Node_quotient:
5055 case Node_mod:
5056 case Node_plus:
5057 case Node_minus:
5058 case Node_subscript:
5059 case Node_concat:
5060 case Node_exp:
5061 case Node_unary_minus:
5062 case Node_field_spec:
5063 case Node_and:
5064 case Node_or:
5065 case Node_equal:
5066 case Node_notequal:
5067 case Node_less:
5068 case Node_greater:
5069 case Node_leq:
5070 case Node_geq:
5071 case Node_match:
5072 case Node_nomatch:
5073 case Node_not:
5074 case Node_val:
5075 case Node_in_array:
5076 case Node_NF:
5077 case Node_NR:
5078 case Node_FNR:
5079 case Node_FS:
5080 case Node_RS:
5081 case Node_FIELDWIDTHS:
5082 case Node_IGNORECASE:
5083 case Node_OFS:
5084 case Node_ORS:
5085 case Node_OFMT:
5086 case Node_CONVFMT:
5087 case Node_BINMODE:
5088 case Node_LINT:
5089 case Node_SUBSEP:
5090 case Node_TEXTDOMAIN:
5091 return TRUE;
5092 default:
5093 break; /* keeps gcc -Wall happy */
5094 }
5095
5096 return FALSE;
5097}
5098
5099/* isassignable --- can this node be assigned to? */
5100
5101static int
5102isassignable(register NODE *n)
5103{
5104 switch (n->type) {
5105 case Node_var_new:
5106 case Node_var:
5107 case Node_FIELDWIDTHS:
5108 case Node_RS:
5109 case Node_FS:
5110 case Node_FNR:
5111 case Node_NR:
5112 case Node_NF:
5113 case Node_IGNORECASE:
5114 case Node_OFMT:
5115 case Node_CONVFMT:
5116 case Node_ORS:
5117 case Node_OFS:
5118 case Node_LINT:
5119 case Node_BINMODE:
5120 case Node_SUBSEP:
5121 case Node_TEXTDOMAIN:
5122 case Node_field_spec:
5123 case Node_subscript:
5124 return TRUE;
5125 case Node_param_list:
5126 return ((n->flags & FUNC) == 0); /* ok if not func name */
5127 default:
5128 break; /* keeps gcc -Wall happy */
5129 }
5130 return FALSE;
5131}
5132
5133/* stopme --- for debugging */
5134
5135NODE *
5136stopme(NODE *tree ATTRIBUTE_UNUSED)
5137{
5138 return (NODE *) 0;
5139}
5140
5141/* dumpintlstr --- write out an initial .po file entry for the string */
5142
5143static void
5144dumpintlstr(const char *str, size_t len)
5145{
5146 char *cp;
5147
5148 /* See the GNU gettext distribution for details on the file format */
5149
5150 if (source != NULL) {
5151 /* ala the gettext sources, remove leading `./'s */
5152 for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
5153 continue;
5154 printf("#: %s:%d\n", cp, sourceline);
5155 }
5156
5157 printf("msgid ");
5158 pp_string_fp(stdout, str, len, '"', TRUE);
5159 putchar('\n');
5160 printf("msgstr \"\"\n\n");
5161 fflush(stdout);
5162}
5163
5164/* dumpintlstr2 --- write out an initial .po file entry for the string and its plural */
5165
5166static void
5167dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2)
5168{
5169 char *cp;
5170
5171 /* See the GNU gettext distribution for details on the file format */
5172
5173 if (source != NULL) {
5174 /* ala the gettext sources, remove leading `./'s */
5175 for (cp = source; cp[0] == '.' && cp[1] == '/'; cp += 2)
5176 continue;
5177 printf("#: %s:%d\n", cp, sourceline);
5178 }
5179
5180 printf("msgid ");
5181 pp_string_fp(stdout, str1, len1, '"', TRUE);
5182 putchar('\n');
5183 printf("msgid_plural ");
5184 pp_string_fp(stdout, str2, len2, '"', TRUE);
5185 putchar('\n');
5186 printf("msgstr[0] \"\"\nmsgstr[1] \"\"\n\n");
5187 fflush(stdout);
5188}
5189
5190/* count_args --- count the number of printf arguments */
5191
5192static void
5193count_args(NODE *tree)
5194{
5195 size_t count = 0;
5196 NODE *save_tree;
5197
5198 assert(tree->type == Node_K_printf
5199 || (tree->type == Node_builtin && tree->builtin == do_sprintf));
5200 save_tree = tree;
5201
5202 tree = tree->lnode; /* printf format string */
5203
5204 for (count = 0; tree != NULL; tree = tree->rnode)
5205 count++;
5206
5207 save_tree->printf_count = count;
5208}
5209
5210/* isarray --- can this type be subscripted? */
5211
5212static int
5213isarray(NODE *n)
5214{
5215 switch (n->type) {
5216 case Node_var_new:
5217 case Node_var_array:
5218 return TRUE;
5219 case Node_param_list:
5220 return (n->flags & FUNC) == 0;
5221 case Node_array_ref:
5222 cant_happen();
5223 break;
5224 default:
5225 break; /* keeps gcc -Wall happy */
5226 }
5227
5228 return FALSE;
5229}
5230
5231/* See if name is a special token. */
5232
5233int
5234check_special(const char *name)
5235{
5236 int low, high, mid;
5237 int i;
5238
5239 low = 0;
5240 high = (sizeof(tokentab) / sizeof(tokentab[0])) - 1;
5241 while (low <= high) {
5242 mid = (low + high) / 2;
5243 i = *name - tokentab[mid].operator[0];
5244 if (i == 0)
5245 i = strcmp(name, tokentab[mid].operator);
5246
5247 if (i < 0) /* token < mid */
5248 high = mid - 1;
5249 else if (i > 0) /* token > mid */
5250 low = mid + 1;
5251 else
5252 return mid;
5253 }
5254 return -1;
5255}
5256
5257
Note: See TracBrowser for help on using the repository browser.