1/* $NetBSD: main.c,v 1.7 2018/02/04 09:15:45 mrg Exp $ */ 2 3/* flex - tool to generate fast lexical analyzers */ 4 5/* Copyright (c) 1990 The Regents of the University of California. */ 6/* All rights reserved. */ 7 8/* This code is derived from software contributed to Berkeley by */ 9/* Vern Paxson. */ 10 11/* The United States Government has rights in this work pursuant */ 12/* to contract no. DE-AC03-76SF00098 between the United States */ 13/* Department of Energy and the University of California. */ 14 15/* This file is part of flex. */ 16 17/* Redistribution and use in source and binary forms, with or without */ 18/* modification, are permitted provided that the following conditions */ 19/* are met: */ 20 21/* 1. Redistributions of source code must retain the above copyright */ 22/* notice, this list of conditions and the following disclaimer. */ 23/* 2. Redistributions in binary form must reproduce the above copyright */ 24/* notice, this list of conditions and the following disclaimer in the */ 25/* documentation and/or other materials provided with the distribution. */ 26 27/* Neither the name of the University nor the names of its contributors */ 28/* may be used to endorse or promote products derived from this software */ 29/* without specific prior written permission. */ 30 31/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ 32/* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ 33/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ 34/* PURPOSE. */ 35#include "flexdef.h" 36__RCSID("$NetBSD: main.c,v 1.7 2018/02/04 09:15:45 mrg Exp $"); 37 38 39#include "version.h" 40#include "options.h" 41#include "tables.h" 42#include "parse.h" 43 44static char flex_version[] = FLEX_VERSION; 45 46/* declare functions that have forward references */ 47 48void flexinit(int, char **); 49void readin(void); 50void set_up_initial_allocations(void); 51 52 53/* these globals are all defined and commented in flexdef.h */ 54int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; 55int interactive, lex_compat, posix_compat, do_yylineno, 56 useecs, fulltbl, usemecs; 57int fullspd, gen_line_dirs, performance_report, backing_up_report; 58int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, 59 csize; 60int reentrant, bison_bridge_lval, bison_bridge_lloc; 61int yymore_used, reject, real_reject, continued_action, in_rule; 62int yymore_really_used, reject_really_used; 63int trace_hex = 0; 64int datapos, dataline, linenum; 65FILE *skelfile = NULL; 66int skel_ind = 0; 67char *action_array; 68int action_size, defs1_offset, prolog_offset, action_offset, 69 action_index; 70char *infilename = NULL, *outfilename = NULL, *headerfilename = NULL; 71int did_outfilename; 72char *prefix, *yyclass, *extra_type = NULL; 73int do_stdinit, use_stdout; 74int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; 75int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; 76int maximum_mns, current_mns, current_max_rules; 77int num_rules, num_eof_rules, default_rule, lastnfa; 78int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; 79int *accptnum, *assoc_rule, *state_type; 80int *rule_type, *rule_linenum, *rule_useful; 81int current_state_type; 82int variable_trailing_context_rules; 83int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; 84int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; 85int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, 86 tecfwd[CSIZE + 1]; 87int tecbck[CSIZE + 1]; 88int lastsc, *scset, *scbol, *scxclu, *sceof; 89int current_max_scs; 90char **scname; 91int current_max_dfa_size, current_max_xpairs; 92int current_max_template_xpairs, current_max_dfas; 93int lastdfa, *nxt, *chk, *tnxt; 94int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; 95union dfaacc_union *dfaacc; 96int *accsiz, *dhash, numas; 97int numsnpairs, jambase, jamstate; 98int lastccl, *cclmap, *ccllen, *cclng, cclreuse; 99int current_maxccls, current_max_ccl_tbl_size; 100unsigned char *ccltbl; 101char nmstr[MAXLINE]; 102int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; 103int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; 104int num_backing_up, bol_needed; 105FILE *backing_up_file; 106int end_of_buffer_state; 107char **input_files; 108int num_input_files; 109jmp_buf flex_main_jmp_buf; 110bool *rule_has_nl, *ccl_has_nl; 111int nlch = '\n'; 112 113bool tablesext, tablesverify, gentables; 114char *tablesfilename=0,*tablesname=0; 115struct yytbl_writer tableswr; 116 117/* Make sure program_name is initialized so we don't crash if writing 118 * out an error message before getting the program name from argv[0]. 119 */ 120char *program_name = "flex"; 121 122static const char outfile_template[] = "lex.%s.%s"; 123static const char backing_name[] = "lex.backup"; 124static const char tablesfile_template[] = "lex.%s.tables"; 125 126/* From scan.l */ 127extern FILE* yyout; 128 129static char outfile_path[MAXLINE]; 130static int outfile_created = 0; 131static char *skelname = NULL; 132static int _stdout_closed = 0; /* flag to prevent double-fclose() on stdout. */ 133const char *escaped_qstart = "]]M4_YY_NOOP[M4_YY_NOOP[M4_YY_NOOP[["; 134const char *escaped_qend = "]]M4_YY_NOOP]M4_YY_NOOP]M4_YY_NOOP[["; 135 136/* For debugging. The max number of filters to apply to skeleton. */ 137static int preproc_level = 1000; 138 139int flex_main (int argc, char *argv[]); 140 141int flex_main (int argc, char *argv[]) 142{ 143 int i, exit_status, child_status; 144 145 /* Set a longjmp target. Yes, I know it's a hack, but it gets worse: The 146 * return value of setjmp, if non-zero, is the desired exit code PLUS ONE. 147 * For example, if you want 'main' to return with code '2', then call 148 * longjmp() with an argument of 3. This is because it is invalid to 149 * specify a value of 0 to longjmp. FLEX_EXIT(n) should be used instead of 150 * exit(n); 151 */ 152 exit_status = setjmp (flex_main_jmp_buf); 153 if (exit_status){ 154 if (stdout && !_stdout_closed && !ferror(stdout)){ 155 fflush(stdout); 156 fclose(stdout); 157 } 158 while (wait(&child_status) > 0){ 159 if (!WIFEXITED (child_status) 160 || WEXITSTATUS (child_status) != 0){ 161 /* report an error of a child 162 */ 163 if( exit_status <= 1 ) 164 exit_status = 2; 165 166 } 167 } 168 return exit_status - 1; 169 } 170 171 flexinit (argc, argv); 172 173 readin (); 174 175 skelout (); 176 /* %% [1.5] DFA */ 177 ntod (); 178 179 for (i = 1; i <= num_rules; ++i) 180 if (!rule_useful[i] && i != default_rule) 181 line_warning (_("rule cannot be matched"), 182 rule_linenum[i]); 183 184 if (spprdflt && !reject && rule_useful[default_rule]) 185 line_warning (_ 186 ("-s option given but default rule can be matched"), 187 rule_linenum[default_rule]); 188 189 /* Generate the C state transition tables from the DFA. */ 190 make_tables (); 191 192 /* Note, flexend does not return. It exits with its argument 193 * as status. 194 */ 195 flexend (0); 196 197 return 0; /* keep compilers/lint happy */ 198} 199 200/* Wrapper around flex_main, so flex_main can be built as a library. */ 201int main (int argc, char *argv[]) 202{ 203#if ENABLE_NLS 204#if HAVE_LOCALE_H 205 setlocale (LC_MESSAGES, ""); 206 setlocale (LC_CTYPE, ""); 207 textdomain (PACKAGE); 208 bindtextdomain (PACKAGE, LOCALEDIR); 209#endif 210#endif 211 212 return flex_main (argc, argv); 213} 214 215/* check_options - check user-specified options */ 216 217void check_options (void) 218{ 219 int i; 220 const char * m4 = NULL; 221 222 if (lex_compat) { 223 if (C_plus_plus) 224 flexerror (_("Can't use -+ with -l option")); 225 226 if (fulltbl || fullspd) 227 flexerror (_("Can't use -f or -F with -l option")); 228 229 if (reentrant || bison_bridge_lval) 230 flexerror (_ 231 ("Can't use --reentrant or --bison-bridge with -l option")); 232 233 yytext_is_array = true; 234 do_yylineno = true; 235 use_read = false; 236 } 237 238 239#if 0 240 /* This makes no sense whatsoever. I'm removing it. */ 241 if (do_yylineno) 242 /* This should really be "maintain_backup_tables = true" */ 243 reject_really_used = true; 244#endif 245 246 if (csize == unspecified) { 247 if ((fulltbl || fullspd) && !useecs) 248 csize = DEFAULT_CSIZE; 249 else 250 csize = CSIZE; 251 } 252 253 if (interactive == unspecified) { 254 if (fulltbl || fullspd) 255 interactive = false; 256 else 257 interactive = true; 258 } 259 260 if (fulltbl || fullspd) { 261 if (usemecs) 262 flexerror (_ 263 ("-Cf/-CF and -Cm don't make sense together")); 264 265 if (interactive) 266 flexerror (_("-Cf/-CF and -I are incompatible")); 267 268 if (lex_compat) 269 flexerror (_ 270 ("-Cf/-CF are incompatible with lex-compatibility mode")); 271 272 273 if (fulltbl && fullspd) 274 flexerror (_ 275 ("-Cf and -CF are mutually exclusive")); 276 } 277 278 if (C_plus_plus && fullspd) 279 flexerror (_("Can't use -+ with -CF option")); 280 281 if (C_plus_plus && yytext_is_array) { 282 lwarn (_("%array incompatible with -+ option")); 283 yytext_is_array = false; 284 } 285 286 if (C_plus_plus && (reentrant)) 287 flexerror (_("Options -+ and --reentrant are mutually exclusive.")); 288 289 if (C_plus_plus && bison_bridge_lval) 290 flexerror (_("bison bridge not supported for the C++ scanner.")); 291 292 293 if (useecs) { /* Set up doubly-linked equivalence classes. */ 294 295 /* We loop all the way up to csize, since ecgroup[csize] is 296 * the position used for NUL characters. 297 */ 298 ecgroup[1] = NIL; 299 300 for (i = 2; i <= csize; ++i) { 301 ecgroup[i] = i - 1; 302 nextecm[i - 1] = i; 303 } 304 305 nextecm[csize] = NIL; 306 } 307 308 else { 309 /* Put everything in its own equivalence class. */ 310 for (i = 1; i <= csize; ++i) { 311 ecgroup[i] = i; 312 nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ 313 } 314 } 315 316 if (extra_type) 317 buf_m4_define( &m4defs_buf, "M4_EXTRA_TYPE_DEFS", extra_type); 318 319 if (!use_stdout) { 320 FILE *prev_stdout; 321 322 if (!did_outfilename) { 323 char *suffix; 324 325 if (C_plus_plus) 326 suffix = "cc"; 327 else 328 suffix = "c"; 329 330 snprintf (outfile_path, sizeof(outfile_path), outfile_template, 331 prefix, suffix); 332 333 outfilename = outfile_path; 334 } 335 336 prev_stdout = freopen (outfilename, "w+", stdout); 337 338 if (prev_stdout == NULL) 339 lerr (_("could not create %s"), outfilename); 340 341 outfile_created = 1; 342 } 343 344 345 /* Setup the filter chain. */ 346 output_chain = filter_create_int(NULL, filter_tee_header, headerfilename); 347 if ( !(m4 = getenv("M4"))) { 348 char *slash; 349 m4 = M4; 350 if ((slash = strrchr(M4, '/')) != NULL) { 351 m4 = slash+1; 352 /* break up $PATH */ 353 const char *path = getenv("PATH"); 354 if (!path) { 355 m4 = M4; 356 } else { 357 int m4_length = strlen(m4); 358 do { 359 size_t length = strlen(path); 360 struct stat sbuf; 361 362 const char *endOfDir = strchr(path, ':'); 363 if (!endOfDir) 364 endOfDir = path+length; 365 366 { 367 char *m4_path = calloc(endOfDir-path + 1 + m4_length + 1, 1); 368 369 memcpy(m4_path, path, endOfDir-path); 370 m4_path[endOfDir-path] = '/'; 371 memcpy(m4_path + (endOfDir-path) + 1, m4, m4_length + 1); 372 if (stat(m4_path, &sbuf) == 0 && 373 (S_ISREG(sbuf.st_mode)) && sbuf.st_mode & S_IXUSR) { 374 m4 = m4_path; 375 break; 376 } 377 free(m4_path); 378 } 379 path = endOfDir+1; 380 } while (path[0]); 381 if (!path[0]) 382 m4 = M4; 383 } 384 } 385 } 386 filter_create_ext(output_chain, m4, "-P", 0); 387 filter_create_int(output_chain, filter_fix_linedirs, NULL); 388 389 /* For debugging, only run the requested number of filters. */ 390 if (preproc_level > 0) { 391 filter_truncate(output_chain, preproc_level); 392 filter_apply_chain(output_chain); 393 } 394 yyout = stdout; 395 396 397 /* always generate the tablesverify flag. */ 398 buf_m4_define (&m4defs_buf, "M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0"); 399 if (tablesext) 400 gentables = false; 401 402 if (tablesverify) 403 /* force generation of C tables. */ 404 gentables = true; 405 406 407 if (tablesext) { 408 FILE *tablesout; 409 struct yytbl_hdr hdr; 410 char *pname = 0; 411 size_t nbytes = 0; 412 413 buf_m4_define (&m4defs_buf, "M4_YY_TABLES_EXTERNAL", NULL); 414 415 if (!tablesfilename) { 416 nbytes = strlen (prefix) + strlen (tablesfile_template) + 2; 417 tablesfilename = pname = calloc(nbytes, 1); 418 snprintf (pname, nbytes, tablesfile_template, prefix); 419 } 420 421 if ((tablesout = fopen (tablesfilename, "w")) == NULL) 422 lerr (_("could not create %s"), tablesfilename); 423 free(pname); 424 tablesfilename = 0; 425 426 yytbl_writer_init (&tableswr, tablesout); 427 428 nbytes = strlen (prefix) + strlen ("tables") + 2; 429 tablesname = calloc(nbytes, 1); 430 snprintf (tablesname, nbytes, "%stables", prefix); 431 yytbl_hdr_init (&hdr, flex_version, tablesname); 432 433 if (yytbl_hdr_fwrite (&tableswr, &hdr) <= 0) 434 flexerror (_("could not write tables header")); 435 } 436 437 if (skelname && (skelfile = fopen (skelname, "r")) == NULL) 438 lerr (_("can't open skeleton file %s"), skelname); 439 440 if (reentrant) { 441 buf_m4_define (&m4defs_buf, "M4_YY_REENTRANT", NULL); 442 if (yytext_is_array) 443 buf_m4_define (&m4defs_buf, "M4_YY_TEXT_IS_ARRAY", NULL); 444 } 445 446 if ( bison_bridge_lval) 447 buf_m4_define (&m4defs_buf, "M4_YY_BISON_LVAL", NULL); 448 449 if ( bison_bridge_lloc) 450 buf_m4_define (&m4defs_buf, "<M4_YY_BISON_LLOC>", NULL); 451 452 if (strchr(prefix, '[') || strchr(prefix, ']')) 453 flexerror(_("Prefix cannot include '[' or ']'")); 454 buf_m4_define(&m4defs_buf, "M4_YY_PREFIX", prefix); 455 456 if (did_outfilename) 457 line_directive_out (stdout, 0); 458 459 if (do_yylineno) 460 buf_m4_define (&m4defs_buf, "M4_YY_USE_LINENO", NULL); 461 462 /* Create the alignment type. */ 463 buf_strdefine (&userdef_buf, "YY_INT_ALIGNED", 464 long_align ? "long int" : "short int"); 465 466 /* Define the start condition macros. */ 467 { 468 struct Buf tmpbuf; 469 buf_init(&tmpbuf, sizeof(char)); 470 for (i = 1; i <= lastsc; i++) { 471 char *str, *fmt = "#define %s %d\n"; 472 size_t strsz; 473 474 strsz = strlen(fmt) + strlen(scname[i]) + (size_t)(1 + ceil (log10(i))) + 2; 475 str = malloc(strsz); 476 if (!str) 477 flexfatal(_("allocation of macro definition failed")); 478 snprintf(str, strsz, fmt, scname[i], i - 1); 479 buf_strappend(&tmpbuf, str); 480 free(str); 481 } 482 buf_m4_define(&m4defs_buf, "M4_YY_SC_DEFS", tmpbuf.elts); 483 buf_destroy(&tmpbuf); 484 } 485 486 /* This is where we begin writing to the file. */ 487 488 /* Dump the %top code. */ 489 if( top_buf.elts) 490 outn((char*) top_buf.elts); 491 492 /* Dump the m4 definitions. */ 493 buf_print_strings(&m4defs_buf, stdout); 494 m4defs_buf.nelts = 0; /* memory leak here. */ 495 496 /* Place a bogus line directive, it will be fixed in the filter. */ 497 if (gen_line_dirs) 498 outn("#line 0 \"M4_YY_OUTFILE_NAME\"\n"); 499 500 /* Dump the user defined preproc directives. */ 501 if (userdef_buf.elts) 502 outn ((char *) (userdef_buf.elts)); 503 504 skelout (); 505 /* %% [1.0] */ 506} 507 508/* flexend - terminate flex 509 * 510 * note 511 * This routine does not return. 512 */ 513 514void flexend (int exit_status) 515{ 516 static int called_before = -1; /* prevent infinite recursion. */ 517 int tblsiz; 518 519 if (++called_before) 520 FLEX_EXIT (exit_status); 521 522 if (skelfile != NULL) { 523 if (ferror (skelfile)) 524 lerr (_("input error reading skeleton file %s"), 525 skelname); 526 527 else if (fclose (skelfile)) 528 lerr (_("error closing skeleton file %s"), 529 skelname); 530 } 531 532#if 0 533 fprintf (header_out, 534 "#ifdef YY_HEADER_EXPORT_START_CONDITIONS\n"); 535 fprintf (header_out, 536 "/* Beware! Start conditions are not prefixed. */\n"); 537 538 /* Special case for "INITIAL" */ 539 fprintf (header_out, 540 "#undef INITIAL\n#define INITIAL 0\n"); 541 for (i = 2; i <= lastsc; i++) 542 fprintf (header_out, "#define %s %d\n", scname[i], i - 1); 543 fprintf (header_out, 544 "#endif /* YY_HEADER_EXPORT_START_CONDITIONS */\n\n"); 545 546 /* Kill ALL flex-related macros. This is so the user 547 * can #include more than one generated header file. */ 548 fprintf (header_out, "#ifndef YY_HEADER_NO_UNDEFS\n"); 549 fprintf (header_out, 550 "/* Undefine all internal macros, etc., that do no belong in the header. */\n\n"); 551 552 { 553 const char * undef_list[] = { 554 555 "BEGIN", 556 "ECHO", 557 "EOB_ACT_CONTINUE_SCAN", 558 "EOB_ACT_END_OF_FILE", 559 "EOB_ACT_LAST_MATCH", 560 "FLEX_SCANNER", 561 "REJECT", 562 "YYFARGS0", 563 "YYFARGS1", 564 "YYFARGS2", 565 "YYFARGS3", 566 "YYLMAX", 567 "YYSTATE", 568 "YY_AT_BOL", 569 "YY_BREAK", 570 "YY_BUFFER_EOF_PENDING", 571 "YY_BUFFER_NEW", 572 "YY_BUFFER_NORMAL", 573 "YY_BUF_SIZE", 574 "M4_YY_CALL_LAST_ARG", 575 "M4_YY_CALL_ONLY_ARG", 576 "YY_CURRENT_BUFFER", 577 "YY_DECL", 578 "M4_YY_DECL_LAST_ARG", 579 "M4_YY_DEF_LAST_ARG", 580 "M4_YY_DEF_ONLY_ARG", 581 "YY_DO_BEFORE_ACTION", 582 "YY_END_OF_BUFFER", 583 "YY_END_OF_BUFFER_CHAR", 584 "YY_EXIT_FAILURE", 585 "YY_EXTRA_TYPE", 586 "YY_FATAL_ERROR", 587 "YY_FLEX_DEFINED_ECHO", 588 "YY_FLEX_LEX_COMPAT", 589 "YY_FLEX_MAJOR_VERSION", 590 "YY_FLEX_MINOR_VERSION", 591 "YY_FLEX_SUBMINOR_VERSION", 592 "YY_FLUSH_BUFFER", 593 "YY_G", 594 "YY_INPUT", 595 "YY_INTERACTIVE", 596 "YY_INT_ALIGNED", 597 "YY_LAST_ARG", 598 "YY_LESS_LINENO", 599 "YY_LEX_ARGS", 600 "YY_LEX_DECLARATION", 601 "YY_LEX_PROTO", 602 "YY_MAIN", 603 "YY_MORE_ADJ", 604 "YY_NEED_STRLEN", 605 "YY_NEW_FILE", 606 "YY_NULL", 607 "YY_NUM_RULES", 608 "YY_ONLY_ARG", 609 "YY_PARAMS", 610 "YY_PROTO", 611 "M4_YY_PROTO_LAST_ARG", 612 "M4_YY_PROTO_ONLY_ARG void", 613 "YY_READ_BUF_SIZE", 614 "YY_REENTRANT", 615 "YY_RESTORE_YY_MORE_OFFSET", 616 "YY_RULE_SETUP", 617 "YY_SC_TO_UI", 618 "YY_SKIP_YYWRAP", 619 "YY_START", 620 "YY_START_STACK_INCR", 621 "YY_STATE_EOF", 622 "YY_STDINIT", 623 "YY_TRAILING_HEAD_MASK", 624 "YY_TRAILING_MASK", 625 "YY_USER_ACTION", 626 "YY_USE_CONST", 627 "YY_USE_PROTOS", 628 "unput", 629 "yyTABLES_NAME", 630 "yy_create_buffer", 631 "yy_delete_buffer", 632 "yy_flex_debug", 633 "yy_flush_buffer", 634 "yy_init_buffer", 635 "yy_load_buffer_state", 636 "yy_new_buffer", 637 "yy_scan_buffer", 638 "yy_scan_bytes", 639 "yy_scan_string", 640 "yy_set_bol", 641 "yy_set_interactive", 642 "yy_switch_to_buffer", 643 "yypush_buffer_state", 644 "yypop_buffer_state", 645 "yyensure_buffer_stack", 646 "yyalloc", 647 "const", 648 "yyextra", 649 "yyfree", 650 "yyget_debug", 651 "yyget_extra", 652 "yyget_in", 653 "yyget_leng", 654 "yyget_lineno", 655 "yyget_lloc", 656 "yyget_lval", 657 "yyget_out", 658 "yyget_text", 659 "yyin", 660 "yyleng", 661 "yyless", 662 "yylex", 663 "yylex_destroy", 664 "yylex_init", 665 "yylex_init_extra", 666 "yylineno", 667 "yylloc", 668 "yylval", 669 "yymore", 670 "yyout", 671 "yyrealloc", 672 "yyrestart", 673 "yyset_debug", 674 "yyset_extra", 675 "yyset_in", 676 "yyset_lineno", 677 "yyset_lloc", 678 "yyset_lval", 679 "yyset_out", 680 "yytables_destroy", 681 "yytables_fload", 682 "yyterminate", 683 "yytext", 684 "yytext_ptr", 685 "yywrap", 686 687 /* must be null-terminated */ 688 NULL}; 689 690 691 for (i=0; undef_list[i] != NULL; i++) 692 fprintf (header_out, "#undef %s\n", undef_list[i]); 693 } 694 695 /* undef any of the auto-generated symbols. */ 696 for (i = 0; i < defs_buf.nelts; i++) { 697 698 /* don't undef start conditions */ 699 if (sclookup (((char **) defs_buf.elts)[i]) > 0) 700 continue; 701 fprintf (header_out, "#undef %s\n", 702 ((char **) defs_buf.elts)[i]); 703 } 704 705 fprintf (header_out, 706 "#endif /* !YY_HEADER_NO_UNDEFS */\n"); 707 fprintf (header_out, "\n"); 708 fprintf (header_out, "#undef %sIN_HEADER\n", prefix); 709 fprintf (header_out, "#endif /* %sHEADER_H */\n", prefix); 710 711 if (ferror (header_out)) 712 lerr (_("error creating header file %s"), 713 headerfilename); 714 fflush (header_out); 715 fclose (header_out); 716#endif 717 718 if (exit_status != 0 && outfile_created) { 719 if (ferror (stdout)) 720 lerr (_("error writing output file %s"), 721 outfilename); 722 723 else if ((_stdout_closed = 1) && fclose (stdout)) 724 lerr (_("error closing output file %s"), 725 outfilename); 726 727 else if (unlink (outfilename)) 728 lerr (_("error deleting output file %s"), 729 outfilename); 730 } 731 732 733 if (backing_up_report && backing_up_file) { 734 if (num_backing_up == 0) 735 fprintf (backing_up_file, _("No backing up.\n")); 736 else if (fullspd || fulltbl) 737 fprintf (backing_up_file, 738 _ 739 ("%d backing up (non-accepting) states.\n"), 740 num_backing_up); 741 else 742 fprintf (backing_up_file, 743 _("Compressed tables always back up.\n")); 744 745 if (ferror (backing_up_file)) 746 lerr (_("error writing backup file %s"), 747 backing_name); 748 749 else if (fclose (backing_up_file)) 750 lerr (_("error closing backup file %s"), 751 backing_name); 752 } 753 754 if (printstats) { 755 fprintf (stderr, _("%s version %s usage statistics:\n"), 756 program_name, flex_version); 757 758 fprintf (stderr, _(" scanner options: -")); 759 760 if (C_plus_plus) 761 putc ('+', stderr); 762 if (backing_up_report) 763 putc ('b', stderr); 764 if (ddebug) 765 putc ('d', stderr); 766 if (sf_case_ins()) 767 putc ('i', stderr); 768 if (lex_compat) 769 putc ('l', stderr); 770 if (posix_compat) 771 putc ('X', stderr); 772 if (performance_report > 0) 773 putc ('p', stderr); 774 if (performance_report > 1) 775 putc ('p', stderr); 776 if (spprdflt) 777 putc ('s', stderr); 778 if (reentrant) 779 fputs ("--reentrant", stderr); 780 if (bison_bridge_lval) 781 fputs ("--bison-bridge", stderr); 782 if (bison_bridge_lloc) 783 fputs ("--bison-locations", stderr); 784 if (use_stdout) 785 putc ('t', stderr); 786 if (printstats) 787 putc ('v', stderr); /* always true! */ 788 if (nowarn) 789 putc ('w', stderr); 790 if (interactive == false) 791 putc ('B', stderr); 792 if (interactive == true) 793 putc ('I', stderr); 794 if (!gen_line_dirs) 795 putc ('L', stderr); 796 if (trace) 797 putc ('T', stderr); 798 799 if (csize == unspecified) 800 /* We encountered an error fairly early on, so csize 801 * never got specified. Define it now, to prevent 802 * bogus table sizes being written out below. 803 */ 804 csize = 256; 805 806 if (csize == 128) 807 putc ('7', stderr); 808 else 809 putc ('8', stderr); 810 811 fprintf (stderr, " -C"); 812 813 if (long_align) 814 putc ('a', stderr); 815 if (fulltbl) 816 putc ('f', stderr); 817 if (fullspd) 818 putc ('F', stderr); 819 if (useecs) 820 putc ('e', stderr); 821 if (usemecs) 822 putc ('m', stderr); 823 if (use_read) 824 putc ('r', stderr); 825 826 if (did_outfilename) 827 fprintf (stderr, " -o%s", outfilename); 828 829 if (skelname) 830 fprintf (stderr, " -S%s", skelname); 831 832 if (strcmp (prefix, "yy")) 833 fprintf (stderr, " -P%s", prefix); 834 835 putc ('\n', stderr); 836 837 fprintf (stderr, _(" %d/%d NFA states\n"), 838 lastnfa, current_mns); 839 fprintf (stderr, _(" %d/%d DFA states (%d words)\n"), 840 lastdfa, current_max_dfas, totnst); 841 fprintf (stderr, _(" %d rules\n"), 842 num_rules + num_eof_rules - 843 1 /* - 1 for def. rule */ ); 844 845 if (num_backing_up == 0) 846 fprintf (stderr, _(" No backing up\n")); 847 else if (fullspd || fulltbl) 848 fprintf (stderr, 849 _ 850 (" %d backing-up (non-accepting) states\n"), 851 num_backing_up); 852 else 853 fprintf (stderr, 854 _ 855 (" Compressed tables always back-up\n")); 856 857 if (bol_needed) 858 fprintf (stderr, 859 _(" Beginning-of-line patterns used\n")); 860 861 fprintf (stderr, _(" %d/%d start conditions\n"), lastsc, 862 current_max_scs); 863 fprintf (stderr, 864 _ 865 (" %d epsilon states, %d double epsilon states\n"), 866 numeps, eps2); 867 868 if (lastccl == 0) 869 fprintf (stderr, _(" no character classes\n")); 870 else 871 fprintf (stderr, 872 _ 873 (" %d/%d character classes needed %d/%d words of storage, %d reused\n"), 874 lastccl, current_maxccls, 875 cclmap[lastccl] + ccllen[lastccl], 876 current_max_ccl_tbl_size, cclreuse); 877 878 fprintf (stderr, _(" %d state/nextstate pairs created\n"), 879 numsnpairs); 880 fprintf (stderr, 881 _(" %d/%d unique/duplicate transitions\n"), 882 numuniq, numdup); 883 884 if (fulltbl) { 885 tblsiz = lastdfa * numecs; 886 fprintf (stderr, _(" %d table entries\n"), 887 tblsiz); 888 } 889 890 else { 891 tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend; 892 893 fprintf (stderr, 894 _(" %d/%d base-def entries created\n"), 895 lastdfa + numtemps, current_max_dfas); 896 fprintf (stderr, 897 _ 898 (" %d/%d (peak %d) nxt-chk entries created\n"), 899 tblend, current_max_xpairs, peakpairs); 900 fprintf (stderr, 901 _ 902 (" %d/%d (peak %d) template nxt-chk entries created\n"), 903 numtemps * nummecs, 904 current_max_template_xpairs, 905 numtemps * numecs); 906 fprintf (stderr, _(" %d empty table entries\n"), 907 nummt); 908 fprintf (stderr, _(" %d protos created\n"), 909 numprots); 910 fprintf (stderr, 911 _(" %d templates created, %d uses\n"), 912 numtemps, tmpuses); 913 } 914 915 if (useecs) { 916 tblsiz = tblsiz + csize; 917 fprintf (stderr, 918 _ 919 (" %d/%d equivalence classes created\n"), 920 numecs, csize); 921 } 922 923 if (usemecs) { 924 tblsiz = tblsiz + numecs; 925 fprintf (stderr, 926 _ 927 (" %d/%d meta-equivalence classes created\n"), 928 nummecs, csize); 929 } 930 931 fprintf (stderr, 932 _ 933 (" %d (%d saved) hash collisions, %d DFAs equal\n"), 934 hshcol, hshsave, dfaeql); 935 fprintf (stderr, _(" %d sets of reallocations needed\n"), 936 num_reallocs); 937 fprintf (stderr, _(" %d total table entries needed\n"), 938 tblsiz); 939 } 940 941 FLEX_EXIT (exit_status); 942} 943 944 945/* flexinit - initialize flex */ 946 947void flexinit (int argc, char **argv) 948{ 949 int i, sawcmpflag, rv, optind; 950 char *arg; 951 scanopt_t sopt; 952 953 printstats = syntaxerror = trace = spprdflt = false; 954 lex_compat = posix_compat = C_plus_plus = backing_up_report = 955 ddebug = fulltbl = false; 956 fullspd = long_align = nowarn = yymore_used = continued_action = 957 false; 958 do_yylineno = yytext_is_array = in_rule = reject = do_stdinit = 959 false; 960 yymore_really_used = reject_really_used = unspecified; 961 interactive = csize = unspecified; 962 do_yywrap = gen_line_dirs = usemecs = useecs = true; 963 reentrant = bison_bridge_lval = bison_bridge_lloc = false; 964 performance_report = 0; 965 did_outfilename = 0; 966 prefix = "yy"; 967 yyclass = 0; 968 use_read = use_stdout = false; 969 tablesext = tablesverify = false; 970 gentables = true; 971 tablesfilename = tablesname = NULL; 972 973 sawcmpflag = false; 974 975 /* Initialize dynamic array for holding the rule actions. */ 976 action_size = 2048; /* default size of action array in bytes */ 977 action_array = allocate_character_array (action_size); 978 defs1_offset = prolog_offset = action_offset = action_index = 0; 979 action_array[0] = '\0'; 980 981 /* Initialize any buffers. */ 982 buf_init (&userdef_buf, sizeof (char)); /* one long string */ 983 buf_init (&defs_buf, sizeof (char *)); /* list of strings */ 984 buf_init (&yydmap_buf, sizeof (char)); /* one long string */ 985 buf_init (&top_buf, sizeof (char)); /* one long string */ 986 987 { 988 const char * m4defs_init_str[] = {"m4_changequote\n", 989 "m4_changequote([[, ]])\n"}; 990 buf_init (&m4defs_buf, sizeof (char *)); 991 buf_append (&m4defs_buf, &m4defs_init_str, 2); 992 } 993 994 sf_init (); 995 996 /* initialize regex lib */ 997 flex_init_regex(); 998 999 /* Enable C++ if program name ends with '+'. */ 1000 program_name = basename (argv[0]); 1001 1002 if (program_name != NULL && 1003 program_name[strlen (program_name) - 1] == '+') 1004 C_plus_plus = true; 1005 1006 /* read flags */ 1007 sopt = scanopt_init (flexopts, argc, argv, 0); 1008 if (!sopt) { 1009 /* This will only happen when flexopts array is altered. */ 1010 fprintf (stderr, 1011 _("Internal error. flexopts are malformed.\n")); 1012 FLEX_EXIT (1); 1013 } 1014 1015 while ((rv = scanopt (sopt, &arg, &optind)) != 0) { 1016 1017 if (rv < 0) { 1018 /* Scanopt has already printed an option-specific error message. */ 1019 fprintf (stderr, 1020 _ 1021 ("Try `%s --help' for more information.\n"), 1022 program_name); 1023 FLEX_EXIT (1); 1024 } 1025 1026 switch ((enum flexopt_flag_t) rv) { 1027 case OPT_CPLUSPLUS: 1028 C_plus_plus = true; 1029 break; 1030 1031 case OPT_BATCH: 1032 interactive = false; 1033 break; 1034 1035 case OPT_BACKUP: 1036 backing_up_report = true; 1037 break; 1038 1039 case OPT_DONOTHING: 1040 break; 1041 1042 case OPT_COMPRESSION: 1043 if (!sawcmpflag) { 1044 useecs = false; 1045 usemecs = false; 1046 fulltbl = false; 1047 sawcmpflag = true; 1048 } 1049 1050 for (i = 0; arg && arg[i] != '\0'; i++) 1051 switch (arg[i]) { 1052 case 'a': 1053 long_align = true; 1054 break; 1055 1056 case 'e': 1057 useecs = true; 1058 break; 1059 1060 case 'F': 1061 fullspd = true; 1062 break; 1063 1064 case 'f': 1065 fulltbl = true; 1066 break; 1067 1068 case 'm': 1069 usemecs = true; 1070 break; 1071 1072 case 'r': 1073 use_read = true; 1074 break; 1075 1076 default: 1077 lerr (_ 1078 ("unknown -C option '%c'"), 1079 arg[i]); 1080 break; 1081 } 1082 break; 1083 1084 case OPT_DEBUG: 1085 ddebug = true; 1086 break; 1087 1088 case OPT_NO_DEBUG: 1089 ddebug = false; 1090 break; 1091 1092 case OPT_FULL: 1093 useecs = usemecs = false; 1094 use_read = fulltbl = true; 1095 break; 1096 1097 case OPT_FAST: 1098 useecs = usemecs = false; 1099 use_read = fullspd = true; 1100 break; 1101 1102 case OPT_HELP: 1103 usage (); 1104 FLEX_EXIT (0); 1105 1106 case OPT_INTERACTIVE: 1107 interactive = true; 1108 break; 1109 1110 case OPT_CASE_INSENSITIVE: 1111 sf_set_case_ins(true); 1112 break; 1113 1114 case OPT_LEX_COMPAT: 1115 lex_compat = true; 1116 break; 1117 1118 case OPT_POSIX_COMPAT: 1119 posix_compat = true; 1120 break; 1121 1122 case OPT_PREPROC_LEVEL: 1123 preproc_level = (int) strtol(arg,NULL,0); 1124 break; 1125 1126 case OPT_MAIN: 1127 buf_strdefine (&userdef_buf, "YY_MAIN", "1"); 1128 do_yywrap = false; 1129 break; 1130 1131 case OPT_NO_MAIN: 1132 buf_strdefine (&userdef_buf, "YY_MAIN", "0"); 1133 break; 1134 1135 case OPT_NO_LINE: 1136 gen_line_dirs = false; 1137 break; 1138 1139 case OPT_OUTFILE: 1140 outfilename = arg; 1141 did_outfilename = 1; 1142 break; 1143 1144 case OPT_PREFIX: 1145 prefix = arg; 1146 break; 1147 1148 case OPT_PERF_REPORT: 1149 ++performance_report; 1150 break; 1151 1152 case OPT_BISON_BRIDGE: 1153 bison_bridge_lval = true; 1154 break; 1155 1156 case OPT_BISON_BRIDGE_LOCATIONS: 1157 bison_bridge_lval = bison_bridge_lloc = true; 1158 break; 1159 1160 case OPT_REENTRANT: 1161 reentrant = true; 1162 break; 1163 1164 case OPT_NO_REENTRANT: 1165 reentrant = false; 1166 break; 1167 1168 case OPT_SKEL: 1169 skelname = arg; 1170 break; 1171 1172 case OPT_DEFAULT: 1173 spprdflt = false; 1174 break; 1175 1176 case OPT_NO_DEFAULT: 1177 spprdflt = true; 1178 break; 1179 1180 case OPT_STDOUT: 1181 use_stdout = true; 1182 break; 1183 1184 case OPT_NO_UNISTD_H: 1185 //buf_strdefine (&userdef_buf, "YY_NO_UNISTD_H", "1"); 1186 buf_m4_define( &m4defs_buf, "M4_YY_NO_UNISTD_H",0); 1187 break; 1188 1189 case OPT_TABLES_FILE: 1190 tablesext = true; 1191 tablesfilename = arg; 1192 break; 1193 1194 case OPT_TABLES_VERIFY: 1195 tablesverify = true; 1196 break; 1197 1198 case OPT_TRACE: 1199 trace = true; 1200 break; 1201 1202 case OPT_VERBOSE: 1203 printstats = true; 1204 break; 1205 1206 case OPT_VERSION: 1207 printf (_("%s %s\n"), program_name, flex_version); 1208 FLEX_EXIT (0); 1209 1210 case OPT_WARN: 1211 nowarn = false; 1212 break; 1213 1214 case OPT_NO_WARN: 1215 nowarn = true; 1216 break; 1217 1218 case OPT_7BIT: 1219 csize = 128; 1220 break; 1221 1222 case OPT_8BIT: 1223 csize = CSIZE; 1224 break; 1225 1226 case OPT_ALIGN: 1227 long_align = true; 1228 break; 1229 1230 case OPT_NO_ALIGN: 1231 long_align = false; 1232 break; 1233 1234 case OPT_ALWAYS_INTERACTIVE: 1235 buf_m4_define (&m4defs_buf, "M4_YY_ALWAYS_INTERACTIVE", 0); 1236 break; 1237 1238 case OPT_NEVER_INTERACTIVE: 1239 buf_m4_define( &m4defs_buf, "M4_YY_NEVER_INTERACTIVE", 0); 1240 break; 1241 1242 case OPT_ARRAY: 1243 yytext_is_array = true; 1244 break; 1245 1246 case OPT_POINTER: 1247 yytext_is_array = false; 1248 break; 1249 1250 case OPT_ECS: 1251 useecs = true; 1252 break; 1253 1254 case OPT_NO_ECS: 1255 useecs = false; 1256 break; 1257 1258 case OPT_HEADER_FILE: 1259 headerfilename = arg; 1260 break; 1261 1262 case OPT_META_ECS: 1263 usemecs = true; 1264 break; 1265 1266 case OPT_NO_META_ECS: 1267 usemecs = false; 1268 break; 1269 1270 case OPT_PREPROCDEFINE: 1271 { 1272 /* arg is "symbol" or "symbol=definition". */ 1273 char *def; 1274 1275 for (def = arg; 1276 *def != '\0' && *def != '='; ++def) ; 1277 1278 buf_strappend (&userdef_buf, "#define "); 1279 if (*def == '\0') { 1280 buf_strappend (&userdef_buf, arg); 1281 buf_strappend (&userdef_buf, 1282 " 1\n"); 1283 } 1284 else { 1285 buf_strnappend (&userdef_buf, arg, 1286 (int) (def - arg)); 1287 buf_strappend (&userdef_buf, " "); 1288 buf_strappend (&userdef_buf, 1289 def + 1); 1290 buf_strappend (&userdef_buf, "\n"); 1291 } 1292 } 1293 break; 1294 1295 case OPT_READ: 1296 use_read = true; 1297 break; 1298 1299 case OPT_STACK: 1300 //buf_strdefine (&userdef_buf, "YY_STACK_USED", "1"); 1301 buf_m4_define( &m4defs_buf, "M4_YY_STACK_USED",0); 1302 break; 1303 1304 case OPT_STDINIT: 1305 do_stdinit = true; 1306 break; 1307 1308 case OPT_NO_STDINIT: 1309 do_stdinit = false; 1310 break; 1311 1312 case OPT_YYCLASS: 1313 yyclass = arg; 1314 break; 1315 1316 case OPT_YYLINENO: 1317 do_yylineno = true; 1318 break; 1319 1320 case OPT_NO_YYLINENO: 1321 do_yylineno = false; 1322 break; 1323 1324 case OPT_YYWRAP: 1325 do_yywrap = true; 1326 break; 1327 1328 case OPT_NO_YYWRAP: 1329 do_yywrap = false; 1330 break; 1331 1332 case OPT_YYMORE: 1333 yymore_really_used = true; 1334 break; 1335 1336 case OPT_NO_YYMORE: 1337 yymore_really_used = false; 1338 break; 1339 1340 case OPT_REJECT: 1341 reject_really_used = true; 1342 break; 1343 1344 case OPT_NO_REJECT: 1345 reject_really_used = false; 1346 break; 1347 1348 case OPT_NO_YY_PUSH_STATE: 1349 //buf_strdefine (&userdef_buf, "YY_NO_PUSH_STATE", "1"); 1350 buf_m4_define( &m4defs_buf, "M4_YY_NO_PUSH_STATE",0); 1351 break; 1352 case OPT_NO_YY_POP_STATE: 1353 //buf_strdefine (&userdef_buf, "YY_NO_POP_STATE", "1"); 1354 buf_m4_define( &m4defs_buf, "M4_YY_NO_POP_STATE",0); 1355 break; 1356 case OPT_NO_YY_TOP_STATE: 1357 //buf_strdefine (&userdef_buf, "YY_NO_TOP_STATE", "1"); 1358 buf_m4_define( &m4defs_buf, "M4_YY_NO_TOP_STATE",0); 1359 break; 1360 case OPT_NO_UNPUT: 1361 //buf_strdefine (&userdef_buf, "YY_NO_UNPUT", "1"); 1362 buf_m4_define( &m4defs_buf, "M4_YY_NO_UNPUT",0); 1363 break; 1364 case OPT_NO_YY_SCAN_BUFFER: 1365 //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BUFFER", "1"); 1366 buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BUFFER",0); 1367 break; 1368 case OPT_NO_YY_SCAN_BYTES: 1369 //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BYTES", "1"); 1370 buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_BYTES",0); 1371 break; 1372 case OPT_NO_YY_SCAN_STRING: 1373 //buf_strdefine (&userdef_buf, "YY_NO_SCAN_STRING", "1"); 1374 buf_m4_define( &m4defs_buf, "M4_YY_NO_SCAN_STRING",0); 1375 break; 1376 case OPT_NO_YYGET_EXTRA: 1377 //buf_strdefine (&userdef_buf, "YY_NO_GET_EXTRA", "1"); 1378 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_EXTRA",0); 1379 break; 1380 case OPT_NO_YYSET_EXTRA: 1381 //buf_strdefine (&userdef_buf, "YY_NO_SET_EXTRA", "1"); 1382 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_EXTRA",0); 1383 break; 1384 case OPT_NO_YYGET_LENG: 1385 //buf_strdefine (&userdef_buf, "YY_NO_GET_LENG", "1"); 1386 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LENG",0); 1387 break; 1388 case OPT_NO_YYGET_TEXT: 1389 //buf_strdefine (&userdef_buf, "YY_NO_GET_TEXT", "1"); 1390 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_TEXT",0); 1391 break; 1392 case OPT_NO_YYGET_LINENO: 1393 //buf_strdefine (&userdef_buf, "YY_NO_GET_LINENO", "1"); 1394 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LINENO",0); 1395 break; 1396 case OPT_NO_YYSET_LINENO: 1397 //buf_strdefine (&userdef_buf, "YY_NO_SET_LINENO", "1"); 1398 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LINENO",0); 1399 break; 1400 case OPT_NO_YYGET_IN: 1401 //buf_strdefine (&userdef_buf, "YY_NO_GET_IN", "1"); 1402 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_IN",0); 1403 break; 1404 case OPT_NO_YYSET_IN: 1405 //buf_strdefine (&userdef_buf, "YY_NO_SET_IN", "1"); 1406 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_IN",0); 1407 break; 1408 case OPT_NO_YYGET_OUT: 1409 //buf_strdefine (&userdef_buf, "YY_NO_GET_OUT", "1"); 1410 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_OUT",0); 1411 break; 1412 case OPT_NO_YYSET_OUT: 1413 //buf_strdefine (&userdef_buf, "YY_NO_SET_OUT", "1"); 1414 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_OUT",0); 1415 break; 1416 case OPT_NO_YYGET_LVAL: 1417 //buf_strdefine (&userdef_buf, "YY_NO_GET_LVAL", "1"); 1418 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LVAL",0); 1419 break; 1420 case OPT_NO_YYSET_LVAL: 1421 //buf_strdefine (&userdef_buf, "YY_NO_SET_LVAL", "1"); 1422 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LVAL",0); 1423 break; 1424 case OPT_NO_YYGET_LLOC: 1425 //buf_strdefine (&userdef_buf, "YY_NO_GET_LLOC", "1"); 1426 buf_m4_define( &m4defs_buf, "M4_YY_NO_GET_LLOC",0); 1427 break; 1428 case OPT_NO_YYSET_LLOC: 1429 //buf_strdefine (&userdef_buf, "YY_NO_SET_LLOC", "1"); 1430 buf_m4_define( &m4defs_buf, "M4_YY_NO_SET_LLOC",0); 1431 break; 1432 case OPT_HEX: 1433 trace_hex = 1; 1434 break; 1435 case OPT_NO_SECT3_ESCAPE: 1436 no_section3_escape = true; 1437 break; 1438 } /* switch */ 1439 } /* while scanopt() */ 1440 1441 scanopt_destroy (sopt); 1442 1443 num_input_files = argc - optind; 1444 input_files = argv + optind; 1445 set_input_file (num_input_files > 0 ? input_files[0] : NULL); 1446 1447 lastccl = lastsc = lastdfa = lastnfa = 0; 1448 num_rules = num_eof_rules = default_rule = 0; 1449 numas = numsnpairs = tmpuses = 0; 1450 numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 1451 0; 1452 numuniq = numdup = hshsave = eofseen = datapos = dataline = 0; 1453 num_backing_up = onesp = numprots = 0; 1454 variable_trailing_context_rules = bol_needed = false; 1455 1456 linenum = sectnum = 1; 1457 firstprot = NIL; 1458 1459 /* Used in mkprot() so that the first proto goes in slot 1 1460 * of the proto queue. 1461 */ 1462 lastprot = 1; 1463 1464 set_up_initial_allocations (); 1465} 1466 1467 1468/* readin - read in the rules section of the input file(s) */ 1469 1470void readin (void) 1471{ 1472 static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;"; 1473 static char yy_nostdinit[] = 1474 "FILE *yyin = NULL, *yyout = NULL;"; 1475 1476 line_directive_out(NULL, 1); 1477 1478 if (yyparse ()) { 1479 pinpoint_message (_("fatal parse error")); 1480 flexend (1); 1481 } 1482 1483 if (syntaxerror) 1484 flexend (1); 1485 1486 /* If the user explicitly requested posix compatibility by specifing the 1487 * posix-compat option, then we check for conflicting options. However, if 1488 * the POSIXLY_CORRECT variable is set, then we quietly make flex as 1489 * posix-compatible as possible. This is the recommended behavior 1490 * according to the GNU Coding Standards. 1491 * 1492 * Note: The posix option was added to flex to provide the posix behavior 1493 * of the repeat operator in regular expressions, e.g., `ab{3}' 1494 */ 1495 if (posix_compat) { 1496 /* TODO: This is where we try to make flex behave according to 1497 * posiz, AND check for conflicting options. How far should we go 1498 * with this? Should we disable all the neat-o flex features? 1499 */ 1500 /* Update: Estes says no, since other flex features don't violate posix. */ 1501 } 1502 1503 if (getenv ("POSIXLY_CORRECT")) { 1504 posix_compat = true; 1505 } 1506 1507 if (backing_up_report) { 1508 backing_up_file = fopen (backing_name, "w"); 1509 if (backing_up_file == NULL) 1510 lerr (_ 1511 ("could not create backing-up info file %s"), 1512 backing_name); 1513 } 1514 1515 else 1516 backing_up_file = NULL; 1517 1518 if (yymore_really_used == true) 1519 yymore_used = true; 1520 else if (yymore_really_used == false) 1521 yymore_used = false; 1522 1523 if (reject_really_used == true) 1524 reject = true; 1525 else if (reject_really_used == false) 1526 reject = false; 1527 1528 if (performance_report > 0) { 1529 if (lex_compat) { 1530 fprintf (stderr, 1531 _ 1532 ("-l AT&T lex compatibility option entails a large performance penalty\n")); 1533 fprintf (stderr, 1534 _ 1535 (" and may be the actual source of other reported performance penalties\n")); 1536 } 1537 1538 else if (do_yylineno) { 1539 fprintf (stderr, 1540 _ 1541 ("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n")); 1542 } 1543 1544 if (performance_report > 1) { 1545 if (interactive) 1546 fprintf (stderr, 1547 _ 1548 ("-I (interactive) entails a minor performance penalty\n")); 1549 1550 if (yymore_used) 1551 fprintf (stderr, 1552 _ 1553 ("yymore() entails a minor performance penalty\n")); 1554 } 1555 1556 if (reject) 1557 fprintf (stderr, 1558 _ 1559 ("REJECT entails a large performance penalty\n")); 1560 1561 if (variable_trailing_context_rules) 1562 fprintf (stderr, 1563 _ 1564 ("Variable trailing context rules entail a large performance penalty\n")); 1565 } 1566 1567 if (reject) 1568 real_reject = true; 1569 1570 if (variable_trailing_context_rules) 1571 reject = true; 1572 1573 if ((fulltbl || fullspd) && reject) { 1574 if (real_reject) 1575 flexerror (_ 1576 ("REJECT cannot be used with -f or -F")); 1577 else if (do_yylineno) 1578 flexerror (_ 1579 ("%option yylineno cannot be used with REJECT")); 1580 else 1581 flexerror (_ 1582 ("variable trailing context rules cannot be used with -f or -F")); 1583 } 1584 1585 if (reject){ 1586 out_m4_define( "M4_YY_USES_REJECT", NULL); 1587 //outn ("\n#define YY_USES_REJECT"); 1588 } 1589 1590 if (!do_yywrap) { 1591 if (!C_plus_plus) { 1592 if (reentrant) 1593 out_str ("\n#define %swrap(yyscanner) (/*CONSTCOND*/1)\n", prefix); 1594 else 1595 out_str ("\n#define %swrap() (/*CONSTCOND*/1)\n", prefix); 1596 } 1597 outn ("#define YY_SKIP_YYWRAP"); 1598 } 1599 1600 if (ddebug) 1601 outn ("\n#define FLEX_DEBUG"); 1602 1603 OUT_BEGIN_CODE (); 1604 outn ("typedef flex_uint8_t YY_CHAR;"); 1605 OUT_END_CODE (); 1606 1607 if (C_plus_plus) { 1608 outn ("#define yytext_ptr yytext"); 1609 1610 if (interactive) 1611 outn ("#define YY_INTERACTIVE"); 1612 } 1613 1614 else { 1615 OUT_BEGIN_CODE (); 1616 /* In reentrant scanner, stdinit is handled in flex.skl. */ 1617 if (do_stdinit) { 1618 if (reentrant){ 1619 outn ("#ifdef VMS"); 1620 outn ("#ifdef __VMS_POSIX"); 1621 outn ("#define YY_STDINIT"); 1622 outn ("#endif"); 1623 outn ("#else"); 1624 outn ("#define YY_STDINIT"); 1625 outn ("#endif"); 1626 } 1627 1628 outn ("#ifdef VMS"); 1629 outn ("#ifndef __VMS_POSIX"); 1630 outn (yy_nostdinit); 1631 outn ("#else"); 1632 outn (yy_stdinit); 1633 outn ("#endif"); 1634 outn ("#else"); 1635 outn (yy_stdinit); 1636 outn ("#endif"); 1637 } 1638 1639 else { 1640 if(!reentrant) 1641 outn (yy_nostdinit); 1642 } 1643 OUT_END_CODE (); 1644 } 1645 1646 OUT_BEGIN_CODE (); 1647 if (fullspd) 1648 outn ("typedef const struct yy_trans_info *yy_state_type;"); 1649 else if (!C_plus_plus) 1650 outn ("typedef int yy_state_type;"); 1651 OUT_END_CODE (); 1652 1653 if (lex_compat) 1654 outn ("#define YY_FLEX_LEX_COMPAT"); 1655 1656 if (!C_plus_plus && !reentrant) { 1657 outn ("extern int yylineno;"); 1658 OUT_BEGIN_CODE (); 1659 outn ("int yylineno = 1;"); 1660 OUT_END_CODE (); 1661 } 1662 1663 if (C_plus_plus) { 1664 outn ("\n#include <FlexLexer.h>"); 1665 1666 if (!do_yywrap) { 1667 outn("\nint yyFlexLexer::yywrap() { return 1; }"); 1668 } 1669 1670 if (yyclass) { 1671 outn ("int yyFlexLexer::yylex()"); 1672 outn ("\t{"); 1673 outn ("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );"); 1674 outn ("\treturn 0;"); 1675 outn ("\t}"); 1676 1677 out_str ("\n#define YY_DECL int %s::yylex()\n", 1678 yyclass); 1679 } 1680 } 1681 1682 else { 1683 1684 /* Watch out: yytext_ptr is a variable when yytext is an array, 1685 * but it's a macro when yytext is a pointer. 1686 */ 1687 if (yytext_is_array) { 1688 if (!reentrant) 1689 outn ("extern char yytext[];\n"); 1690 } 1691 else { 1692 if (reentrant) { 1693 outn ("#define yytext_ptr yytext_r"); 1694 } 1695 else { 1696 outn ("extern char *yytext;"); 1697 1698 outn("#ifdef yytext_ptr"); 1699 outn("#undef yytext_ptr"); 1700 outn("#endif"); 1701 outn ("#define yytext_ptr yytext"); 1702 } 1703 } 1704 1705 if (yyclass) 1706 flexerror (_ 1707 ("%option yyclass only meaningful for C++ scanners")); 1708 } 1709 1710 if (useecs) 1711 numecs = cre8ecs (nextecm, ecgroup, csize); 1712 else 1713 numecs = csize; 1714 1715 /* Now map the equivalence class for NUL to its expected place. */ 1716 ecgroup[0] = ecgroup[csize]; 1717 NUL_ec = ABS (ecgroup[0]); 1718 1719 if (useecs) 1720 ccl2ecl (); 1721} 1722 1723 1724/* set_up_initial_allocations - allocate memory for internal tables */ 1725 1726void set_up_initial_allocations (void) 1727{ 1728 maximum_mns = (long_align ? MAXIMUM_MNS_LONG : MAXIMUM_MNS); 1729 current_mns = INITIAL_MNS; 1730 firstst = allocate_integer_array (current_mns); 1731 lastst = allocate_integer_array (current_mns); 1732 finalst = allocate_integer_array (current_mns); 1733 transchar = allocate_integer_array (current_mns); 1734 trans1 = allocate_integer_array (current_mns); 1735 trans2 = allocate_integer_array (current_mns); 1736 accptnum = allocate_integer_array (current_mns); 1737 assoc_rule = allocate_integer_array (current_mns); 1738 state_type = allocate_integer_array (current_mns); 1739 1740 current_max_rules = INITIAL_MAX_RULES; 1741 rule_type = allocate_integer_array (current_max_rules); 1742 rule_linenum = allocate_integer_array (current_max_rules); 1743 rule_useful = allocate_integer_array (current_max_rules); 1744 rule_has_nl = allocate_bool_array (current_max_rules); 1745 1746 current_max_scs = INITIAL_MAX_SCS; 1747 scset = allocate_integer_array (current_max_scs); 1748 scbol = allocate_integer_array (current_max_scs); 1749 scxclu = allocate_integer_array (current_max_scs); 1750 sceof = allocate_integer_array (current_max_scs); 1751 scname = allocate_char_ptr_array (current_max_scs); 1752 1753 current_maxccls = INITIAL_MAX_CCLS; 1754 cclmap = allocate_integer_array (current_maxccls); 1755 ccllen = allocate_integer_array (current_maxccls); 1756 cclng = allocate_integer_array (current_maxccls); 1757 ccl_has_nl = allocate_bool_array (current_maxccls); 1758 1759 current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE; 1760 ccltbl = allocate_Character_array (current_max_ccl_tbl_size); 1761 1762 current_max_dfa_size = INITIAL_MAX_DFA_SIZE; 1763 1764 current_max_xpairs = INITIAL_MAX_XPAIRS; 1765 nxt = allocate_integer_array (current_max_xpairs); 1766 chk = allocate_integer_array (current_max_xpairs); 1767 1768 current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS; 1769 tnxt = allocate_integer_array (current_max_template_xpairs); 1770 1771 current_max_dfas = INITIAL_MAX_DFAS; 1772 base = allocate_integer_array (current_max_dfas); 1773 def = allocate_integer_array (current_max_dfas); 1774 dfasiz = allocate_integer_array (current_max_dfas); 1775 accsiz = allocate_integer_array (current_max_dfas); 1776 dhash = allocate_integer_array (current_max_dfas); 1777 dss = allocate_int_ptr_array (current_max_dfas); 1778 dfaacc = allocate_dfaacc_union (current_max_dfas); 1779 1780 nultrans = NULL; 1781} 1782 1783 1784void usage (void) 1785{ 1786 FILE *f = stdout; 1787 1788 if (!did_outfilename) { 1789 snprintf (outfile_path, sizeof(outfile_path), outfile_template, 1790 prefix, C_plus_plus ? "cc" : "c"); 1791 outfilename = outfile_path; 1792 } 1793 1794 fprintf (f, _("Usage: %s [OPTIONS] [FILE]...\n"), program_name); 1795 fprintf (f, 1796 _ 1797 ("Generates programs that perform pattern-matching on text.\n" 1798 "\n" "Table Compression:\n" 1799 " -Ca, --align trade off larger tables for better memory alignment\n" 1800 " -Ce, --ecs construct equivalence classes\n" 1801 " -Cf do not compress tables; use -f representation\n" 1802 " -CF do not compress tables; use -F representation\n" 1803 " -Cm, --meta-ecs construct meta-equivalence classes\n" 1804 " -Cr, --read use read() instead of stdio for scanner input\n" 1805 " -f, --full generate fast, large scanner. Same as -Cfr\n" 1806 " -F, --fast use alternate table representation. Same as -CFr\n" 1807 " -Cem default compression (same as --ecs --meta-ecs)\n" 1808 "\n" "Debugging:\n" 1809 " -d, --debug enable debug mode in scanner\n" 1810 " -b, --backup write backing-up information to %s\n" 1811 " -p, --perf-report write performance report to stderr\n" 1812 " -s, --nodefault suppress default rule to ECHO unmatched text\n" 1813 " -T, --trace %s should run in trace mode\n" 1814 " -w, --nowarn do not generate warnings\n" 1815 " -v, --verbose write summary of scanner statistics to stdout\n" 1816 " --hex use hexadecimal numbers instead of octal in debug outputs\n" 1817 "\n" "Files:\n" 1818 " -o, --outfile=FILE specify output filename\n" 1819 " -S, --skel=FILE specify skeleton file\n" 1820 " -t, --stdout write scanner on stdout instead of %s\n" 1821 " --yyclass=NAME name of C++ class\n" 1822 " --header-file=FILE create a C header file in addition to the scanner\n" 1823 " --tables-file[=FILE] write tables to FILE\n" "\n" 1824 "Scanner behavior:\n" 1825 " -7, --7bit generate 7-bit scanner\n" 1826 " -8, --8bit generate 8-bit scanner\n" 1827 " -B, --batch generate batch scanner (opposite of -I)\n" 1828 " -i, --case-insensitive ignore case in patterns\n" 1829 " -l, --lex-compat maximal compatibility with original lex\n" 1830 " -X, --posix-compat maximal compatibility with POSIX lex\n" 1831 " -I, --interactive generate interactive scanner (opposite of -B)\n" 1832 " --yylineno track line count in yylineno\n" 1833 "\n" "Generated code:\n" 1834 " -+, --c++ generate C++ scanner class\n" 1835 " -Dmacro[=defn] #define macro defn (default defn is '1')\n" 1836 " -L, --noline suppress #line directives in scanner\n" 1837 " -P, --prefix=STRING use STRING as prefix instead of \"yy\"\n" 1838 " -R, --reentrant generate a reentrant C scanner\n" 1839 " --bison-bridge scanner for bison pure parser.\n" 1840 " --bison-locations include yylloc support.\n" 1841 " --stdinit initialize yyin/yyout to stdin/stdout\n" 1842 " --nounistd do not include <unistd.h>\n" 1843 " --noFUNCTION do not generate a particular FUNCTION\n" 1844 "\n" "Miscellaneous:\n" 1845 " -c do-nothing POSIX option\n" 1846 " -n do-nothing POSIX option\n" 1847 " -?\n" 1848 " -h, --help produce this help message\n" 1849 " -V, --version report %s version\n"), 1850 backing_name, program_name, outfile_path, program_name); 1851 1852} 1853