diff options
Diffstat (limited to 'contrib/awk/awktab.c')
-rw-r--r-- | contrib/awk/awktab.c | 3983 |
1 files changed, 3983 insertions, 0 deletions
diff --git a/contrib/awk/awktab.c b/contrib/awk/awktab.c new file mode 100644 index 0000000..23aa4fb --- /dev/null +++ b/contrib/awk/awktab.c @@ -0,0 +1,3983 @@ + +/* A Bison parser, made from ./awk.y + by GNU Bison version 1.25 + */ + +#define YYBISON 1 /* Identify Bison output. */ + +#define FUNC_CALL 258 +#define NAME 259 +#define REGEXP 260 +#define ERROR 261 +#define YNUMBER 262 +#define YSTRING 263 +#define RELOP 264 +#define APPEND_OP 265 +#define ASSIGNOP 266 +#define MATCHOP 267 +#define NEWLINE 268 +#define CONCAT_OP 269 +#define LEX_BEGIN 270 +#define LEX_END 271 +#define LEX_IF 272 +#define LEX_ELSE 273 +#define LEX_RETURN 274 +#define LEX_DELETE 275 +#define LEX_WHILE 276 +#define LEX_DO 277 +#define LEX_FOR 278 +#define LEX_BREAK 279 +#define LEX_CONTINUE 280 +#define LEX_PRINT 281 +#define LEX_PRINTF 282 +#define LEX_NEXT 283 +#define LEX_EXIT 284 +#define LEX_FUNCTION 285 +#define LEX_GETLINE 286 +#define LEX_NEXTFILE 287 +#define LEX_IN 288 +#define LEX_AND 289 +#define LEX_OR 290 +#define INCREMENT 291 +#define DECREMENT 292 +#define LEX_BUILTIN 293 +#define LEX_LENGTH 294 +#define UNARY 295 + +#line 26 "./awk.y" + +#ifdef DEBUG +#define YYDEBUG 12 +#endif + +#include "awk.h" + +#define CAN_FREE TRUE +#define DONT_FREE FALSE + +#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ +static void yyerror(const char *m, ...) ; +#else +static void yyerror(); /* va_alist */ +#endif +static char *get_src_buf P((void)); +static int yylex P((void)); +static NODE *node_common P((NODETYPE op)); +static NODE *snode P((NODE *subn, NODETYPE op, int sindex)); +static NODE *mkrangenode P((NODE *cpair)); +static NODE *make_for_loop P((NODE *init, NODE *cond, NODE *incr)); +static NODE *append_right P((NODE *list, NODE *new)); +static void func_install P((NODE *params, NODE *def)); +static void pop_var P((NODE *np, int freeit)); +static void pop_params P((NODE *params)); +static NODE *make_param P((char *name)); +static NODE *mk_rexp P((NODE *exp)); +static int dup_parms P((NODE *func)); +static void param_sanity P((NODE *arglist)); +static int isnoeffect P((NODETYPE t)); +static int isassignable P((NODE *n)); + +enum defref { FUNC_DEFINE, FUNC_USE }; +static void func_use P((char *name, enum defref how)); +static void check_funcs P((void)); + +static int want_assign; /* lexical scanning kludge */ +static int want_regexp; /* lexical scanning kludge */ +static int can_return; /* lexical scanning kludge */ +static int io_allowed = TRUE; /* lexical scanning kludge */ +static char *lexptr; /* pointer to next char during parsing */ +static char *lexend; +static char *lexptr_begin; /* keep track of where we were for error msgs */ +static char *lexeme; /* beginning of lexeme for debugging */ +static char *thisline = NULL; +#define YYDEBUG_LEXER_TEXT (lexeme) +static int param_counter; +static char *tokstart = NULL; +static char *tok = NULL; +static char *tokend; + +#define HASHSIZE 1021 /* this constant only used here */ +NODE *variables[HASHSIZE]; + +extern char *source; +extern int sourceline; +extern struct src *srcfiles; +extern int numfiles; +extern int errcount; +extern NODE *begin_block; +extern NODE *end_block; + +#line 89 "./awk.y" +typedef union { + long lval; + AWKNUM fval; + NODE *nodeval; + NODETYPE nodetypeval; + char *sval; + NODE *(*ptrval)(); +} YYSTYPE; +#include <stdio.h> + +#ifndef __cplusplus +#ifndef __STDC__ +#define const +#endif +#endif + + + +#define YYFINAL 312 +#define YYFLAG -32768 +#define YYNTBASE 62 + +#define YYTRANSLATE(x) ((unsigned)(x) <= 295 ? yytranslate[x] : 107) + +static const char yytranslate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 51, 2, 2, 54, 50, 2, 2, 55, + 56, 48, 46, 42, 47, 2, 49, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 41, 61, 43, + 2, 44, 40, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 57, 2, 58, 53, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 59, 45, 60, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 52 +}; + +#if YYDEBUG != 0 +static const short yyprhs[] = { 0, + 0, 4, 6, 9, 11, 14, 15, 16, 20, 21, + 25, 28, 31, 34, 36, 39, 42, 44, 46, 48, + 50, 52, 53, 61, 66, 71, 73, 77, 78, 83, + 89, 94, 96, 99, 101, 104, 106, 109, 112, 115, + 119, 121, 128, 137, 146, 157, 167, 170, 173, 180, + 185, 189, 192, 196, 197, 202, 209, 213, 216, 218, + 220, 227, 237, 239, 242, 243, 245, 246, 249, 250, + 253, 256, 259, 260, 262, 264, 268, 270, 273, 277, + 278, 280, 281, 283, 285, 289, 291, 294, 298, 302, + 303, 305, 307, 311, 313, 316, 320, 324, 325, 330, + 336, 341, 345, 349, 353, 357, 359, 362, 366, 370, + 374, 378, 384, 386, 389, 390, 395, 399, 403, 407, + 409, 412, 416, 420, 424, 430, 432, 435, 437, 441, + 445, 449, 453, 457, 461, 464, 467, 470, 474, 479, + 484, 486, 491, 493, 496, 499, 501, 503, 506, 509, + 510, 512, 514, 519, 522, 525, 528, 530, 531, 533, + 535 +}; + +static const short yyrhs[] = { 83, + 63, 83, 0, 64, 0, 63, 64, 0, 1, 0, + 63, 1, 0, 0, 0, 15, 65, 75, 0, 0, + 16, 66, 75, 0, 15, 77, 0, 16, 77, 0, + 72, 75, 0, 75, 0, 72, 77, 0, 69, 71, + 0, 4, 0, 3, 0, 68, 0, 38, 0, 39, + 0, 0, 30, 70, 67, 55, 86, 103, 83, 0, + 101, 76, 102, 104, 0, 101, 102, 104, 83, 0, + 93, 0, 93, 42, 93, 0, 0, 49, 74, 5, + 49, 0, 101, 76, 102, 104, 83, 0, 101, 102, + 104, 83, 0, 78, 0, 76, 78, 0, 1, 0, + 76, 1, 0, 82, 0, 105, 83, 0, 105, 83, + 0, 101, 102, 0, 101, 76, 102, 0, 81, 0, + 21, 55, 93, 103, 83, 78, 0, 22, 83, 78, + 21, 55, 93, 103, 83, 0, 23, 55, 4, 33, + 4, 103, 83, 78, 0, 23, 55, 88, 105, 93, + 105, 88, 103, 83, 78, 0, 23, 55, 88, 105, + 105, 88, 103, 83, 78, 0, 24, 77, 0, 25, + 77, 0, 80, 55, 92, 103, 85, 77, 0, 80, + 89, 85, 77, 0, 28, 88, 77, 0, 32, 77, + 0, 29, 88, 77, 0, 0, 19, 79, 88, 77, + 0, 20, 4, 57, 92, 58, 77, 0, 20, 4, + 77, 0, 93, 77, 0, 26, 0, 27, 0, 17, + 55, 93, 103, 83, 78, 0, 17, 55, 93, 103, + 83, 78, 18, 83, 78, 0, 13, 0, 82, 13, + 0, 0, 82, 0, 0, 43, 97, 0, 0, 44, + 93, 0, 10, 93, 0, 45, 93, 0, 0, 87, + 0, 4, 0, 87, 106, 4, 0, 1, 0, 87, + 1, 0, 87, 106, 1, 0, 0, 93, 0, 0, + 90, 0, 95, 0, 90, 106, 95, 0, 1, 0, + 90, 1, 0, 90, 1, 95, 0, 90, 106, 1, + 0, 0, 92, 0, 93, 0, 92, 106, 93, 0, + 1, 0, 92, 1, 0, 92, 1, 93, 0, 92, + 106, 1, 0, 0, 100, 11, 94, 93, 0, 55, + 92, 103, 33, 4, 0, 93, 45, 31, 99, 0, + 31, 99, 84, 0, 93, 34, 93, 0, 93, 35, + 93, 0, 93, 12, 93, 0, 73, 0, 51, 73, + 0, 93, 33, 4, 0, 93, 9, 93, 0, 93, + 43, 93, 0, 93, 44, 93, 0, 93, 40, 93, + 41, 93, 0, 97, 0, 93, 97, 0, 0, 100, + 11, 96, 95, 0, 95, 34, 95, 0, 95, 35, + 95, 0, 31, 99, 84, 0, 73, 0, 51, 73, + 0, 95, 12, 95, 0, 95, 33, 4, 0, 95, + 9, 95, 0, 95, 40, 95, 41, 95, 0, 97, + 0, 95, 97, 0, 98, 0, 97, 53, 97, 0, + 97, 48, 97, 0, 97, 49, 97, 0, 97, 50, + 97, 0, 97, 46, 97, 0, 97, 47, 97, 0, + 100, 36, 0, 100, 37, 0, 51, 97, 0, 55, + 93, 103, 0, 38, 55, 91, 103, 0, 39, 55, + 91, 103, 0, 39, 0, 3, 55, 91, 103, 0, + 100, 0, 36, 100, 0, 37, 100, 0, 7, 0, + 8, 0, 47, 97, 0, 46, 97, 0, 0, 100, + 0, 4, 0, 4, 57, 92, 58, 0, 54, 98, + 0, 59, 83, 0, 60, 83, 0, 56, 0, 0, + 105, 0, 61, 0, 42, 83, 0 +}; + +#endif + +#if YYDEBUG != 0 +static const short yyrline[] = { 0, + 150, 158, 166, 182, 183, 184, 188, 190, 204, 206, + 220, 226, 232, 234, 236, 249, 258, 260, 262, 272, + 273, 277, 281, 296, 301, 310, 312, 321, 323, 341, + 343, 348, 354, 362, 364, 369, 370, 374, 376, 378, + 380, 382, 384, 386, 413, 417, 422, 425, 428, 430, + 450, 489, 508, 510, 515, 517, 519, 533, 538, 540, + 545, 550, 557, 559, 563, 564, 568, 570, 575, 577, + 579, 581, 586, 588, 593, 595, 597, 599, 601, 607, + 609, 614, 616, 621, 623, 629, 631, 633, 635, 640, + 642, 647, 649, 655, 657, 659, 661, 666, 669, 674, + 676, 681, 687, 689, 691, 697, 707, 715, 717, 723, + 725, 727, 729, 731, 736, 739, 740, 742, 744, 750, + 752, 754, 756, 758, 760, 762, 764, 769, 771, 773, + 775, 777, 779, 781, 783, 785, 790, 792, 794, 797, + 799, 807, 814, 815, 817, 819, 821, 824, 832, 843, + 845, 850, 852, 862, 867, 871, 875, 879, 880, 884, + 887 +}; +#endif + + +#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) + +static const char * const yytname[] = { "$","error","$undefined.","FUNC_CALL", +"NAME","REGEXP","ERROR","YNUMBER","YSTRING","RELOP","APPEND_OP","ASSIGNOP","MATCHOP", +"NEWLINE","CONCAT_OP","LEX_BEGIN","LEX_END","LEX_IF","LEX_ELSE","LEX_RETURN", +"LEX_DELETE","LEX_WHILE","LEX_DO","LEX_FOR","LEX_BREAK","LEX_CONTINUE","LEX_PRINT", +"LEX_PRINTF","LEX_NEXT","LEX_EXIT","LEX_FUNCTION","LEX_GETLINE","LEX_NEXTFILE", +"LEX_IN","LEX_AND","LEX_OR","INCREMENT","DECREMENT","LEX_BUILTIN","LEX_LENGTH", +"'?'","':'","','","'<'","'>'","'|'","'+'","'-'","'*'","'/'","'%'","'!'","UNARY", +"'^'","'$'","'('","')'","'['","']'","'{'","'}'","';'","start","program","rule", +"@1","@2","func_name","lex_builtin","function_prologue","@3","function_body", +"pattern","regexp","@4","action","statements","statement_term","statement","@5", +"print","if_statement","nls","opt_nls","input_redir","output_redir","opt_param_list", +"param_list","opt_exp","opt_rexpression_list","rexpression_list","opt_expression_list", +"expression_list","exp","@6","rexp","@7","simp_exp","non_post_simp_exp","opt_variable", +"variable","l_brace","r_brace","r_paren","opt_semi","semi","comma", NULL +}; +#endif + +static const short yyr1[] = { 0, + 62, 63, 63, 63, 63, 63, 65, 64, 66, 64, + 64, 64, 64, 64, 64, 64, 67, 67, 67, 68, + 68, 70, 69, 71, 71, 72, 72, 74, 73, 75, + 75, 76, 76, 76, 76, 77, 77, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 79, 78, 78, 78, 78, 80, 80, + 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, + 85, 85, 86, 86, 87, 87, 87, 87, 87, 88, + 88, 89, 89, 90, 90, 90, 90, 90, 90, 91, + 91, 92, 92, 92, 92, 92, 92, 94, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 96, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, + 99, 100, 100, 100, 101, 102, 103, 104, 104, 105, + 106 +}; + +static const short yyr2[] = { 0, + 3, 1, 2, 1, 2, 0, 0, 3, 0, 3, + 2, 2, 2, 1, 2, 2, 1, 1, 1, 1, + 1, 0, 7, 4, 4, 1, 3, 0, 4, 5, + 4, 1, 2, 1, 2, 1, 2, 2, 2, 3, + 1, 6, 8, 8, 10, 9, 2, 2, 6, 4, + 3, 2, 3, 0, 4, 6, 3, 2, 1, 1, + 6, 9, 1, 2, 0, 1, 0, 2, 0, 2, + 2, 2, 0, 1, 1, 3, 1, 2, 3, 0, + 1, 0, 1, 1, 3, 1, 2, 3, 3, 0, + 1, 1, 3, 1, 2, 3, 3, 0, 4, 5, + 4, 3, 3, 3, 3, 1, 2, 3, 3, 3, + 3, 5, 1, 2, 0, 4, 3, 3, 3, 1, + 2, 3, 3, 3, 5, 1, 2, 1, 3, 3, + 3, 3, 3, 3, 2, 2, 2, 3, 4, 4, + 1, 4, 1, 2, 2, 1, 1, 2, 2, 0, + 1, 1, 4, 2, 2, 2, 1, 0, 1, 1, + 2 +}; + +static const short yydefact[] = { 65, + 63, 66, 0, 64, 4, 0, 152, 146, 147, 7, + 9, 22, 150, 0, 0, 0, 141, 0, 0, 28, + 0, 0, 0, 65, 0, 2, 0, 0, 106, 14, + 26, 113, 128, 143, 0, 0, 0, 160, 0, 11, + 36, 65, 0, 12, 0, 67, 151, 144, 145, 0, + 0, 0, 0, 149, 143, 148, 0, 107, 137, 154, + 143, 94, 0, 92, 155, 5, 3, 1, 16, 0, + 13, 15, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 114, 0, 0, 0, 0, 0, 0, 98, + 135, 136, 34, 0, 54, 0, 0, 65, 0, 0, + 0, 59, 60, 80, 80, 0, 65, 0, 32, 0, + 41, 0, 0, 158, 65, 0, 0, 92, 0, 8, + 37, 10, 18, 17, 20, 21, 0, 19, 0, 102, + 0, 0, 0, 0, 95, 65, 157, 0, 0, 138, + 0, 158, 109, 105, 108, 103, 104, 0, 27, 110, + 111, 150, 133, 134, 130, 131, 132, 129, 0, 0, + 80, 0, 0, 0, 80, 47, 48, 0, 81, 0, + 52, 156, 35, 33, 158, 86, 150, 0, 0, 120, + 69, 0, 84, 126, 143, 58, 0, 39, 65, 159, + 38, 142, 153, 0, 68, 139, 140, 29, 96, 161, + 0, 97, 93, 158, 65, 0, 101, 99, 0, 0, + 0, 57, 0, 0, 152, 0, 51, 53, 65, 67, + 121, 0, 0, 0, 0, 0, 87, 0, 0, 0, + 0, 0, 0, 0, 127, 115, 40, 31, 77, 75, + 0, 0, 100, 24, 25, 112, 65, 55, 0, 65, + 0, 0, 0, 30, 119, 69, 71, 70, 72, 50, + 88, 89, 85, 124, 122, 123, 117, 118, 0, 0, + 65, 78, 0, 0, 0, 0, 0, 0, 0, 80, + 0, 0, 116, 23, 79, 76, 61, 56, 42, 0, + 65, 80, 0, 49, 125, 65, 65, 0, 0, 65, + 0, 43, 44, 65, 0, 62, 0, 46, 45, 0, + 0, 0 +}; + +static const short yydefgoto[] = { 310, + 25, 26, 39, 43, 127, 128, 27, 45, 69, 28, + 29, 57, 30, 108, 40, 109, 161, 110, 111, 2, + 3, 130, 226, 241, 242, 168, 181, 182, 116, 117, + 112, 159, 183, 270, 32, 33, 46, 34, 113, 114, + 140, 189, 42, 139 +}; + +static const short yypact[] = { -6, +-32768, 0, 875,-32768,-32768, -40, -38,-32768,-32768, -7, + -7,-32768, 10, 10, 10, -31, -26, 1735, 1735,-32768, + 1715, 1735, 1131, -6, 932,-32768, -24, 72,-32768,-32768, + 1304, 205,-32768, 5, 709, 1110, 1131,-32768, -24,-32768, + 0, -6, -24,-32768, 85, 3,-32768,-32768,-32768, 1110, + 1110, 1735, 1620, 8, 106, 8, 81,-32768, 8,-32768, +-32768,-32768, 37, 1250,-32768,-32768,-32768,-32768,-32768, 709, +-32768,-32768, 1620, 1620, 90, 1620, 1620, 1620, 1620, 1620, + 1620, 65, 205, 1735, 1735, 1735, 1735, 1735, 1735,-32768, +-32768,-32768,-32768, 50,-32768, 111, 70, -6, 93, -7, + -7,-32768,-32768, 1620, 1620, -7, -6, 758,-32768, 819, +-32768, 1040, 709, 100, -6, 99, 55, 1402, 9,-32768, +-32768,-32768,-32768,-32768,-32768,-32768, 109,-32768, 1735,-32768, + 99, 99, 1250, 119, 1620, -6,-32768, 133, 1180,-32768, + 758, 100, 1327, 794,-32768, 1515, 1451, 1353, 1402, 1327, + 1327, 10, 125, 125, 8, 8, 8, 8, 1620, 1620, + 1620, 42, 1620, 981, 1657,-32768,-32768, -7, 1402, -7, +-32768,-32768,-32768,-32768, 100,-32768, 10, 1715, 1131,-32768, + 96, 39, 1538, 205, 117,-32768, 758,-32768, -6,-32768, +-32768,-32768,-32768, 7, 205,-32768,-32768,-32768, 1402,-32768, + 166,-32768, 1402, 100, -6, 1620,-32768, 1402, 1250, -7, + 1131,-32768, 1250, 151, -12, 100,-32768,-32768, -6, 3, +-32768, 37, 1620, 1620, 1620, -7, 1678, 1201, 1678, 1678, + 181, 1678, 1678, 1678, 205,-32768,-32768,-32768,-32768,-32768, + 99, 56,-32768,-32768,-32768, 1402, -6,-32768, 11, -6, + 131, 183, 1061,-32768,-32768, 96, 1402, 1402, 1402,-32768, + 1538,-32768, 1538, 635, 83,-32768, 1599, 1579, 1474, 1678, + -6,-32768, 103, 981, -7, 981, 1620, 99, 623, 1620, + -7, 1678, 1538,-32768,-32768,-32768, 170,-32768,-32768, 1250, + -6, 1620, 99,-32768, 1538, -6, -6, 981, 99, -6, + 981,-32768,-32768, -6, 981,-32768, 981,-32768,-32768, 190, + 191,-32768 +}; + +static const short yypgoto[] = {-32768, +-32768, 167,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 211,-32768, 107, -53, 315, -105,-32768,-32768,-32768, 199, + 97, -22, -62,-32768,-32768, -103,-32768,-32768, 94, -14, + -3,-32768, -202,-32768, 318, 177, -134, 95, 124, -69, + 407, -138, 420, -177 +}; + + +#define YYLAST 1790 + + +static const short yytable[] = { 31, + 142, 170, 174, 205, 228, 1, 1, 239, 63, 135, + 240, 135, 4, 7, 36, 90, 141, 207, 37, 64, + 252, 31, 119, 50, 261, 263, 264, 265, 51, 267, + 268, 269, 118, 118, 24, 174, 219, 135, 175, 227, + 91, 92, 220, 188, 37, 129, 118, 118, -83, 133, + 136, -83, 136, 38, 1, 135, 272, 210, 214, 187, + 89, 216, -73, 22, 273, 244, 193, 283, 275, 143, + 144, 204, 146, 147, 148, 149, 150, 151, 136, 295, + 136, 174, -83, -83, 1, 134, 7, 123, 124, 8, + 9, 229, 137, 145,-32768, 152, 136, 136, 211, -83, + 169, 169, 38, 285, 160, 223, 286, 47, 48, 49, + -91, -74, 55, 55, 162, 55, 61, 237, 14, 15, + 65, 68, 125, 126, 163, 55, 35, 236, 18, 19, + 24, 199, 38, 52, 71, 203, 22, 53, 121, 224, + 225, 91, 92, 131, 132, 120, 55, 165, 35, 122, + 70, 35, 91, 92, 137, 208, 209, 169, 55, 213, + 38, 169, 35, 194, 222, 201, 35, 198, 287, 243, + 289, 251, 86, 87, 88, 64, 293, 89, 55, 55, + 55, 55, 55, 55, 266, 277, 278, 296, 299, 311, + 312, 67, 303, 281, 164, 306, 249, 255, 60, 308, + 0, 309, 246, 172, 185, 0, 55, 118, 41, 41, + 0, 191, 55, 0, 0, 0, 0, 0, 0, 257, + 258, 259, 0, 55, 0, 0, 41, 55, 0, 0, + 0, 58, 200, 0, 0, 0, 0, 55, 55, 0, + 55, 55, 55, 55, 55, 55, 47, 0, 0, 279, + 84, 85, 86, 87, 88, 0, 0, 89, 0, 0, + 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, + 0, 47, 55, 290, 0, 0, 169, 55, 0, 0, + 0, 0, 0, 0, 0, 238, 0, 0, 169, 0, + 0, 0, 0, 55, 0, 0, 0, 55, 41, 41, + 0, 245, 55, 55, 41, 0, 0, 55, 0, 0, + 41, 0, 0, 0, 0, 254, 0, 0, 0, 0, + 180, 185, 185, 185, 185, 44, 185, 185, 185, 0, + 0, 0, 0, 0, 0, 54, 56, 0, 59, 0, + 55, 0, 72, 274, 0, 0, 276, 0, 83, 0, + 0, 55, 55, 55, 0, 55, 0, 55, 55, 55, + 41, 55, 55, 55, 185, 0, 41, 284, 41, 59, + 0, 0, 0, 55, 0, 0, 185, 55, 0, 0, + 0, 83, 0, 0, 55, 0, 0, 298, 221, 55, + 0, 0, 301, 302, 0, 0, 305, 0, 0, 0, + 307, 153, 154, 155, 156, 157, 158, 0, 41, 0, + 0, 0, 0, 0, 166, 167, 0, 0, 0, 0, + 171, 0, 0, 0, 41, 0, 186, 184, 0, 83, + 0, 0, 0, 0, 0, 83, 0, 180, 180, 180, + 180, 0, 180, 180, 180, 0, 195, 0, 0, 0, + 83, 0, 0, 0, 115, 0, 0, 0, 0, 0, + 83, 83, 0, 83, 83, 83, 83, 83, 83, 138, + 0, 0, 0, 41, 0, 0, 212, 0, 0, 41, + 180, 0, 217, 0, 218, 0, 83, 0, 0, 115, + 0, 0, 180, 0, 0, 59, 0, 0, 0, 0, + 235, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, + 83, 0, 192, 0, 248, 83, 83, 115, 0, 0, + 83, 0, 115, 190, 0, 0, 0, 196, 197, 0, + 260, 0, 0, 0, 184, 184, 184, 184, 0, 184, + 184, 184, 0, 0, 0, 0, 0, 0, 0, 0, + 115, 190, 0, 83, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 83, 83, 83, 0, 235, 0, + 235, 235, 235, 115, 235, 235, 235, 184, 0, 288, + 0, 0, 0, 0, 190, 294, 83, 0, 0, 184, + 235, 0, 0, 0, 0, 0, 115, 83, 0, 0, + 0, 0, 235, 0, 0, 247, 0, 0, 0, 250, + 0, 0, 0, 190, 0, 6, 7, 0, 256, 8, + 9, 73, 0, 0, 74, 253, 0, 0, 7, 0, + 0, 8, 9,-32768, 0, 0, 0, 271, 0, 0, + 0, 0, 0, 0, 0, 75, 76, 77, 14, 15, + 16, 17, 78, 0, 0, 80, 81, 82, 18, 19, + 14, 15, 280, 52, 0, 0, 22, 53, 0, 0, + 18, 19, 0, 38, 291, 52, 0, 0, 22, 53, + 0, 0, 0, 115, 0, 115, 297, 0, 292, 300, + 0, 0, 0, 0, 0, 304, 0, 0, 0, 93, + 0, 6, 7, 0, 0, 8, 9, 115, 0, 0, + 115, 0, 0, 0, 115, 94, 115, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 0, 13, + 106, 0, 0, 0, 14, 15, 16, 17, 0, 0, + 0, 0, 0, 0, 18, 19, 0, 20, 173, 21, + 6, 7, 22, 23, 8, 9, 0, 24, 107, 38, + 0, 0, 0, 0, 94, 0, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 0, 13, 106, + 0, 0, 0, 14, 15, 16, 17, 7, 0, 0, + 8, 9, 73, 18, 19,-32768, 20, 0, 21, 0, + 0, 22, 23, 0, 0, 0, 24, 107, 38, 176, + 0, 6, 7, 0, 0, 8, 9, 0, -82, 14, + 15, -82, 0, 0, 0, 0, 80, 81, 82, 18, + 19, 0, 0, 0, 52, 0, 0, 22, 53, 177, + 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, + 0, 0, -82, -82, 18, 19, 0, 20, 0, 178, + 0, 0, 22, 179, -6, 5, 0, 6, 7, -82, + 0, 8, 9, 0, 0, 0, 0, -6, 0, 10, + 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 12, 13, 0, 0, 0, 0, + 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, + 18, 19, 0, 20, 0, 21, 0, 0, 22, 23, + 0, -65, 66, 24, 6, 7, 0, 0, 8, 9, + 0, 0, 0, 0, 1, 0, 10, 11, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 12, 13, 0, 0, 0, 0, 14, 15, 16, + 17, 0, 0, 0, 0, 0, 0, 18, 19, 0, + 20, 0, 21, 6, 7, 22, 23, 8, 9, 0, + 24, 0, 0, 0, 0, 0, 0, 94, 0, 95, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 0, 13, 106, 0, 0, 0, 14, 15, 16, 17, + 0, 0, 0, 0, 0, 0, 18, 19, 0, 20, + 0, 21, 0, 0, 22, 23, 0, 0, 0, 24, + 0, 38, 6, 7, 0, 0, 8, 9, 73, 0, + 0, 74, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 7, 0, 0, 8, 9, 0, + 0, 0, 75, 76, 77, 14, 15, 16, 17, 78, + 0, 0, 80, 81, 82, 18, 19, 0, 0, 0, + 52, 13, 0, 22, 53, 0, 14, 15, 16, 17, + 38, 0, 0, 0, 0, 0, 18, 19, 0, 20, + 62, 21, 6, 7, 22, 23, 8, 9, 0, 0, + 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 62, 0, 6, 7, 0, 0, 8, 9, 0, + 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, + 0, 0, 0, 0, 0, 18, 19, 0, 20, 0, + 21, 13, 0, 22, 23, -90, 14, 15, 16, 17, + 0, 0, 0, 0, 0, 0, 18, 19, 0, 20, + 202, 21, 6, 7, 22, 23, 8, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 0, 6, 7, 0, 0, 8, 9, 0, + 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, + 0, 0, 0, 0, 0, 18, 19, 0, 20, 0, + 21, 177, 0, 22, 23, 0, 14, 15, 16, 17, + 0, 0, 0, 0, 0, 0, 18, 19, 0, 20, + 0, 178, 6, 7, 22, 53, 8, 9, 73, 0, + 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 75, 76, 77, 14, 15, 16, 17, 78, + 0, 0, 80, 81, 82, 18, 19, 0, 0, 0, + 52, 0, 0, 22, 53, 137, 6, 7, 0, 0, + 8, 9, 73, 0, 0, 74, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 8, 9,-32768, 75, 76, 77, 14, + 15, 16, 17, 78, 0, 79, 80, 81, 82, 18, + 19, 0, 0, 0, 52, 6, 7, 22, 53, 8, + 9, 73, 14, 15, 74, 0, 0, 0, 0,-32768, +-32768,-32768, 18, 19, 0, 0, 0, 52, 0, 0, + 22, 53, 0, 0, 0, 75, 76, 77, 14, 15, + 16, 17, 78, 206, 0, 80, 81, 82, 18, 19, + 0, 0, 0, 52, 6, 7, 22, 53, 8, 9, + 73, 0, 0, 74, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 75, 76, 77, 14, 15, 16, + 17, 78, 0, 0, 80, 81, 82, 18, 19, 0, + 0, 0, 52, 6, 7, 22, 53, 8, 9, 73, + 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, + 8, 9, 229, 75, 76, 230, 14, 15, 16, 17, + 0, 0, 0, 80, 81, 82, 18, 19, 0, 0, + 0, 52, 0, 0, 22, 53, 231, 232, 233, 14, + 15, 16, 17, 234, 282, 0, 0, 6, 7, 18, + 19, 8, 9, 73, 52, 0, 74, 22, 53, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 7, 0, 0, 8, 9, 229, 75, 0, 230, + 14, 15, 16, 17, 0, 0, 0, 80, 81, 82, + 18, 19, 0, 0, 0, 52, 0, 0, 22, 53, + 231, 232, 233, 14, 15, 16, 17, 234, 0, 0, + 0, 6, 7, 18, 19, 8, 9, 229, 52, 0, + 230, 22, 53, 0, 0, 0, 0, 0, 0, 0, + 0, 6, 7, 0, 0, 8, 9, 229, 0, 0, + 230, 231, 232, 0, 14, 15, 16, 17, 0, 0, + 0, 0, 6, 7, 18, 19, 8, 9, 0, 52, + 0, 231, 22, 53, 14, 15, 16, 17, 0, 0, + 0, 0, 0, 0, 18, 19, 0, 0, 0, 52, + 13, 0, 22, 53, 0, 14, 15, 16, 17, 6, + 215, 0, 0, 8, 9, 18, 19, 0, 20, 0, + 21, 0, 0, 22, 23, 0, 0, 0, 0, 0, + 6, 7, 0, 0, 8, 9, 0, 13, 0, 0, + 0, 0, 14, 15, 16, 17, 0, 0, 0, 0, + 0, 0, 18, 19, 0, 20, 0, 21, 177, 0, + 22, 23, 0, 14, 15, 16, 17, 6, 7, 0, + 0, 8, 9, 18, 19, 0, 20, 0, 178, 0, + 0, 22, 53, 0, 0, 0, 0, 6, 7, 0, + 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, + 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, + 18, 19, 0, 20, 0, 52, 0, 0, 22, 53, + 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, + 18, 19, 0, 0, 0, 52, 0, 0, 22, 53 +}; + +static const short yycheck[] = { 3, + 70, 105, 108, 142, 182, 13, 13, 1, 23, 1, + 4, 1, 13, 4, 55, 11, 70, 152, 57, 23, + 33, 25, 37, 55, 227, 228, 229, 230, 55, 232, + 233, 234, 36, 37, 59, 141, 175, 1, 108, 1, + 36, 37, 177, 113, 57, 43, 50, 51, 10, 53, + 42, 13, 42, 61, 13, 1, 1, 161, 164, 113, + 53, 165, 56, 54, 242, 204, 58, 270, 58, 73, + 74, 141, 76, 77, 78, 79, 80, 81, 42, 282, + 42, 187, 44, 45, 13, 5, 4, 3, 4, 7, + 8, 9, 56, 4, 12, 31, 42, 42, 57, 61, + 104, 105, 61, 1, 55, 10, 4, 13, 14, 15, + 56, 56, 18, 19, 4, 21, 22, 187, 36, 37, + 24, 25, 38, 39, 55, 31, 3, 11, 46, 47, + 59, 135, 61, 51, 28, 139, 54, 55, 42, 44, + 45, 36, 37, 50, 51, 39, 52, 55, 25, 43, + 27, 28, 36, 37, 56, 159, 160, 161, 64, 163, + 61, 165, 39, 55, 179, 33, 43, 49, 274, 4, + 276, 21, 48, 49, 50, 179, 280, 53, 84, 85, + 86, 87, 88, 89, 4, 55, 4, 18, 292, 0, + 0, 25, 298, 256, 98, 301, 211, 220, 22, 305, + -1, 307, 206, 107, 110, -1, 112, 211, 10, 11, + -1, 115, 118, -1, -1, -1, -1, -1, -1, 223, + 224, 225, -1, 129, -1, -1, 28, 133, -1, -1, + -1, 21, 136, -1, -1, -1, -1, 143, 144, -1, + 146, 147, 148, 149, 150, 151, 152, -1, -1, 253, + 46, 47, 48, 49, 50, -1, -1, 53, -1, -1, + -1, -1, -1, 169, -1, -1, -1, -1, -1, -1, + -1, 177, 178, 277, -1, -1, 280, 183, -1, -1, + -1, -1, -1, -1, -1, 189, -1, -1, 292, -1, + -1, -1, -1, 199, -1, -1, -1, 203, 100, 101, + -1, 205, 208, 209, 106, -1, -1, 213, -1, -1, + 112, -1, -1, -1, -1, 219, -1, -1, -1, -1, + 110, 227, 228, 229, 230, 11, 232, 233, 234, -1, + -1, -1, -1, -1, -1, 18, 19, -1, 21, -1, + 246, -1, 28, 247, -1, -1, 250, -1, 31, -1, + -1, 257, 258, 259, -1, 261, -1, 263, 264, 265, + 162, 267, 268, 269, 270, -1, 168, 271, 170, 52, + -1, -1, -1, 279, -1, -1, 282, 283, -1, -1, + -1, 64, -1, -1, 290, -1, -1, 291, 178, 295, + -1, -1, 296, 297, -1, -1, 300, -1, -1, -1, + 304, 84, 85, 86, 87, 88, 89, -1, 210, -1, + -1, -1, -1, -1, 100, 101, -1, -1, -1, -1, + 106, -1, -1, -1, 226, -1, 112, 110, -1, 112, + -1, -1, -1, -1, -1, 118, -1, 227, 228, 229, + 230, -1, 232, 233, 234, -1, 129, -1, -1, -1, + 133, -1, -1, -1, 35, -1, -1, -1, -1, -1, + 143, 144, -1, 146, 147, 148, 149, 150, 151, 63, + -1, -1, -1, 275, -1, -1, 162, -1, -1, 281, + 270, -1, 168, -1, 170, -1, 169, -1, -1, 70, + -1, -1, 282, -1, -1, 178, -1, -1, -1, -1, + 183, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 199, -1, -1, -1, + 203, -1, 116, -1, 210, 208, 209, 108, -1, -1, + 213, -1, 113, 114, -1, -1, -1, 131, 132, -1, + 226, -1, -1, -1, 227, 228, 229, 230, -1, 232, + 233, 234, -1, -1, -1, -1, -1, -1, -1, -1, + 141, 142, -1, 246, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 257, 258, 259, -1, 261, -1, + 263, 264, 265, 164, 267, 268, 269, 270, -1, 275, + -1, -1, -1, -1, 175, 281, 279, -1, -1, 282, + 283, -1, -1, -1, -1, -1, 187, 290, -1, -1, + -1, -1, 295, -1, -1, 209, -1, -1, -1, 213, + -1, -1, -1, 204, -1, 3, 4, -1, 222, 7, + 8, 9, -1, -1, 12, 216, -1, -1, 4, -1, + -1, 7, 8, 9, -1, -1, -1, 241, -1, -1, + -1, -1, -1, -1, -1, 33, 34, 35, 36, 37, + 38, 39, 40, -1, -1, 43, 44, 45, 46, 47, + 36, 37, 253, 51, -1, -1, 54, 55, -1, -1, + 46, 47, -1, 61, 278, 51, -1, -1, 54, 55, + -1, -1, -1, 274, -1, 276, 290, -1, 279, 293, + -1, -1, -1, -1, -1, 299, -1, -1, -1, 1, + -1, 3, 4, -1, -1, 7, 8, 298, -1, -1, + 301, -1, -1, -1, 305, 17, 307, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, -1, 31, + 32, -1, -1, -1, 36, 37, 38, 39, -1, -1, + -1, -1, -1, -1, 46, 47, -1, 49, 1, 51, + 3, 4, 54, 55, 7, 8, -1, 59, 60, 61, + -1, -1, -1, -1, 17, -1, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, -1, 31, 32, + -1, -1, -1, 36, 37, 38, 39, 4, -1, -1, + 7, 8, 9, 46, 47, 12, 49, -1, 51, -1, + -1, 54, 55, -1, -1, -1, 59, 60, 61, 1, + -1, 3, 4, -1, -1, 7, 8, -1, 10, 36, + 37, 13, -1, -1, -1, -1, 43, 44, 45, 46, + 47, -1, -1, -1, 51, -1, -1, 54, 55, 31, + -1, -1, -1, -1, 36, 37, 38, 39, -1, -1, + -1, -1, 44, 45, 46, 47, -1, 49, -1, 51, + -1, -1, 54, 55, 0, 1, -1, 3, 4, 61, + -1, 7, 8, -1, -1, -1, -1, 13, -1, 15, + 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 30, 31, -1, -1, -1, -1, + 36, 37, 38, 39, -1, -1, -1, -1, -1, -1, + 46, 47, -1, 49, -1, 51, -1, -1, 54, 55, + -1, 0, 1, 59, 3, 4, -1, -1, 7, 8, + -1, -1, -1, -1, 13, -1, 15, 16, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 30, 31, -1, -1, -1, -1, 36, 37, 38, + 39, -1, -1, -1, -1, -1, -1, 46, 47, -1, + 49, -1, 51, 3, 4, 54, 55, 7, 8, -1, + 59, -1, -1, -1, -1, -1, -1, 17, -1, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + -1, 31, 32, -1, -1, -1, 36, 37, 38, 39, + -1, -1, -1, -1, -1, -1, 46, 47, -1, 49, + -1, 51, -1, -1, 54, 55, -1, -1, -1, 59, + -1, 61, 3, 4, -1, -1, 7, 8, 9, -1, + -1, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 3, 4, -1, -1, 7, 8, -1, + -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, + -1, -1, 43, 44, 45, 46, 47, -1, -1, -1, + 51, 31, -1, 54, 55, -1, 36, 37, 38, 39, + 61, -1, -1, -1, -1, -1, 46, 47, -1, 49, + 1, 51, 3, 4, 54, 55, 7, 8, -1, -1, + -1, 61, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, -1, 3, 4, -1, -1, 7, 8, -1, + 31, -1, -1, -1, -1, 36, 37, 38, 39, -1, + -1, -1, -1, -1, -1, 46, 47, -1, 49, -1, + 51, 31, -1, 54, 55, 56, 36, 37, 38, 39, + -1, -1, -1, -1, -1, -1, 46, 47, -1, 49, + 1, 51, 3, 4, 54, 55, 7, 8, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1, -1, 3, 4, -1, -1, 7, 8, -1, + 31, -1, -1, -1, -1, 36, 37, 38, 39, -1, + -1, -1, -1, -1, -1, 46, 47, -1, 49, -1, + 51, 31, -1, 54, 55, -1, 36, 37, 38, 39, + -1, -1, -1, -1, -1, -1, 46, 47, -1, 49, + -1, 51, 3, 4, 54, 55, 7, 8, 9, -1, + -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 33, 34, 35, 36, 37, 38, 39, 40, + -1, -1, 43, 44, 45, 46, 47, -1, -1, -1, + 51, -1, -1, 54, 55, 56, 3, 4, -1, -1, + 7, 8, 9, -1, -1, 12, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 4, -1, -1, 7, 8, 9, 33, 34, 35, 36, + 37, 38, 39, 40, -1, 42, 43, 44, 45, 46, + 47, -1, -1, -1, 51, 3, 4, 54, 55, 7, + 8, 9, 36, 37, 12, -1, -1, -1, -1, 43, + 44, 45, 46, 47, -1, -1, -1, 51, -1, -1, + 54, 55, -1, -1, -1, 33, 34, 35, 36, 37, + 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, + -1, -1, -1, 51, 3, 4, 54, 55, 7, 8, + 9, -1, -1, 12, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 33, 34, 35, 36, 37, 38, + 39, 40, -1, -1, 43, 44, 45, 46, 47, -1, + -1, -1, 51, 3, 4, 54, 55, 7, 8, 9, + -1, -1, 12, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3, 4, -1, -1, + 7, 8, 9, 33, 34, 12, 36, 37, 38, 39, + -1, -1, -1, 43, 44, 45, 46, 47, -1, -1, + -1, 51, -1, -1, 54, 55, 33, 34, 35, 36, + 37, 38, 39, 40, 41, -1, -1, 3, 4, 46, + 47, 7, 8, 9, 51, -1, 12, 54, 55, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 3, 4, -1, -1, 7, 8, 9, 33, -1, 12, + 36, 37, 38, 39, -1, -1, -1, 43, 44, 45, + 46, 47, -1, -1, -1, 51, -1, -1, 54, 55, + 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, + -1, 3, 4, 46, 47, 7, 8, 9, 51, -1, + 12, 54, 55, -1, -1, -1, -1, -1, -1, -1, + -1, 3, 4, -1, -1, 7, 8, 9, -1, -1, + 12, 33, 34, -1, 36, 37, 38, 39, -1, -1, + -1, -1, 3, 4, 46, 47, 7, 8, -1, 51, + -1, 33, 54, 55, 36, 37, 38, 39, -1, -1, + -1, -1, -1, -1, 46, 47, -1, -1, -1, 51, + 31, -1, 54, 55, -1, 36, 37, 38, 39, 3, + 4, -1, -1, 7, 8, 46, 47, -1, 49, -1, + 51, -1, -1, 54, 55, -1, -1, -1, -1, -1, + 3, 4, -1, -1, 7, 8, -1, 31, -1, -1, + -1, -1, 36, 37, 38, 39, -1, -1, -1, -1, + -1, -1, 46, 47, -1, 49, -1, 51, 31, -1, + 54, 55, -1, 36, 37, 38, 39, 3, 4, -1, + -1, 7, 8, 46, 47, -1, 49, -1, 51, -1, + -1, 54, 55, -1, -1, -1, -1, 3, 4, -1, + -1, 7, 8, -1, -1, -1, -1, -1, -1, -1, + 36, 37, 38, 39, -1, -1, -1, -1, -1, -1, + 46, 47, -1, 49, -1, 51, -1, -1, 54, 55, + 36, 37, 38, 39, -1, -1, -1, -1, -1, -1, + 46, 47, -1, -1, -1, 51, -1, -1, 54, 55 +}; +/* -*-C-*- Note some compilers choke on comments on `#line' lines. */ +#line 3 "/usr/share/bison.simple" + +/* Skeleton output parser for bison, + Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +#ifndef alloca +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else /* not GNU C. */ +#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) +#include <alloca.h> +#else /* not sparc */ +#if defined (MSDOS) && !defined (__TURBOC__) +#include <malloc.h> +#else /* not MSDOS, or __TURBOC__ */ +#if defined(_AIX) +#include <malloc.h> + #pragma alloca +#else /* not MSDOS, __TURBOC__, or _AIX */ +#ifdef __hpux +#ifdef __cplusplus +extern "C" { +void *alloca (unsigned int); +}; +#else /* not __cplusplus */ +void *alloca (); +#endif /* not __cplusplus */ +#endif /* __hpux */ +#endif /* not _AIX */ +#endif /* not MSDOS, or __TURBOC__ */ +#endif /* not sparc. */ +#endif /* not GNU C. */ +#endif /* alloca not defined. */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYACCEPT return(0) +#define YYABORT return(1) +#define YYERROR goto yyerrlab1 +/* Like YYERROR except do call yyerror. + This remains here temporarily to ease the + transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ +#define YYFAIL goto yyerrlab +#define YYRECOVERING() (!!yyerrstatus) +#define YYBACKUP(token, value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { yychar = (token), yylval = (value); \ + yychar1 = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { yyerror ("syntax error: cannot back up"); YYERROR; } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +#ifndef YYPURE +#define YYLEX yylex() +#endif + +#ifdef YYPURE +#ifdef YYLSP_NEEDED +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval, &yylloc) +#endif +#else /* not YYLSP_NEEDED */ +#ifdef YYLEX_PARAM +#define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +#define YYLEX yylex(&yylval) +#endif +#endif /* not YYLSP_NEEDED */ +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef YYPURE + +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + +#ifdef YYLSP_NEEDED +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ +#endif + +int yynerrs; /* number of parse errors so far */ +#endif /* not YYPURE */ + +#if YYDEBUG != 0 +int yydebug; /* nonzero means print parse trace */ +/* Since this is uninitialized, it does not stop multiple parsers + from coexisting. */ +#endif + +/* YYINITDEPTH indicates the initial size of the parser's stacks */ + +#ifndef YYINITDEPTH +#define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#if YYMAXDEPTH == 0 +#undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 10000 +#endif + +#ifndef YYPARSE_RETURN_TYPE +#define YYPARSE_RETURN_TYPE int +#endif + +/* Prevent warning if -Wstrict-prototypes. */ +#ifdef __GNUC__ +YYPARSE_RETURN_TYPE yyparse (void); +#endif + +#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) +#else /* not GNU C or C++ */ +#ifndef __cplusplus + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (to, from, count) + char *to; + char *from; + int count; +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#else /* __cplusplus */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +__yy_memcpy (char *to, char *from, int count) +{ + register char *f = from; + register char *t = to; + register int i = count; + + while (i-- > 0) + *t++ = *f++; +} + +#endif +#endif + +#line 196 "/usr/share/bison.simple" + +/* The user can define YYPARSE_PARAM as the name of an argument to be passed + into yyparse. The argument should have type void *. + It should actually point to an object. + Grammar actions can access the variable by casting it + to the proper pointer type. */ + +#ifdef YYPARSE_PARAM +#ifdef __cplusplus +#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM +#define YYPARSE_PARAM_DECL +#else /* not __cplusplus */ +#define YYPARSE_PARAM_ARG YYPARSE_PARAM +#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +#endif /* not __cplusplus */ +#else /* not YYPARSE_PARAM */ +#define YYPARSE_PARAM_ARG +#define YYPARSE_PARAM_DECL +#endif /* not YYPARSE_PARAM */ + +YYPARSE_RETURN_TYPE +yyparse(YYPARSE_PARAM_ARG) + YYPARSE_PARAM_DECL +{ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1 = 0; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYINITDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + +#ifdef YYLSP_NEEDED + YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + +#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#else +#define YYPOPSTACK (yyvsp--, yyssp--) +#endif + + int yystacksize = YYINITDEPTH; + +#ifdef YYPURE + int yychar; + YYSTYPE yylval; + int yynerrs; +#ifdef YYLSP_NEEDED + YYLTYPE yylloc; +#endif +#endif + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Starting parse\n"); +#endif + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss - 1; + yyvsp = yyvs; +#ifdef YYLSP_NEEDED + yylsp = yyls; +#endif + +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: + + *++yyssp = yystate; + + if (yyssp >= yyss + yystacksize - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; +#ifdef YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; +#endif + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + +#ifdef yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ +#ifdef YYLSP_NEEDED + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yystacksize); +#else + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yystacksize); +#endif + + yyss = yyss1; yyvs = yyvs1; +#ifdef YYLSP_NEEDED + yyls = yyls1; +#endif +#else /* no yyoverflow */ + /* Extend the stack our own way. */ + if (yystacksize >= YYMAXDEPTH) + { + yyerror("parser stack overflow"); + return 2; + } + yystacksize *= 2; + if (yystacksize > YYMAXDEPTH) + yystacksize = YYMAXDEPTH; + yyss = (short *) alloca (yystacksize * sizeof (*yyssp)); + __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp)); + yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp)); + __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp)); +#ifdef YYLSP_NEEDED + yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp)); + __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp)); +#endif +#endif /* no yyoverflow */ + + yyssp = yyss + size - 1; + yyvsp = yyvs + size - 1; +#ifdef YYLSP_NEEDED + yylsp = yyls + size - 1; +#endif + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yystacksize); +#endif + + if (yyssp >= yyss + yystacksize - 1) + YYABORT; + } + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); +#endif + + goto yybackup; + yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Reading a token: "); +#endif + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); +#endif + } + else + { + yychar1 = YYTRANSLATE(yychar); + +#if YYDEBUG != 0 + if (yydebug) + { + fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise meaning + of a token, for further debugging info. */ +#ifdef YYPRINT + YYPRINT (stderr, yychar, yylval); +#endif + fprintf (stderr, ")\n"); + } +#endif + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); +#endif + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + +/* Do the default action for the current state. */ +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +/* Do a reduction. yyn is the number of a rule to reduce with. */ +yyreduce: + yylen = yyr2[yyn]; + if (yylen > 0) + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + +#if YYDEBUG != 0 + if (yydebug) + { + int i; + + fprintf (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); + + /* Print the symbols being reduced, and their result. */ + for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) + fprintf (stderr, "%s ", yytname[yyrhs[i]]); + fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + } +#endif + + + switch (yyn) { + +case 1: +#line 151 "./awk.y" +{ + expression_value = yyvsp[-1].nodeval; + check_funcs(); + ; + break;} +case 2: +#line 159 "./awk.y" +{ + if (yyvsp[0].nodeval != NULL) + yyval.nodeval = yyvsp[0].nodeval; + else + yyval.nodeval = NULL; + yyerrok; + ; + break;} +case 3: +#line 168 "./awk.y" +{ + if (yyvsp[0].nodeval == NULL) + yyval.nodeval = yyvsp[-1].nodeval; + else if (yyvsp[-1].nodeval == NULL) + yyval.nodeval = yyvsp[0].nodeval; + else { + if (yyvsp[-1].nodeval->type != Node_rule_list) + yyvsp[-1].nodeval = node(yyvsp[-1].nodeval, Node_rule_list, + (NODE*) NULL); + yyval.nodeval = append_right(yyvsp[-1].nodeval, + node(yyvsp[0].nodeval, Node_rule_list, (NODE *) NULL)); + } + yyerrok; + ; + break;} +case 4: +#line 182 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 5: +#line 183 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 6: +#line 184 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 7: +#line 188 "./awk.y" +{ io_allowed = FALSE; ; + break;} +case 8: +#line 190 "./awk.y" +{ + if (begin_block != NULL) { + if (begin_block->type != Node_rule_list) + begin_block = node(begin_block, Node_rule_list, + (NODE *) NULL); + (void) append_right(begin_block, node( + node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval), + Node_rule_list, (NODE *) NULL) ); + } else + begin_block = node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval); + yyval.nodeval = NULL; + io_allowed = TRUE; + yyerrok; + ; + break;} +case 9: +#line 204 "./awk.y" +{ io_allowed = FALSE; ; + break;} +case 10: +#line 206 "./awk.y" +{ + if (end_block != NULL) { + if (end_block->type != Node_rule_list) + end_block = node(end_block, Node_rule_list, + (NODE *) NULL); + (void) append_right (end_block, node( + node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval), + Node_rule_list, (NODE *) NULL)); + } else + end_block = node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval); + yyval.nodeval = NULL; + io_allowed = TRUE; + yyerrok; + ; + break;} +case 11: +#line 221 "./awk.y" +{ + warning("BEGIN blocks must have an action part"); + errcount++; + yyerrok; + ; + break;} +case 12: +#line 227 "./awk.y" +{ + warning("END blocks must have an action part"); + errcount++; + yyerrok; + ; + break;} +case 13: +#line 233 "./awk.y" +{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_rule_node, yyvsp[0].nodeval); yyerrok; ; + break;} +case 14: +#line 235 "./awk.y" +{ yyval.nodeval = node((NODE *) NULL, Node_rule_node, yyvsp[0].nodeval); yyerrok; ; + break;} +case 15: +#line 237 "./awk.y" +{ + yyval.nodeval = node(yyvsp[-1].nodeval, + Node_rule_node, + node(node(node(make_number(0.0), + Node_field_spec, + (NODE *) NULL), + Node_expression_list, + (NODE *) NULL), + Node_K_print, + (NODE *) NULL)); + yyerrok; + ; + break;} +case 16: +#line 250 "./awk.y" +{ + func_install(yyvsp[-1].nodeval, yyvsp[0].nodeval); + yyval.nodeval = NULL; + yyerrok; + ; + break;} +case 17: +#line 259 "./awk.y" +{ yyval.sval = yyvsp[0].sval; ; + break;} +case 18: +#line 261 "./awk.y" +{ yyval.sval = yyvsp[0].sval; ; + break;} +case 19: +#line 263 "./awk.y" +{ + yyerror("%s() is a built-in function, it cannot be redefined", + tokstart); + errcount++; + /* yyerrok; */ + ; + break;} +case 22: +#line 278 "./awk.y" +{ + param_counter = 0; + ; + break;} +case 23: +#line 282 "./awk.y" +{ + NODE *t; + + t = make_param(yyvsp[-4].sval); + t->flags |= FUNC; + yyval.nodeval = append_right(t, yyvsp[-2].nodeval); + can_return = TRUE; + /* check for duplicate parameter names */ + if (dup_parms(yyval.nodeval)) + errcount++; + ; + break;} +case 24: +#line 297 "./awk.y" +{ + yyval.nodeval = yyvsp[-2].nodeval; + can_return = FALSE; + ; + break;} +case 25: +#line 302 "./awk.y" +{ + yyval.nodeval = node((NODE *) NULL, Node_K_return, (NODE *) NULL); + can_return = FALSE; + ; + break;} +case 26: +#line 311 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 27: +#line 313 "./awk.y" +{ yyval.nodeval = mkrangenode(node(yyvsp[-2].nodeval, Node_cond_pair, yyvsp[0].nodeval)); ; + break;} +case 28: +#line 322 "./awk.y" +{ ++want_regexp; ; + break;} +case 29: +#line 324 "./awk.y" +{ + NODE *n; + size_t len; + + getnode(n); + n->type = Node_regex; + len = strlen(yyvsp[-1].sval); + n->re_exp = make_string(yyvsp[-1].sval, len); + n->re_reg = make_regexp(yyvsp[-1].sval, len, FALSE, TRUE); + n->re_text = NULL; + n->re_flags = CONST; + n->re_cnt = 1; + yyval.nodeval = n; + ; + break;} +case 30: +#line 342 "./awk.y" +{ yyval.nodeval = yyvsp[-3].nodeval; ; + break;} +case 31: +#line 344 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 32: +#line 349 "./awk.y" +{ + yyval.nodeval = yyvsp[0].nodeval; + if (do_lint && isnoeffect(yyval.nodeval->type)) + warning("statement may have no effect"); + ; + break;} +case 33: +#line 355 "./awk.y" +{ + if (yyvsp[-1].nodeval == NULL || yyvsp[-1].nodeval->type != Node_statement_list) + yyvsp[-1].nodeval = node(yyvsp[-1].nodeval, Node_statement_list, (NODE *) NULL); + yyval.nodeval = append_right(yyvsp[-1].nodeval, + node(yyvsp[0].nodeval, Node_statement_list, (NODE *) NULL)); + yyerrok; + ; + break;} +case 34: +#line 363 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 35: +#line 365 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 38: +#line 375 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 39: +#line 377 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 40: +#line 379 "./awk.y" +{ yyval.nodeval = yyvsp[-1].nodeval; ; + break;} +case 41: +#line 381 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 42: +#line 383 "./awk.y" +{ yyval.nodeval = node(yyvsp[-3].nodeval, Node_K_while, yyvsp[0].nodeval); ; + break;} +case 43: +#line 385 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_K_do, yyvsp[-5].nodeval); ; + break;} +case 44: +#line 387 "./awk.y" +{ + /* + * Efficiency hack. Recognize the special case of + * + * for (iggy in foo) + * delete foo[iggy] + * + * and treat it as if it were + * + * delete foo + * + * Check that the body is a `delete a[i]' statement, + * and that both the loop var and array names match. + */ + if (yyvsp[0].nodeval->type == Node_K_delete + && yyvsp[0].nodeval->rnode != NULL + && strcmp(yyvsp[-5].sval, yyvsp[0].nodeval->rnode->var_value->vname) == 0 + && strcmp(yyvsp[-3].sval, yyvsp[0].nodeval->lnode->vname) == 0) { + yyvsp[0].nodeval->type = Node_K_delete_loop; + yyval.nodeval = yyvsp[0].nodeval; + } else { + yyval.nodeval = node(yyvsp[0].nodeval, Node_K_arrayfor, + make_for_loop(variable(yyvsp[-5].sval, CAN_FREE, Node_var), + (NODE *) NULL, variable(yyvsp[-3].sval, CAN_FREE, Node_var_array))); + } + ; + break;} +case 45: +#line 414 "./awk.y" +{ + yyval.nodeval = node(yyvsp[0].nodeval, Node_K_for, (NODE *) make_for_loop(yyvsp[-7].nodeval, yyvsp[-5].nodeval, yyvsp[-3].nodeval)); + ; + break;} +case 46: +#line 418 "./awk.y" +{ + yyval.nodeval = node(yyvsp[0].nodeval, Node_K_for, + (NODE *) make_for_loop(yyvsp[-6].nodeval, (NODE *) NULL, yyvsp[-3].nodeval)); + ; + break;} +case 47: +#line 424 "./awk.y" +{ yyval.nodeval = node((NODE *) NULL, Node_K_break, (NODE *) NULL); ; + break;} +case 48: +#line 427 "./awk.y" +{ yyval.nodeval = node((NODE *) NULL, Node_K_continue, (NODE *) NULL); ; + break;} +case 49: +#line 429 "./awk.y" +{ yyval.nodeval = node(yyvsp[-3].nodeval, yyvsp[-5].nodetypeval, yyvsp[-1].nodeval); ; + break;} +case 50: +#line 431 "./awk.y" +{ + if (yyvsp[-3].nodetypeval == Node_K_print && yyvsp[-2].nodeval == NULL) { + static int warned = FALSE; + + yyvsp[-2].nodeval = node(node(make_number(0.0), + Node_field_spec, + (NODE *) NULL), + Node_expression_list, + (NODE *) NULL); + + if (do_lint && ! io_allowed && ! warned) { + warned = TRUE; + warning( + "plain `print' in BEGIN or END rule should probably be `print \"\"'"); + } + } + + yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-3].nodetypeval, yyvsp[-1].nodeval); + ; + break;} +case 51: +#line 451 "./awk.y" +{ NODETYPE type; + + if (yyvsp[-1].nodeval) { + if (yyvsp[-1].nodeval == lookup("file")) { + static int warned = FALSE; + + if (! warned) { + warned = TRUE; + warning("`next file' is obsolete; use `nextfile'"); + } + if (do_lint) + warning("`next file' is a gawk extension"); + if (do_traditional) { + /* + * can't use yyerror, since may have overshot + * the source line + */ + errcount++; + error("`next file' is a gawk extension"); + } + if (! io_allowed) { + /* same thing */ + errcount++; + error("`next file' used in BEGIN or END action"); + } + type = Node_K_nextfile; + } else { + errcount++; + error("illegal expression after `next'"); + type = Node_K_next; /* sanity */ + } + } else { + if (! io_allowed) + yyerror("`next' used in BEGIN or END action"); + type = Node_K_next; + } + yyval.nodeval = node((NODE *) NULL, type, (NODE *) NULL); + ; + break;} +case 52: +#line 490 "./awk.y" +{ + if (do_lint) + warning("`nextfile' is a gawk extension"); + if (do_traditional) { + /* + * can't use yyerror, since may have overshot + * the source line + */ + errcount++; + error("`nextfile' is a gawk extension"); + } + if (! io_allowed) { + /* same thing */ + errcount++; + error("`nextfile' used in BEGIN or END action"); + } + yyval.nodeval = node((NODE *) NULL, Node_K_nextfile, (NODE *) NULL); + ; + break;} +case 53: +#line 509 "./awk.y" +{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_exit, (NODE *) NULL); ; + break;} +case 54: +#line 511 "./awk.y" +{ + if (! can_return) + yyerror("`return' used outside function context"); + ; + break;} +case 55: +#line 516 "./awk.y" +{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_return, (NODE *) NULL); ; + break;} +case 56: +#line 518 "./awk.y" +{ yyval.nodeval = node(variable(yyvsp[-4].sval, CAN_FREE, Node_var_array), Node_K_delete, yyvsp[-2].nodeval); ; + break;} +case 57: +#line 520 "./awk.y" +{ + if (do_lint) + warning("`delete array' is a gawk extension"); + if (do_traditional) { + /* + * can't use yyerror, since may have overshot + * the source line + */ + errcount++; + error("`delete array' is a gawk extension"); + } + yyval.nodeval = node(variable(yyvsp[-1].sval, CAN_FREE, Node_var_array), Node_K_delete, (NODE *) NULL); + ; + break;} +case 58: +#line 534 "./awk.y" +{ yyval.nodeval = yyvsp[-1].nodeval; ; + break;} +case 59: +#line 539 "./awk.y" +{ yyval.nodetypeval = yyvsp[0].nodetypeval; ; + break;} +case 60: +#line 541 "./awk.y" +{ yyval.nodetypeval = yyvsp[0].nodetypeval; ; + break;} +case 61: +#line 546 "./awk.y" +{ + yyval.nodeval = node(yyvsp[-3].nodeval, Node_K_if, + node(yyvsp[0].nodeval, Node_if_branches, (NODE *) NULL)); + ; + break;} +case 62: +#line 552 "./awk.y" +{ yyval.nodeval = node(yyvsp[-6].nodeval, Node_K_if, + node(yyvsp[-3].nodeval, Node_if_branches, yyvsp[0].nodeval)); ; + break;} +case 63: +#line 558 "./awk.y" +{ want_assign = FALSE; ; + break;} +case 67: +#line 569 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 68: +#line 571 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_redirect_input, (NODE *) NULL); ; + break;} +case 69: +#line 576 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 70: +#line 578 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_redirect_output, (NODE *) NULL); ; + break;} +case 71: +#line 580 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_redirect_append, (NODE *) NULL); ; + break;} +case 72: +#line 582 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_redirect_pipe, (NODE *) NULL); ; + break;} +case 73: +#line 587 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 74: +#line 589 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 75: +#line 594 "./awk.y" +{ yyval.nodeval = make_param(yyvsp[0].sval); ; + break;} +case 76: +#line 596 "./awk.y" +{ yyval.nodeval = append_right(yyvsp[-2].nodeval, make_param(yyvsp[0].sval)); yyerrok; ; + break;} +case 77: +#line 598 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 78: +#line 600 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 79: +#line 602 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 80: +#line 608 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 81: +#line 610 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 82: +#line 615 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 83: +#line 617 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 84: +#line 622 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL); ; + break;} +case 85: +#line 624 "./awk.y" +{ + yyval.nodeval = append_right(yyvsp[-2].nodeval, + node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL)); + yyerrok; + ; + break;} +case 86: +#line 630 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 87: +#line 632 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 88: +#line 634 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 89: +#line 636 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 90: +#line 641 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 91: +#line 643 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 92: +#line 648 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL); ; + break;} +case 93: +#line 650 "./awk.y" +{ + yyval.nodeval = append_right(yyvsp[-2].nodeval, + node(yyvsp[0].nodeval, Node_expression_list, (NODE *) NULL)); + yyerrok; + ; + break;} +case 94: +#line 656 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 95: +#line 658 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 96: +#line 660 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 97: +#line 662 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 98: +#line 667 "./awk.y" +{ want_assign = FALSE; ; + break;} +case 99: +#line 669 "./awk.y" +{ + if (do_lint && yyvsp[0].nodeval->type == Node_regex) + warning("Regular expression on left of assignment."); + yyval.nodeval = node(yyvsp[-3].nodeval, yyvsp[-2].nodetypeval, yyvsp[0].nodeval); + ; + break;} +case 100: +#line 675 "./awk.y" +{ yyval.nodeval = node(variable(yyvsp[0].sval, CAN_FREE, Node_var_array), Node_in_array, yyvsp[-3].nodeval); ; + break;} +case 101: +#line 677 "./awk.y" +{ + yyval.nodeval = node(yyvsp[0].nodeval, Node_K_getline, + node(yyvsp[-3].nodeval, Node_redirect_pipein, (NODE *) NULL)); + ; + break;} +case 102: +#line 682 "./awk.y" +{ + if (do_lint && ! io_allowed && yyvsp[0].nodeval == NULL) + warning("non-redirected getline undefined inside BEGIN or END action"); + yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_getline, yyvsp[0].nodeval); + ; + break;} +case 103: +#line 688 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_and, yyvsp[0].nodeval); ; + break;} +case 104: +#line 690 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_or, yyvsp[0].nodeval); ; + break;} +case 105: +#line 692 "./awk.y" +{ + if (yyvsp[-2].nodeval->type == Node_regex) + warning("Regular expression on left of MATCH operator."); + yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, mk_rexp(yyvsp[0].nodeval)); + ; + break;} +case 106: +#line 698 "./awk.y" +{ + yyval.nodeval = yyvsp[0].nodeval; + if (do_lint && tokstart[0] == '*') { + /* possible C comment */ + int n = strlen(tokstart) - 1; + if (tokstart[n] == '*') + warning("regexp looks like a C comment, but is not"); + } + ; + break;} +case 107: +#line 708 "./awk.y" +{ + yyval.nodeval = node(node(make_number(0.0), + Node_field_spec, + (NODE *) NULL), + Node_nomatch, + yyvsp[0].nodeval); + ; + break;} +case 108: +#line 716 "./awk.y" +{ yyval.nodeval = node(variable(yyvsp[0].sval, CAN_FREE, Node_var_array), Node_in_array, yyvsp[-2].nodeval); ; + break;} +case 109: +#line 718 "./awk.y" +{ + if (do_lint && yyvsp[0].nodeval->type == Node_regex) + warning("Regular expression on left of comparison."); + yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, yyvsp[0].nodeval); + ; + break;} +case 110: +#line 724 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_less, yyvsp[0].nodeval); ; + break;} +case 111: +#line 726 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_greater, yyvsp[0].nodeval); ; + break;} +case 112: +#line 728 "./awk.y" +{ yyval.nodeval = node(yyvsp[-4].nodeval, Node_cond_exp, node(yyvsp[-2].nodeval, Node_if_branches, yyvsp[0].nodeval));; + break;} +case 113: +#line 730 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 114: +#line 732 "./awk.y" +{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_concat, yyvsp[0].nodeval); ; + break;} +case 115: +#line 737 "./awk.y" +{ want_assign = FALSE; ; + break;} +case 116: +#line 739 "./awk.y" +{ yyval.nodeval = node(yyvsp[-3].nodeval, yyvsp[-2].nodetypeval, yyvsp[0].nodeval); ; + break;} +case 117: +#line 741 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_and, yyvsp[0].nodeval); ; + break;} +case 118: +#line 743 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_or, yyvsp[0].nodeval); ; + break;} +case 119: +#line 745 "./awk.y" +{ + if (do_lint && ! io_allowed && yyvsp[0].nodeval == NULL) + warning("non-redirected getline undefined inside BEGIN or END action"); + yyval.nodeval = node(yyvsp[-1].nodeval, Node_K_getline, yyvsp[0].nodeval); + ; + break;} +case 120: +#line 751 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 121: +#line 753 "./awk.y" +{ yyval.nodeval = node((NODE *) NULL, Node_nomatch, yyvsp[0].nodeval); ; + break;} +case 122: +#line 755 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, mk_rexp(yyvsp[0].nodeval)); ; + break;} +case 123: +#line 757 "./awk.y" +{ yyval.nodeval = node(variable(yyvsp[0].sval, CAN_FREE, Node_var_array), Node_in_array, yyvsp[-2].nodeval); ; + break;} +case 124: +#line 759 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, yyvsp[-1].nodetypeval, yyvsp[0].nodeval); ; + break;} +case 125: +#line 761 "./awk.y" +{ yyval.nodeval = node(yyvsp[-4].nodeval, Node_cond_exp, node(yyvsp[-2].nodeval, Node_if_branches, yyvsp[0].nodeval));; + break;} +case 126: +#line 763 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 127: +#line 765 "./awk.y" +{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_concat, yyvsp[0].nodeval); ; + break;} +case 129: +#line 772 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_exp, yyvsp[0].nodeval); ; + break;} +case 130: +#line 774 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_times, yyvsp[0].nodeval); ; + break;} +case 131: +#line 776 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_quotient, yyvsp[0].nodeval); ; + break;} +case 132: +#line 778 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_mod, yyvsp[0].nodeval); ; + break;} +case 133: +#line 780 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_plus, yyvsp[0].nodeval); ; + break;} +case 134: +#line 782 "./awk.y" +{ yyval.nodeval = node(yyvsp[-2].nodeval, Node_minus, yyvsp[0].nodeval); ; + break;} +case 135: +#line 784 "./awk.y" +{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_postincrement, (NODE *) NULL); ; + break;} +case 136: +#line 786 "./awk.y" +{ yyval.nodeval = node(yyvsp[-1].nodeval, Node_postdecrement, (NODE *) NULL); ; + break;} +case 137: +#line 791 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_not, (NODE *) NULL); ; + break;} +case 138: +#line 793 "./awk.y" +{ yyval.nodeval = yyvsp[-1].nodeval; ; + break;} +case 139: +#line 796 "./awk.y" +{ yyval.nodeval = snode(yyvsp[-1].nodeval, Node_builtin, (int) yyvsp[-3].lval); ; + break;} +case 140: +#line 798 "./awk.y" +{ yyval.nodeval = snode(yyvsp[-1].nodeval, Node_builtin, (int) yyvsp[-3].lval); ; + break;} +case 141: +#line 800 "./awk.y" +{ + if (do_lint) + warning("call of `length' without parentheses is not portable"); + yyval.nodeval = snode((NODE *) NULL, Node_builtin, (int) yyvsp[0].lval); + if (do_posix) + warning("call of `length' without parentheses is deprecated by POSIX"); + ; + break;} +case 142: +#line 808 "./awk.y" +{ + yyval.nodeval = node(yyvsp[-1].nodeval, Node_func_call, make_string(yyvsp[-3].sval, strlen(yyvsp[-3].sval))); + func_use(yyvsp[-3].sval, FUNC_USE); + param_sanity(yyvsp[-1].nodeval); + free(yyvsp[-3].sval); + ; + break;} +case 144: +#line 816 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_preincrement, (NODE *) NULL); ; + break;} +case 145: +#line 818 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_predecrement, (NODE *) NULL); ; + break;} +case 146: +#line 820 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 147: +#line 822 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 148: +#line 825 "./awk.y" +{ + if (yyvsp[0].nodeval->type == Node_val) { + yyvsp[0].nodeval->numbr = -(force_number(yyvsp[0].nodeval)); + yyval.nodeval = yyvsp[0].nodeval; + } else + yyval.nodeval = node(yyvsp[0].nodeval, Node_unary_minus, (NODE *) NULL); + ; + break;} +case 149: +#line 833 "./awk.y" +{ + /* + * was: $$ = $2 + * POSIX semantics: force a conversion to numeric type + */ + yyval.nodeval = node (make_number(0.0), Node_plus, yyvsp[0].nodeval); + ; + break;} +case 150: +#line 844 "./awk.y" +{ yyval.nodeval = NULL; ; + break;} +case 151: +#line 846 "./awk.y" +{ yyval.nodeval = yyvsp[0].nodeval; ; + break;} +case 152: +#line 851 "./awk.y" +{ yyval.nodeval = variable(yyvsp[0].sval, CAN_FREE, Node_var); ; + break;} +case 153: +#line 853 "./awk.y" +{ + if (yyvsp[-1].nodeval == NULL) { + fatal("invalid subscript expression"); + } else if (yyvsp[-1].nodeval->rnode == NULL) { + yyval.nodeval = node(variable(yyvsp[-3].sval, CAN_FREE, Node_var_array), Node_subscript, yyvsp[-1].nodeval->lnode); + freenode(yyvsp[-1].nodeval); + } else + yyval.nodeval = node(variable(yyvsp[-3].sval, CAN_FREE, Node_var_array), Node_subscript, yyvsp[-1].nodeval); + ; + break;} +case 154: +#line 863 "./awk.y" +{ yyval.nodeval = node(yyvsp[0].nodeval, Node_field_spec, (NODE *) NULL); ; + break;} +case 156: +#line 871 "./awk.y" +{ yyerrok; ; + break;} +case 157: +#line 875 "./awk.y" +{ yyerrok; ; + break;} +case 160: +#line 884 "./awk.y" +{ yyerrok; want_assign = FALSE; ; + break;} +case 161: +#line 887 "./awk.y" +{ yyerrok; ; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 498 "/usr/share/bison.simple" + + yyvsp -= yylen; + yyssp -= yylen; +#ifdef YYLSP_NEEDED + yylsp -= yylen; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + + *++yyvsp = yyval; + +#ifdef YYLSP_NEEDED + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } +#endif + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { + ++yynerrs; + +#ifdef YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (yyn > YYFLAG && yyn < YYLAST) + { + int size = 0; + char *msg; + int x, count; + + count = 0; + /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + size += strlen(yytname[x]) + 15, count++; + msg = (char *) malloc(size + 15); + if (msg != 0) + { + strcpy(msg, "parse error"); + + if (count < 5) + { + count = 0; + for (x = (yyn < 0 ? -yyn : 0); + x < (sizeof(yytname) / sizeof(char *)); x++) + if (yycheck[x + yyn] == x) + { + strcat(msg, count == 0 ? ", expecting `" : " or `"); + strcat(msg, yytname[x]); + strcat(msg, "'"); + count++; + } + } + yyerror(msg); + free(msg); + } + else + yyerror ("parse error; also virtual memory exceeded"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror("parse error"); + } + + goto yyerrlab1; +yyerrlab1: /* here on error raised explicitly by an action */ + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYABORT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); +#endif + + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYABORT; + yyvsp--; + yystate = *--yyssp; +#ifdef YYLSP_NEEDED + yylsp--; +#endif + +#if YYDEBUG != 0 + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now"); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } +#endif + +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + +#if YYDEBUG != 0 + if (yydebug) + fprintf(stderr, "Shifting error token, "); +#endif + + *++yyvsp = yylval; +#ifdef YYLSP_NEEDED + *++yylsp = yylloc; +#endif + + yystate = yyn; + goto yynewstate; +} +#line 890 "./awk.y" + + +struct token { + const char *operator; /* text to match */ + NODETYPE value; /* node type */ + int class; /* lexical class */ + unsigned flags; /* # of args. allowed and compatability */ +# define ARGS 0xFF /* 0, 1, 2, 3 args allowed (any combination */ +# define A(n) (1<<(n)) +# define VERSION 0xFF00 /* old awk is zero */ +# define NOT_OLD 0x0100 /* feature not in old awk */ +# define NOT_POSIX 0x0200 /* feature not in POSIX */ +# define GAWKX 0x0400 /* gawk extension */ +# define RESX 0x0800 /* Bell Labs Research extension */ + NODE *(*ptr)(); /* function that implements this keyword */ +}; + + +/* Tokentab is sorted ascii ascending order, so it can be binary searched. */ +/* Function pointers come from declarations in awk.h. */ + +static struct token tokentab[] = { +{"BEGIN", Node_illegal, LEX_BEGIN, 0, 0}, +{"END", Node_illegal, LEX_END, 0, 0}, +#ifdef ARRAYDEBUG +{"adump", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_adump}, +#endif +#ifdef BITOPS +{"and", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_and}, +#endif /* BITOPS */ +{"atan2", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2}, +{"break", Node_K_break, LEX_BREAK, 0, 0}, +{"close", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_close}, +#ifdef BITOPS +{"compl", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl}, +#endif /* BITOPS */ +{"continue", Node_K_continue, LEX_CONTINUE, 0, 0}, +{"cos", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos}, +{"delete", Node_K_delete, LEX_DELETE, NOT_OLD, 0}, +{"do", Node_K_do, LEX_DO, NOT_OLD, 0}, +{"else", Node_illegal, LEX_ELSE, 0, 0}, +{"exit", Node_K_exit, LEX_EXIT, 0, 0}, +{"exp", Node_builtin, LEX_BUILTIN, A(1), do_exp}, +{"fflush", Node_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush}, +{"for", Node_K_for, LEX_FOR, 0, 0}, +{"func", Node_K_function, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0}, +{"function", Node_K_function, LEX_FUNCTION, NOT_OLD, 0}, +{"gensub", Node_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), do_gensub}, +{"getline", Node_K_getline, LEX_GETLINE, NOT_OLD, 0}, +{"gsub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_gsub}, +{"if", Node_K_if, LEX_IF, 0, 0}, +{"in", Node_illegal, LEX_IN, 0, 0}, +{"index", Node_builtin, LEX_BUILTIN, A(2), do_index}, +{"int", Node_builtin, LEX_BUILTIN, A(1), do_int}, +{"length", Node_builtin, LEX_LENGTH, A(0)|A(1), do_length}, +{"log", Node_builtin, LEX_BUILTIN, A(1), do_log}, +#ifdef BITOPS +{"lshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift}, +#endif /* BITOPS */ +{"match", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_match}, +{"next", Node_K_next, LEX_NEXT, 0, 0}, +{"nextfile", Node_K_nextfile, LEX_NEXTFILE, GAWKX, 0}, +#ifdef BITOPS +{"or", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_or}, +#endif /* BITOPS */ +{"print", Node_K_print, LEX_PRINT, 0, 0}, +{"printf", Node_K_printf, LEX_PRINTF, 0, 0}, +{"rand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand}, +{"return", Node_K_return, LEX_RETURN, NOT_OLD, 0}, +#ifdef BITOPS +{"rshift", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift}, +#endif /* BITOPS */ +{"sin", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin}, +{"split", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_split}, +{"sprintf", Node_builtin, LEX_BUILTIN, 0, do_sprintf}, +{"sqrt", Node_builtin, LEX_BUILTIN, A(1), do_sqrt}, +{"srand", Node_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand}, +#ifdef ARRAYDEBUG +{"stopme", Node_builtin, LEX_BUILTIN, GAWKX|A(0), stopme}, +#endif +{"strftime", Node_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2), do_strftime}, +#ifdef BITOPS +{"strtonum", Node_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum}, +#endif /* BITOPS */ +{"sub", Node_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_sub}, +{"substr", Node_builtin, LEX_BUILTIN, A(2)|A(3), do_substr}, +{"system", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system}, +{"systime", Node_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime}, +{"tolower", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower}, +{"toupper", Node_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper}, +{"while", Node_K_while, LEX_WHILE, 0, 0}, +#ifdef BITOPS +{"xor", Node_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor}, +#endif /* BITOPS */ +}; + +/* yyerror --- print a syntax error message, show where */ + +#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ +static void +yyerror(const char *m, ...) +#else +/* VARARGS0 */ +static void +yyerror(va_alist) +va_dcl +#endif +{ + va_list args; + const char *mesg = NULL; + register char *bp, *cp; + char *scan; + char buf[120]; + static char end_of_file_line[] = "(END OF FILE)"; + + errcount++; + /* Find the current line in the input file */ + if (lexptr && lexeme) { + if (thisline == NULL) { + cp = lexeme; + if (*cp == '\n') { + cp--; + mesg = "unexpected newline"; + } + for (; cp != lexptr_begin && *cp != '\n'; --cp) + continue; + if (*cp == '\n') + cp++; + thisline = cp; + } + /* NL isn't guaranteed */ + bp = lexeme; + while (bp < lexend && *bp && *bp != '\n') + bp++; + } else { + thisline = end_of_file_line; + bp = thisline + strlen(thisline); + } + msg("%.*s", (int) (bp - thisline), thisline); + bp = buf; + cp = buf + sizeof(buf) - 24; /* 24 more than longest msg. input */ + if (lexptr != NULL) { + scan = thisline; + while (bp < cp && scan < lexeme) + if (*scan++ == '\t') + *bp++ = '\t'; + else + *bp++ = ' '; + *bp++ = '^'; + *bp++ = ' '; + } +#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__ + va_start(args, m); + if (mesg == NULL) + mesg = m; +#else + va_start(args); + if (mesg == NULL) + mesg = va_arg(args, char *); +#endif + strcpy(bp, mesg); + err("", buf, args); + va_end(args); +} + +/* get_src_buf --- read the next buffer of source program */ + +static char * +get_src_buf() +{ + static int samefile = FALSE; + static int nextfile = 0; + static char *buf = NULL; + static int fd; + int n; + register char *scan; + static int len = 0; + static int did_newline = FALSE; + int newfile; + struct stat sbuf; + +# define SLOP 128 /* enough space to hold most source lines */ + +again: + newfile = FALSE; + if (nextfile > numfiles) + return NULL; + + if (srcfiles[nextfile].stype == CMDLINE) { + if (len == 0) { + len = strlen(srcfiles[nextfile].val); + if (len == 0) { + /* + * Yet Another Special case: + * gawk '' /path/name + * Sigh. + */ + static int warned = FALSE; + + if (do_lint && ! warned) { + warned = TRUE; + warning("empty program text on command line"); + } + ++nextfile; + goto again; + } + sourceline = 1; + lexptr = lexptr_begin = srcfiles[nextfile].val; + lexend = lexptr + len; + } else if (! did_newline && *(lexptr-1) != '\n') { + /* + * The following goop is to ensure that the source + * ends with a newline and that the entire current + * line is available for error messages. + */ + int offset; + + did_newline = TRUE; + offset = lexptr - lexeme; + for (scan = lexeme; scan > lexptr_begin; scan--) + if (*scan == '\n') { + scan++; + break; + } + len = lexptr - scan; + emalloc(buf, char *, len+1, "get_src_buf"); + memcpy(buf, scan, len); + thisline = buf; + lexptr = buf + len; + *lexptr = '\n'; + lexeme = lexptr - offset; + lexptr_begin = buf; + lexend = lexptr + 1; + } else { + len = 0; + lexeme = lexptr = lexptr_begin = NULL; + } + if (lexptr == NULL && ++nextfile <= numfiles) + goto again; + return lexptr; + } + if (! samefile) { + source = srcfiles[nextfile].val; + if (source == NULL) { + if (buf != NULL) { + free(buf); + buf = NULL; + } + len = 0; + return lexeme = lexptr = lexptr_begin = NULL; + } + fd = pathopen(source); + if (fd <= INVALID_HANDLE) { + char *in; + + /* suppress file name and line no. in error mesg */ + in = source; + source = NULL; + fatal("can't open source file \"%s\" for reading (%s)", + in, strerror(errno)); + } + len = optimal_bufsize(fd, & sbuf); + newfile = TRUE; + if (buf != NULL) + free(buf); + emalloc(buf, char *, len + SLOP, "get_src_buf"); + lexptr_begin = buf + SLOP; + samefile = TRUE; + sourceline = 1; + } else { + /* + * Here, we retain the current source line (up to length SLOP) + * in the beginning of the buffer that was overallocated above + */ + int offset; + int linelen; + + offset = lexptr - lexeme; + for (scan = lexeme; scan > lexptr_begin; scan--) + if (*scan == '\n') { + scan++; + break; + } + linelen = lexptr - scan; + if (linelen > SLOP) + linelen = SLOP; + thisline = buf + SLOP - linelen; + memcpy(thisline, scan, linelen); + lexeme = buf + SLOP - offset; + lexptr_begin = thisline; + } + n = read(fd, buf + SLOP, len); + if (n == -1) + fatal("can't read sourcefile \"%s\" (%s)", + source, strerror(errno)); + if (n == 0) { + if (newfile) { + static int warned = FALSE; + + if (do_lint && ! warned) { + warned = TRUE; + warning("source file `%s' is empty", source); + } + } + if (fileno(stdin) != fd) /* safety */ + close(fd); + samefile = FALSE; + nextfile++; + if (lexeme) + *lexeme = '\0'; + len = 0; + goto again; + } + lexptr = buf + SLOP; + lexend = lexptr + n; + return buf; +} + +/* tokadd --- add a character to the token buffer */ + +#define tokadd(x) (*tok++ = (x), tok == tokend ? tokexpand() : tok) + +/* tokexpand --- grow the token buffer */ + +char * +tokexpand() +{ + static int toksize = 60; + int tokoffset; + + tokoffset = tok - tokstart; + toksize *= 2; + if (tokstart != NULL) + erealloc(tokstart, char *, toksize, "tokexpand"); + else + emalloc(tokstart, char *, toksize, "tokexpand"); + tokend = tokstart + toksize; + tok = tokstart + tokoffset; + return tok; +} + +/* nextc --- get the next input character */ + +#if DEBUG +int +nextc() +{ + int c; + + if (lexptr && lexptr < lexend) + c = (int) (unsigned char) *lexptr++; + else if (get_src_buf()) + c = (int) (unsigned char) *lexptr++; + else + c = EOF; + + return c; +} +#else +#define nextc() ((lexptr && lexptr < lexend) ? \ + ((int) (unsigned char) *lexptr++) : \ + (get_src_buf() ? ((int) (unsigned char) *lexptr++) : EOF) \ + ) +#endif + +/* pushback --- push a character back on the input */ + +#define pushback() (lexptr && lexptr > lexptr_begin ? lexptr-- : lexptr) + +/* allow_newline --- allow newline after &&, ||, ? and : */ + +static void +allow_newline() +{ + int c; + + for (;;) { + c = nextc(); + if (c == EOF) + break; + if (c == '#') { + while ((c = nextc()) != '\n' && c != EOF) + continue; + if (c == EOF) + break; + } + if (c == '\n') + sourceline++; + if (! isspace(c)) { + pushback(); + break; + } + } +} + +/* yylex --- Read the input and turn it into tokens. */ + +static int +yylex() +{ + register int c, c1; + int seen_e = FALSE; /* These are for numbers */ + int seen_point = FALSE; + int esc_seen; /* for literal strings */ + int low, mid, high; + static int did_newline = FALSE; + char *tokkey; + static int lasttok = 0, eof_warned = FALSE; + int inhex = FALSE; + + if (nextc() == EOF) { + if (lasttok != NEWLINE) { + lasttok = NEWLINE; + if (do_lint && ! eof_warned) { + warning("source file does not end in newline"); + eof_warned = TRUE; + } + return NEWLINE; /* fake it */ + } + return 0; + } + pushback(); +#ifdef OS2 + /* + * added for OS/2's extproc feature of cmd.exe + * (like #! in BSD sh) + */ + if (strncasecmp(lexptr, "extproc ", 8) == 0) { + while (*lexptr && *lexptr != '\n') + lexptr++; + } +#endif + lexeme = lexptr; + thisline = NULL; + if (want_regexp) { + int in_brack = 0; /* count brackets, [[:alnum:]] allowed */ + /* + * Counting brackets is non-trivial. [[] is ok, + * and so is [\]], with a point being that /[/]/ as a regexp + * constant has to work. + * + * Do not count [ or ] if either one is preceded by a \. + * A `[' should be counted if + * a) it is the first one so far (in_brack == 0) + * b) it is the `[' in `[:' + * A ']' should be counted if not preceded by a \, since + * it is either closing `:]' or just a plain list. + * According to POSIX, []] is how you put a ] into a set. + * Try to handle that too. + * + * The code for \ handles \[ and \]. + */ + + want_regexp = FALSE; + tok = tokstart; + for (;;) { + c = nextc(); + switch (c) { + case '[': + /* one day check for `.' and `=' too */ + if ((c1 = nextc()) == ':' || in_brack == 0) + in_brack++; + pushback(); + break; + case ']': + if (tokstart[0] == '[' + && (tok == tokstart + 1 + || (tok == tokstart + 2 + && tokstart[1] == '^'))) + /* do nothing */; + else + in_brack--; + break; + case '\\': + if ((c = nextc()) == EOF) { + yyerror("unterminated regexp ends with \\ at end of file"); + return lasttok = REGEXP; /* kludge */ + } else if (c == '\n') { + sourceline++; + continue; + } else { + tokadd('\\'); + tokadd(c); + continue; + } + break; + case '/': /* end of the regexp */ + if (in_brack > 0) + break; + + pushback(); + tokadd('\0'); + yylval.sval = tokstart; + return lasttok = REGEXP; + case '\n': + pushback(); + yyerror("unterminated regexp"); + return lasttok = REGEXP; /* kludge */ + case EOF: + yyerror("unterminated regexp at end of file"); + return lasttok = REGEXP; /* kludge */ + } + tokadd(c); + } + } +retry: + while ((c = nextc()) == ' ' || c == '\t') + continue; + + lexeme = lexptr ? lexptr - 1 : lexptr; + thisline = NULL; + tok = tokstart; + yylval.nodetypeval = Node_illegal; + + switch (c) { + case EOF: + if (lasttok != NEWLINE) { + lasttok = NEWLINE; + if (do_lint && ! eof_warned) { + warning("source file does not end in newline"); + eof_warned = TRUE; + } + return NEWLINE; /* fake it */ + } + return 0; + + case '\n': + sourceline++; + return lasttok = NEWLINE; + + case '#': /* it's a comment */ + while ((c = nextc()) != '\n') { + if (c == EOF) { + if (lasttok != NEWLINE) { + lasttok = NEWLINE; + if (do_lint && ! eof_warned) { + warning( + "source file does not end in newline"); + eof_warned = TRUE; + } + return NEWLINE; /* fake it */ + } + return 0; + } + } + sourceline++; + return lasttok = NEWLINE; + + case '\\': +#ifdef RELAXED_CONTINUATION + /* + * This code puports to allow comments and/or whitespace + * after the `\' at the end of a line used for continuation. + * Use it at your own risk. We think it's a bad idea, which + * is why it's not on by default. + */ + if (! do_traditional) { + /* strip trailing white-space and/or comment */ + while ((c = nextc()) == ' ' || c == '\t') + continue; + if (c == '#') { + if (do_lint) + warning( + "use of `\\ #...' line continuation is not portable"); + while ((c = nextc()) != '\n') + if (c == EOF) + break; + } + pushback(); + } +#endif /* RELAXED_CONTINUATION */ + if (nextc() == '\n') { + sourceline++; + goto retry; + } else { + yyerror("backslash not last character on line"); + exit(1); + } + break; + + case '$': + want_assign = TRUE; + return lasttok = '$'; + + case ':': + case '?': + allow_newline(); + return lasttok = c; + + case ')': + case '(': + case ';': + case '{': + case ',': + want_assign = FALSE; + /* fall through */ + case '[': + case ']': + return lasttok = c; + + case '*': + if ((c = nextc()) == '=') { + yylval.nodetypeval = Node_assign_times; + return lasttok = ASSIGNOP; + } else if (do_posix) { + pushback(); + return lasttok = '*'; + } else if (c == '*') { + /* make ** and **= aliases for ^ and ^= */ + static int did_warn_op = FALSE, did_warn_assgn = FALSE; + + if (nextc() == '=') { + if (do_lint && ! did_warn_assgn) { + did_warn_assgn = TRUE; + warning("**= is not allowed by POSIX"); + warning("operator `**=' is not supported in old awk"); + } + yylval.nodetypeval = Node_assign_exp; + return ASSIGNOP; + } else { + pushback(); + if (do_lint && ! did_warn_op) { + did_warn_op = TRUE; + warning("** is not allowed by POSIX"); + warning("operator `**' is not supported in old awk"); + } + return lasttok = '^'; + } + } + pushback(); + return lasttok = '*'; + + case '/': + if (want_assign) { + if (nextc() == '=') { + yylval.nodetypeval = Node_assign_quotient; + return lasttok = ASSIGNOP; + } + pushback(); + } + return lasttok = '/'; + + case '%': + if (nextc() == '=') { + yylval.nodetypeval = Node_assign_mod; + return lasttok = ASSIGNOP; + } + pushback(); + return lasttok = '%'; + + case '^': + { + static int did_warn_op = FALSE, did_warn_assgn = FALSE; + + if (nextc() == '=') { + if (do_lint && ! did_warn_assgn) { + did_warn_assgn = TRUE; + warning("operator `^=' is not supported in old awk"); + } + yylval.nodetypeval = Node_assign_exp; + return lasttok = ASSIGNOP; + } + pushback(); + if (do_lint && ! did_warn_op) { + did_warn_op = TRUE; + warning("operator `^' is not supported in old awk"); + } + return lasttok = '^'; + } + + case '+': + if ((c = nextc()) == '=') { + yylval.nodetypeval = Node_assign_plus; + return lasttok = ASSIGNOP; + } + if (c == '+') + return lasttok = INCREMENT; + pushback(); + return lasttok = '+'; + + case '!': + if ((c = nextc()) == '=') { + yylval.nodetypeval = Node_notequal; + return lasttok = RELOP; + } + if (c == '~') { + yylval.nodetypeval = Node_nomatch; + want_assign = FALSE; + return lasttok = MATCHOP; + } + pushback(); + return lasttok = '!'; + + case '<': + if (nextc() == '=') { + yylval.nodetypeval = Node_leq; + return lasttok = RELOP; + } + yylval.nodetypeval = Node_less; + pushback(); + return lasttok = '<'; + + case '=': + if (nextc() == '=') { + yylval.nodetypeval = Node_equal; + return lasttok = RELOP; + } + yylval.nodetypeval = Node_assign; + pushback(); + return lasttok = ASSIGNOP; + + case '>': + if ((c = nextc()) == '=') { + yylval.nodetypeval = Node_geq; + return lasttok = RELOP; + } else if (c == '>') { + yylval.nodetypeval = Node_redirect_append; + return lasttok = APPEND_OP; + } + yylval.nodetypeval = Node_greater; + pushback(); + return lasttok = '>'; + + case '~': + yylval.nodetypeval = Node_match; + want_assign = FALSE; + return lasttok = MATCHOP; + + case '}': + /* + * Added did newline stuff. Easier than + * hacking the grammar. + */ + if (did_newline) { + did_newline = FALSE; + return lasttok = c; + } + did_newline++; + --lexptr; /* pick up } next time */ + return lasttok = NEWLINE; + + case '"': + esc_seen = FALSE; + while ((c = nextc()) != '"') { + if (c == '\n') { + pushback(); + yyerror("unterminated string"); + exit(1); + } + if (c == '\\') { + c = nextc(); + if (c == '\n') { + sourceline++; + continue; + } + esc_seen = TRUE; + tokadd('\\'); + } + if (c == EOF) { + pushback(); + yyerror("unterminated string"); + exit(1); + } + tokadd(c); + } + yylval.nodeval = make_str_node(tokstart, + tok - tokstart, esc_seen ? SCAN : 0); + yylval.nodeval->flags |= PERM; + return lasttok = YSTRING; + + case '-': + if ((c = nextc()) == '=') { + yylval.nodetypeval = Node_assign_minus; + return lasttok = ASSIGNOP; + } + if (c == '-') + return lasttok = DECREMENT; + pushback(); + return lasttok = '-'; + + case '.': + c = nextc(); + pushback(); + if (! isdigit(c)) + return lasttok = '.'; + else + c = '.'; + /* FALL THROUGH */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* It's a number */ + for (;;) { + int gotnumber = FALSE; + + tokadd(c); + switch (c) { +#ifdef BITOPS + case 'x': + case 'X': + if (do_traditional) + goto done; + if (tok == tokstart + 2) + inhex = TRUE; + break; +#endif /* BITOTS */ + case '.': + if (seen_point) { + gotnumber = TRUE; + break; + } + seen_point = TRUE; + break; + case 'e': + case 'E': + if (inhex) + break; + if (seen_e) { + gotnumber = TRUE; + break; + } + seen_e = TRUE; + if ((c = nextc()) == '-' || c == '+') + tokadd(c); + else + pushback(); + break; +#ifdef BITOPS + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'D': + case 'd': + case 'f': + case 'F': + if (do_traditional || ! inhex) + goto done; + /* fall through */ +#endif + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + default: + done: + gotnumber = TRUE; + } + if (gotnumber) + break; + c = nextc(); + } + if (c != EOF) + pushback(); + else if (do_lint && ! eof_warned) { + warning("source file does not end in newline"); + eof_warned = TRUE; + } + tokadd('\0'); +#ifdef BITOPS + if (! do_traditional && isnondecimal(tokstart)) + yylval.nodeval = make_number(nondec2awknum(tokstart, strlen(tokstart))); + else +#endif /* BITOPS */ + yylval.nodeval = make_number(atof(tokstart)); + yylval.nodeval->flags |= PERM; + return lasttok = YNUMBER; + + case '&': + if ((c = nextc()) == '&') { + yylval.nodetypeval = Node_and; + allow_newline(); + want_assign = FALSE; + return lasttok = LEX_AND; + } + pushback(); + return lasttok = '&'; + + case '|': + if ((c = nextc()) == '|') { + yylval.nodetypeval = Node_or; + allow_newline(); + want_assign = FALSE; + return lasttok = LEX_OR; + } + pushback(); + return lasttok = '|'; + } + + if (c != '_' && ! isalpha(c)) { + yyerror("Invalid char '%c' in expression\n", c); + exit(1); + } + + /* it's some type of name-type-thing. Find its length. */ + tok = tokstart; + while (is_identchar(c)) { + tokadd(c); + c = nextc(); + } + tokadd('\0'); + emalloc(tokkey, char *, tok - tokstart, "yylex"); + memcpy(tokkey, tokstart, tok - tokstart); + if (c != EOF) + pushback(); + else if (do_lint && ! eof_warned) { + warning("source file does not end in newline"); + eof_warned = TRUE; + } + + /* See if it is a special token. */ + low = 0; + high = (sizeof(tokentab) / sizeof(tokentab[0])) - 1; + while (low <= high) { + int i; + + mid = (low + high) / 2; + c = *tokstart - tokentab[mid].operator[0]; + i = c ? c : strcmp(tokstart, tokentab[mid].operator); + + if (i < 0) /* token < mid */ + high = mid - 1; + else if (i > 0) /* token > mid */ + low = mid + 1; + else { + if (do_lint) { + if (tokentab[mid].flags & GAWKX) + warning("%s() is a gawk extension", + tokentab[mid].operator); + if (tokentab[mid].flags & RESX) + warning("%s() is a Bell Labs extension", + tokentab[mid].operator); + if (tokentab[mid].flags & NOT_POSIX) + warning("POSIX does not allow %s", + tokentab[mid].operator); + } + if (do_lint_old && (tokentab[mid].flags & NOT_OLD)) + warning("%s is not supported in old awk", + tokentab[mid].operator); + if ((do_traditional && (tokentab[mid].flags & GAWKX)) + || (do_posix && (tokentab[mid].flags & NOT_POSIX))) + break; + if (tokentab[mid].class == LEX_BUILTIN + || tokentab[mid].class == LEX_LENGTH + ) + yylval.lval = mid; + else + yylval.nodetypeval = tokentab[mid].value; + + free(tokkey); + return lasttok = tokentab[mid].class; + } + } + + yylval.sval = tokkey; + if (*lexptr == '(') + return lasttok = FUNC_CALL; + else { + want_assign = TRUE; + return lasttok = NAME; + } +} + +/* node_common --- common code for allocating a new node */ + +static NODE * +node_common(op) +NODETYPE op; +{ + register NODE *r; + + getnode(r); + r->type = op; + r->flags = MALLOC; + /* if lookahead is NL, lineno is 1 too high */ + if (lexeme && *lexeme == '\n') + r->source_line = sourceline - 1; + else + r->source_line = sourceline; + r->source_file = source; + return r; +} + +/* node --- allocates a node with defined lnode and rnode. */ + +NODE * +node(left, op, right) +NODE *left, *right; +NODETYPE op; +{ + register NODE *r; + + r = node_common(op); + r->lnode = left; + r->rnode = right; + return r; +} + +/* snode --- allocate a node with defined subnode and proc for builtin + functions. Checks for arg. count and supplies defaults where + possible. */ + +static NODE * +snode(subn, op, idx) +NODETYPE op; +int idx; +NODE *subn; +{ + register NODE *r; + register NODE *n; + int nexp = 0; + int args_allowed; + + r = node_common(op); + + /* traverse expression list to see how many args. given */ + for (n = subn; n != NULL; n = n->rnode) { + nexp++; + if (nexp > 3) + break; + } + + /* check against how many args. are allowed for this builtin */ + args_allowed = tokentab[idx].flags & ARGS; + if (args_allowed && (args_allowed & A(nexp)) == 0) + fatal("%s() cannot have %d argument%c", + tokentab[idx].operator, nexp, nexp == 1 ? ' ' : 's'); + + r->proc = tokentab[idx].ptr; + + /* special case processing for a few builtins */ + /* + * FIXME: go through these to make sure that everything done + * here is really right. Move anything that's not into + * the corresponding routine. + */ + if (nexp == 0 && r->proc == do_length) { + subn = node(node(make_number(0.0), Node_field_spec, (NODE *) NULL), + Node_expression_list, + (NODE *) NULL); + } else if (r->proc == do_match) { + if (subn->rnode->lnode->type != Node_regex) + subn->rnode->lnode = mk_rexp(subn->rnode->lnode); + } else if (r->proc == do_sub || r->proc == do_gsub) { + if (subn->lnode->type != Node_regex) + subn->lnode = mk_rexp(subn->lnode); + if (nexp == 2) + append_right(subn, node(node(make_number(0.0), + Node_field_spec, + (NODE *) NULL), + Node_expression_list, + (NODE *) NULL)); + else if (subn->rnode->rnode->lnode->type == Node_val) { + if (do_lint) + warning("string literal as last arg of substitute"); + } else if (! isassignable(subn->rnode->rnode->lnode)) + yyerror("%s third parameter is not a changeable object", + r->proc == do_sub ? "sub" : "gsub"); + } else if (r->proc == do_gensub) { + if (subn->lnode->type != Node_regex) + subn->lnode = mk_rexp(subn->lnode); + if (nexp == 3) + append_right(subn, node(node(make_number(0.0), + Node_field_spec, + (NODE *) NULL), + Node_expression_list, + (NODE *) NULL)); + } else if (r->proc == do_split) { + if (nexp == 2) + append_right(subn, + node(FS_node, Node_expression_list, (NODE *) NULL)); + n = subn->rnode->rnode->lnode; + if (n->type != Node_regex) + subn->rnode->rnode->lnode = mk_rexp(n); + if (nexp == 2) + subn->rnode->rnode->lnode->re_flags |= FS_DFLT; + } + + r->subnode = subn; + return r; +} + +/* + * mkrangenode: + * This allocates a Node_line_range node with defined condpair and + * zeroes the trigger word to avoid the temptation of assuming that calling + * 'node( foo, Node_line_range, 0)' will properly initialize 'triggered'. + * Otherwise like node(). + */ + +static NODE * +mkrangenode(cpair) +NODE *cpair; +{ + register NODE *r; + + getnode(r); + r->type = Node_line_range; + r->condpair = cpair; + r->triggered = FALSE; + return r; +} + +/* make_for_loop --- build a for loop */ + +static NODE * +make_for_loop(init, cond, incr) +NODE *init, *cond, *incr; +{ + register FOR_LOOP_HEADER *r; + NODE *n; + + emalloc(r, FOR_LOOP_HEADER *, sizeof(FOR_LOOP_HEADER), "make_for_loop"); + getnode(n); + n->type = Node_illegal; + r->init = init; + r->cond = cond; + r->incr = incr; + n->sub.nodep.r.hd = r; + return n; +} + +/* dup_parms --- return TRUE if there are duplicate parameters */ + +static int +dup_parms(func) +NODE *func; +{ + register NODE *np; + char *fname, **names; + int count, i, j, dups; + NODE *params; + + if (func == NULL) /* error earlier */ + return TRUE; + + fname = func->param; + count = func->param_cnt; + params = func->rnode; + + if (count == 0) /* no args, no problem */ + return FALSE; + + if (params == NULL) /* error earlier */ + return TRUE; + + emalloc(names, char **, count * sizeof(char *), "dup_parms"); + + i = 0; + for (np = params; np != NULL; np = np->rnode) { + if (np->param == NULL) { /* error earlier, give up, go home */ + free(names); + return TRUE; + } + names[i++] = np->param; + } + + dups = 0; + for (i = 1; i < count; i++) { + for (j = 0; j < i; j++) { + if (strcmp(names[i], names[j]) == 0) { + dups++; + error( + "function `%s': parameter #%d, `%s', duplicates parameter #%d", + fname, i+1, names[j], j+1); + } + } + } + + free(names); + return (dups > 0 ? TRUE : FALSE); +} + +/* + * install: + * Install a name in the symbol table, even if it is already there. + * Caller must check against redefinition if that is desired. + */ + +NODE * +install(name, value) +char *name; +NODE *value; +{ + register NODE *hp; + register size_t len; + register int bucket; + + len = strlen(name); + bucket = hash(name, len, (unsigned long) HASHSIZE); + getnode(hp); + hp->type = Node_hashnode; + hp->hnext = variables[bucket]; + variables[bucket] = hp; + hp->hlength = len; + hp->hvalue = value; + hp->hname = name; + hp->hvalue->vname = name; + return hp->hvalue; +} + +/* lookup --- find the most recent hash node for name installed by install */ + +NODE * +lookup(name) +const char *name; +{ + register NODE *bucket; + register size_t len; + + len = strlen(name); + for (bucket = variables[hash(name, len, (unsigned long) HASHSIZE)]; + bucket != NULL; bucket = bucket->hnext) + if (bucket->hlength == len && STREQN(bucket->hname, name, len)) + return bucket->hvalue; + + return NULL; +} + +/* + * append_right: + * Add new to the rightmost branch of LIST. This uses n^2 time, so we make + * a simple attempt at optimizing it. + */ + +static NODE * +append_right(list, new) +NODE *list, *new; +{ + register NODE *oldlist; + static NODE *savefront = NULL, *savetail = NULL; + + if (list == NULL || new == NULL) + return list; + + oldlist = list; + if (savefront == oldlist) { + savetail = savetail->rnode = new; + return oldlist; + } else + savefront = oldlist; + while (list->rnode != NULL) + list = list->rnode; + savetail = list->rnode = new; + return oldlist; +} + +/* + * func_install: + * check if name is already installed; if so, it had better have Null value, + * in which case def is added as the value. Otherwise, install name with def + * as value. + */ + +static void +func_install(params, def) +NODE *params; +NODE *def; +{ + NODE *r; + NODE *n; + + /* check for function foo(foo) { ... }. bleh. */ + for (n = params->rnode; n != NULL; n = n->rnode) { + if (strcmp(n->param, params->param) == 0) + fatal("function `%s': can't use function name as parameter name", + params->param); + } + + pop_params(params->rnode); + pop_var(params, FALSE); + r = lookup(params->param); + if (r != NULL) { + fatal("function name `%s' previously defined", params->param); + } else + (void) install(params->param, node(params, Node_func, def)); + + func_use(params->param, FUNC_DEFINE); +} + +/* pop_var --- remove a variable from the symbol table */ + +static void +pop_var(np, freeit) +NODE *np; +int freeit; +{ + register NODE *bucket, **save; + register size_t len; + char *name; + + name = np->param; + len = strlen(name); + save = &(variables[hash(name, len, (unsigned long) HASHSIZE)]); + for (bucket = *save; bucket != NULL; bucket = bucket->hnext) { + if (len == bucket->hlength && STREQN(bucket->hname, name, len)) { + *save = bucket->hnext; + freenode(bucket); + if (freeit) + free(np->param); + return; + } + save = &(bucket->hnext); + } +} + +/* pop_params --- remove list of function parameters from symbol table */ + +/* + * pop parameters out of the symbol table. do this in reverse order to + * avoid reading freed memory if there were duplicated parameters. + */ +static void +pop_params(params) +NODE *params; +{ + if (params == NULL) + return; + pop_params(params->rnode); + pop_var(params, TRUE); +} + +/* make_param --- make NAME into a function parameter */ + +static NODE * +make_param(name) +char *name; +{ + NODE *r; + + getnode(r); + r->type = Node_param_list; + r->rnode = NULL; + r->param = name; + r->param_cnt = param_counter++; + return (install(name, r)); +} + +static struct fdesc { + char *name; + short used; + short defined; + struct fdesc *next; +} *ftable[HASHSIZE]; + +/* func_use --- track uses and definitions of functions */ + +static void +func_use(name, how) +char *name; +enum defref how; +{ + struct fdesc *fp; + int len; + int ind; + + len = strlen(name); + ind = hash(name, len, HASHSIZE); + + for (fp = ftable[ind]; fp != NULL; fp = fp->next) { + if (strcmp(fp->name, name) == 0) { + if (how == FUNC_DEFINE) + fp->defined++; + else + fp->used++; + return; + } + } + + /* not in the table, fall through to allocate a new one */ + + emalloc(fp, struct fdesc *, sizeof(struct fdesc), "func_use"); + memset(fp, '\0', sizeof(struct fdesc)); + emalloc(fp->name, char *, len + 1, "func_use"); + strcpy(fp->name, name); + if (how == FUNC_DEFINE) + fp->defined++; + else + fp->used++; + fp->next = ftable[ind]; + ftable[ind] = fp; +} + +/* check_funcs --- verify functions that are called but not defined */ + +static void +check_funcs() +{ + struct fdesc *fp, *next; + int i; + + for (i = 0; i < HASHSIZE; i++) { + for (fp = ftable[i]; fp != NULL; fp = fp->next) { +#ifdef REALLYMEAN + /* making this the default breaks old code. sigh. */ + if (fp->defined == 0) { + error( + "function `%s' called but never defined", fp->name); + errcount++; + } +#else + if (do_lint && fp->defined == 0) + warning( + "function `%s' called but never defined", fp->name); +#endif + if (do_lint && fp->used == 0) { + warning("function `%s' defined but never called", + fp->name); + } + } + } + + /* now let's free all the memory */ + for (i = 0; i < HASHSIZE; i++) { + for (fp = ftable[i]; fp != NULL; fp = next) { + next = fp->next; + free(fp->name); + free(fp); + } + } +} + +/* param_sanity --- look for parameters that are regexp constants */ + +static void +param_sanity(arglist) +NODE *arglist; +{ + NODE *argp, *arg; + int i; + + for (i = 1, argp = arglist; argp != NULL; argp = argp->rnode, i++) { + arg = argp->lnode; + if (arg->type == Node_regex) + warning("regexp constant for parameter #%d yields boolean value", i); + } +} + +/* variable --- make sure NAME is in the symbol table */ + +NODE * +variable(name, can_free, type) +char *name; +int can_free; +NODETYPE type; +{ + register NODE *r; + static int env_loaded = FALSE; + + if (! env_loaded && STREQ(name, "ENVIRON")) { + load_environ(); + env_loaded = TRUE; + } + if ((r = lookup(name)) == NULL) + r = install(name, node(Nnull_string, type, (NODE *) NULL)); + else if (can_free) + free(name); + return r; +} + +/* mk_rexp --- make a regular expression constant */ + +static NODE * +mk_rexp(exp) +NODE *exp; +{ + NODE *n; + + if (exp->type == Node_regex) + return exp; + + getnode(n); + n->type = Node_regex; + n->re_exp = exp; + n->re_text = NULL; + n->re_reg = NULL; + n->re_flags = 0; + n->re_cnt = 1; + return n; +} + +/* isnoeffect --- when used as a statement, has no side effects */ + +/* + * To be completely general, we should recursively walk the parse + * tree, to make sure that all the subexpressions also have no effect. + * Instead, we just weaken the actual warning that's printed, up above + * in the grammar. + */ + +static int +isnoeffect(type) +NODETYPE type; +{ + switch (type) { + case Node_times: + case Node_quotient: + case Node_mod: + case Node_plus: + case Node_minus: + case Node_subscript: + case Node_concat: + case Node_exp: + case Node_unary_minus: + case Node_field_spec: + case Node_and: + case Node_or: + case Node_equal: + case Node_notequal: + case Node_less: + case Node_greater: + case Node_leq: + case Node_geq: + case Node_match: + case Node_nomatch: + case Node_not: + case Node_val: + case Node_in_array: + case Node_NF: + case Node_NR: + case Node_FNR: + case Node_FS: + case Node_RS: + case Node_FIELDWIDTHS: + case Node_IGNORECASE: + case Node_OFS: + case Node_ORS: + case Node_OFMT: + case Node_CONVFMT: + return TRUE; + default: + break; /* keeps gcc -Wall happy */ + } + + return FALSE; +} + +/* isassignable --- can this node be assigned to? */ + +static int +isassignable(n) +register NODE *n; +{ + switch (n->type) { + case Node_var: + case Node_FIELDWIDTHS: + case Node_RS: + case Node_FS: + case Node_FNR: + case Node_NR: + case Node_NF: + case Node_IGNORECASE: + case Node_OFMT: + case Node_CONVFMT: + case Node_ORS: + case Node_OFS: + case Node_field_spec: + case Node_subscript: + return TRUE; + case Node_param_list: + return ((n->flags & FUNC) == 0); /* ok if not func name */ + default: + break; /* keeps gcc -Wall happy */ + } + return FALSE; +} + +/* for debugging */ +NODE * +stopme(tree) +NODE *tree; +{ + return tmp_number((AWKNUM) 0.0); +} |