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