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