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