1 /* $OpenBSD: main.c,v 1.10 2004/02/03 21:20:17 espie Exp $ */ 2 3 /* flex - tool to generate fast lexical analyzers */ 4 5 /*- 6 * Copyright (c) 1990 The Regents of the University of California. 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * Vern Paxson. 11 * 12 * The United States Government has rights in this work pursuant 13 * to contract no. DE-AC03-76SF00098 between the United States 14 * Department of Energy and the University of California. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 26 * Neither the name of the University nor the names of its contributors 27 * may be used to endorse or promote products derived from this software 28 * without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 31 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 32 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 33 * PURPOSE. 34 */ 35 36 #ifndef lint 37 char copyright[] = 38 "@(#) Copyright (c) 1990 The Regents of the University of California.\n\ 39 All rights reserved.\n"; 40 #endif /* not lint */ 41 42 /* $Header: /home/cvs/src/usr.bin/lex/main.c,v 1.10 2004/02/03 21:20:17 espie Exp $ */ 43 44 45 #include "flexdef.h" 46 #include "version.h" 47 48 static char flex_version[] = FLEX_VERSION; 49 50 51 /* declare functions that have forward references */ 52 53 void flexinit PROTO((int, char**)); 54 void readin PROTO((void)); 55 void set_up_initial_allocations PROTO((void)); 56 57 #ifdef NEED_ARGV_FIXUP 58 extern void argv_fixup PROTO((int *, char ***)); 59 #endif 60 61 62 /* these globals are all defined and commented in flexdef.h */ 63 int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; 64 int interactive, caseins, lex_compat, do_yylineno, useecs, fulltbl, usemecs; 65 int fullspd, gen_line_dirs, performance_report, backing_up_report; 66 int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap, csize; 67 int yymore_used, reject, real_reject, continued_action, in_rule; 68 int yymore_really_used, reject_really_used; 69 int datapos, dataline, linenum, out_linenum; 70 FILE *skelfile = NULL; 71 int skel_ind = 0; 72 char *action_array; 73 int action_size, defs1_offset, prolog_offset, action_offset, action_index; 74 char *infilename = NULL, *outfilename = NULL; 75 int did_outfilename; 76 char *prefix, *yyclass; 77 int do_stdinit, use_stdout; 78 int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; 79 int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; 80 int current_mns, current_max_rules; 81 int num_rules, num_eof_rules, default_rule, lastnfa; 82 int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; 83 int *accptnum, *assoc_rule, *state_type; 84 int *rule_type, *rule_linenum, *rule_useful; 85 int current_state_type; 86 int variable_trailing_context_rules; 87 int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; 88 int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; 89 int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs, tecfwd[CSIZE + 1]; 90 int tecbck[CSIZE + 1]; 91 int lastsc, *scset, *scbol, *scxclu, *sceof; 92 int current_max_scs; 93 char **scname; 94 int current_max_dfa_size, current_max_xpairs; 95 int current_max_template_xpairs, current_max_dfas; 96 int lastdfa, *nxt, *chk, *tnxt; 97 int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; 98 union dfaacc_union *dfaacc; 99 int *accsiz, *dhash, numas; 100 int numsnpairs, jambase, jamstate; 101 int lastccl, *cclmap, *ccllen, *cclng, cclreuse; 102 int current_maxccls, current_max_ccl_tbl_size; 103 Char *ccltbl; 104 char nmstr[MAXLINE]; 105 int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; 106 int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; 107 int num_backing_up, bol_needed; 108 FILE *backing_up_file; 109 int end_of_buffer_state; 110 char **input_files; 111 int num_input_files; 112 113 /* Make sure program_name is initialized so we don't crash if writing 114 * out an error message before getting the program name from argv[0]. 115 */ 116 char *program_name = "flex"; 117 118 #ifndef SHORT_FILE_NAMES 119 static char *outfile_template = "lex.%s.%s"; 120 static char *backing_name = "lex.backup"; 121 #else 122 static char *outfile_template = "lex%s.%s"; 123 static char *backing_name = "lex.bck"; 124 #endif 125 126 #ifdef THINK_C 127 #include <console.h> 128 #endif 129 130 #ifdef MS_DOS 131 extern unsigned _stklen = 16384; 132 #endif 133 134 static char outfile_path[MAXLINE]; 135 static int outfile_created = 0; 136 static char *skelname = NULL; 137 138 139 int main( argc, argv ) 140 int argc; 141 char **argv; 142 { 143 int i; 144 145 #ifdef THINK_C 146 argc = ccommand( &argv ); 147 #endif 148 #ifdef NEED_ARGV_FIXUP 149 argv_fixup( &argc, &argv ); 150 #endif 151 152 flexinit( argc, argv ); 153 154 readin(); 155 156 ntod(); 157 158 for ( i = 1; i <= num_rules; ++i ) 159 if ( ! rule_useful[i] && i != default_rule ) 160 line_warning( _( "rule cannot be matched" ), 161 rule_linenum[i] ); 162 163 if ( spprdflt && ! reject && rule_useful[default_rule] ) 164 line_warning( 165 _( "-s option given but default rule can be matched" ), 166 rule_linenum[default_rule] ); 167 168 /* Generate the C state transition tables from the DFA. */ 169 make_tables(); 170 171 /* Note, flexend does not return. It exits with its argument 172 * as status. 173 */ 174 flexend( 0 ); 175 176 return 0; /* keep compilers/lint happy */ 177 } 178 179 180 /* check_options - check user-specified options */ 181 182 void check_options() 183 { 184 int i; 185 186 if ( lex_compat ) 187 { 188 if ( C_plus_plus ) 189 flexerror( _( "Can't use -+ with -l option" ) ); 190 191 if ( fulltbl || fullspd ) 192 flexerror( _( "Can't use -f or -F with -l option" ) ); 193 194 /* Don't rely on detecting use of yymore() and REJECT, 195 * just assume they'll be used. 196 */ 197 yymore_really_used = reject_really_used = true; 198 199 yytext_is_array = true; 200 do_yylineno = true; 201 use_read = false; 202 } 203 204 if ( do_yylineno ) 205 /* This should really be "maintain_backup_tables = true" */ 206 reject_really_used = true; 207 208 if ( csize == unspecified ) 209 { 210 if ( (fulltbl || fullspd) && ! useecs ) 211 csize = DEFAULT_CSIZE; 212 else 213 csize = CSIZE; 214 } 215 216 if ( interactive == unspecified ) 217 { 218 if ( fulltbl || fullspd ) 219 interactive = false; 220 else 221 interactive = true; 222 } 223 224 if ( fulltbl || fullspd ) 225 { 226 if ( usemecs ) 227 flexerror( 228 _( "-Cf/-CF and -Cm don't make sense together" ) ); 229 230 if ( interactive ) 231 flexerror( _( "-Cf/-CF and -I are incompatible" ) ); 232 233 if ( lex_compat ) 234 flexerror( 235 _( "-Cf/-CF are incompatible with lex-compatibility mode" ) ); 236 237 if ( do_yylineno ) 238 flexerror( 239 _( "-Cf/-CF and %option yylineno are incompatible" ) ); 240 241 if ( fulltbl && fullspd ) 242 flexerror( _( "-Cf and -CF are mutually exclusive" ) ); 243 } 244 245 if ( C_plus_plus && fullspd ) 246 flexerror( _( "Can't use -+ with -CF option" ) ); 247 248 if ( C_plus_plus && yytext_is_array ) 249 { 250 warn( _( "%array incompatible with -+ option" ) ); 251 yytext_is_array = false; 252 } 253 254 if ( useecs ) 255 { /* Set up doubly-linked equivalence classes. */ 256 257 /* We loop all the way up to csize, since ecgroup[csize] is 258 * the position used for NUL characters. 259 */ 260 ecgroup[1] = NIL; 261 262 for ( i = 2; i <= csize; ++i ) 263 { 264 ecgroup[i] = i - 1; 265 nextecm[i - 1] = i; 266 } 267 268 nextecm[csize] = NIL; 269 } 270 271 else 272 { 273 /* Put everything in its own equivalence class. */ 274 for ( i = 1; i <= csize; ++i ) 275 { 276 ecgroup[i] = i; 277 nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */ 278 } 279 } 280 281 if ( ! use_stdout ) 282 { 283 FILE *prev_stdout; 284 285 if ( ! did_outfilename ) 286 { 287 char *suffix; 288 289 if ( C_plus_plus ) 290 suffix = "cc"; 291 else 292 suffix = "c"; 293 294 snprintf( outfile_path, sizeof outfile_path, 295 outfile_template, prefix, suffix ); 296 297 outfilename = outfile_path; 298 } 299 300 prev_stdout = freopen( outfilename, "w", stdout ); 301 302 if ( prev_stdout == NULL ) 303 lerrsf( _( "could not create %s" ), outfilename ); 304 305 outfile_created = 1; 306 } 307 308 if ( skelname && (skelfile = fopen( skelname, "r" )) == NULL ) 309 lerrsf( _( "can't open skeleton file %s" ), skelname ); 310 311 if ( strcmp( prefix, "yy" ) ) 312 { 313 #define GEN_PREFIX(name) out_str3( "#define yy%s %s%s\n", name, prefix, name ) 314 if ( C_plus_plus ) 315 GEN_PREFIX( "FlexLexer" ); 316 else 317 { 318 GEN_PREFIX( "_create_buffer" ); 319 GEN_PREFIX( "_delete_buffer" ); 320 GEN_PREFIX( "_scan_buffer" ); 321 GEN_PREFIX( "_scan_string" ); 322 GEN_PREFIX( "_scan_bytes" ); 323 GEN_PREFIX( "_flex_debug" ); 324 GEN_PREFIX( "_init_buffer" ); 325 GEN_PREFIX( "_flush_buffer" ); 326 GEN_PREFIX( "_load_buffer_state" ); 327 GEN_PREFIX( "_switch_to_buffer" ); 328 GEN_PREFIX( "in" ); 329 GEN_PREFIX( "leng" ); 330 GEN_PREFIX( "lex" ); 331 GEN_PREFIX( "out" ); 332 GEN_PREFIX( "restart" ); 333 GEN_PREFIX( "text" ); 334 335 if ( do_yylineno ) 336 GEN_PREFIX( "lineno" ); 337 } 338 339 if ( do_yywrap ) 340 GEN_PREFIX( "wrap" ); 341 342 outn( "" ); 343 } 344 345 if ( did_outfilename ) 346 line_directive_out( stdout, 0 ); 347 348 skelout(); 349 } 350 351 352 /* flexend - terminate flex 353 * 354 * note 355 * This routine does not return. 356 */ 357 358 void flexend( exit_status ) 359 int exit_status; 360 361 { 362 int tblsiz; 363 int unlink(); 364 365 if ( skelfile != NULL ) 366 { 367 if ( ferror( skelfile ) ) 368 lerrsf( _( "input error reading skeleton file %s" ), 369 skelname ); 370 371 else if ( fclose( skelfile ) ) 372 lerrsf( _( "error closing skeleton file %s" ), 373 skelname ); 374 } 375 376 if ( exit_status != 0 && outfile_created ) 377 { 378 if ( ferror( stdout ) ) 379 lerrsf( _( "error writing output file %s" ), 380 outfilename ); 381 382 else if ( fclose( stdout ) ) 383 lerrsf( _( "error closing output file %s" ), 384 outfilename ); 385 386 else if ( unlink( outfilename ) ) 387 lerrsf( _( "error deleting output file %s" ), 388 outfilename ); 389 } 390 391 if ( backing_up_report && backing_up_file ) 392 { 393 if ( num_backing_up == 0 ) 394 fprintf( backing_up_file, _( "No backing up.\n" ) ); 395 else if ( fullspd || fulltbl ) 396 fprintf( backing_up_file, 397 _( "%d backing up (non-accepting) states.\n" ), 398 num_backing_up ); 399 else 400 fprintf( backing_up_file, 401 _( "Compressed tables always back up.\n" ) ); 402 403 if ( ferror( backing_up_file ) ) 404 lerrsf( _( "error writing backup file %s" ), 405 backing_name ); 406 407 else if ( fclose( backing_up_file ) ) 408 lerrsf( _( "error closing backup file %s" ), 409 backing_name ); 410 } 411 412 if ( printstats ) 413 { 414 fprintf( stderr, _( "%s version %s usage statistics:\n" ), 415 program_name, flex_version ); 416 417 fprintf( stderr, _( " scanner options: -" ) ); 418 419 if ( C_plus_plus ) 420 putc( '+', stderr ); 421 if ( backing_up_report ) 422 putc( 'b', stderr ); 423 if ( ddebug ) 424 putc( 'd', stderr ); 425 if ( caseins ) 426 putc( 'i', stderr ); 427 if ( lex_compat ) 428 putc( 'l', stderr ); 429 if ( performance_report > 0 ) 430 putc( 'p', stderr ); 431 if ( performance_report > 1 ) 432 putc( 'p', stderr ); 433 if ( spprdflt ) 434 putc( 's', stderr ); 435 if ( use_stdout ) 436 putc( 't', stderr ); 437 if ( printstats ) 438 putc( 'v', stderr ); /* always true! */ 439 if ( nowarn ) 440 putc( 'w', stderr ); 441 if ( interactive == false ) 442 putc( 'B', stderr ); 443 if ( interactive == true ) 444 putc( 'I', stderr ); 445 if ( ! gen_line_dirs ) 446 putc( 'L', stderr ); 447 if ( trace ) 448 putc( 'T', stderr ); 449 450 if ( csize == unspecified ) 451 /* We encountered an error fairly early on, so csize 452 * never got specified. Define it now, to prevent 453 * bogus table sizes being written out below. 454 */ 455 csize = 256; 456 457 if ( csize == 128 ) 458 putc( '7', stderr ); 459 else 460 putc( '8', stderr ); 461 462 fprintf( stderr, " -C" ); 463 464 if ( long_align ) 465 putc( 'a', stderr ); 466 if ( fulltbl ) 467 putc( 'f', stderr ); 468 if ( fullspd ) 469 putc( 'F', stderr ); 470 if ( useecs ) 471 putc( 'e', stderr ); 472 if ( usemecs ) 473 putc( 'm', stderr ); 474 if ( use_read ) 475 putc( 'r', stderr ); 476 477 if ( did_outfilename ) 478 fprintf( stderr, " -o%s", outfilename ); 479 480 if ( skelname ) 481 fprintf( stderr, " -S%s", skelname ); 482 483 if ( strcmp( prefix, "yy" ) ) 484 fprintf( stderr, " -P%s", prefix ); 485 486 putc( '\n', stderr ); 487 488 fprintf( stderr, _( " %d/%d NFA states\n" ), 489 lastnfa, current_mns ); 490 fprintf( stderr, _( " %d/%d DFA states (%d words)\n" ), 491 lastdfa, current_max_dfas, totnst ); 492 fprintf( stderr, _( " %d rules\n" ), 493 num_rules + num_eof_rules - 1 /* - 1 for def. rule */ ); 494 495 if ( num_backing_up == 0 ) 496 fprintf( stderr, _( " No backing up\n" ) ); 497 else if ( fullspd || fulltbl ) 498 fprintf( stderr, 499 _( " %d backing-up (non-accepting) states\n" ), 500 num_backing_up ); 501 else 502 fprintf( stderr, 503 _( " Compressed tables always back-up\n" ) ); 504 505 if ( bol_needed ) 506 fprintf( stderr, 507 _( " Beginning-of-line patterns used\n" ) ); 508 509 fprintf( stderr, _( " %d/%d start conditions\n" ), lastsc, 510 current_max_scs ); 511 fprintf( stderr, 512 _( " %d epsilon states, %d double epsilon states\n" ), 513 numeps, eps2 ); 514 515 if ( lastccl == 0 ) 516 fprintf( stderr, _( " no character classes\n" ) ); 517 else 518 fprintf( stderr, 519 _( " %d/%d character classes needed %d/%d words of storage, %d reused\n" ), 520 lastccl, current_maxccls, 521 cclmap[lastccl] + ccllen[lastccl], 522 current_max_ccl_tbl_size, cclreuse ); 523 524 fprintf( stderr, _( " %d state/nextstate pairs created\n" ), 525 numsnpairs ); 526 fprintf( stderr, _( " %d/%d unique/duplicate transitions\n" ), 527 numuniq, numdup ); 528 529 if ( fulltbl ) 530 { 531 tblsiz = lastdfa * numecs; 532 fprintf( stderr, _( " %d table entries\n" ), tblsiz ); 533 } 534 535 else 536 { 537 tblsiz = 2 * (lastdfa + numtemps) + 2 * tblend; 538 539 fprintf( stderr, 540 _( " %d/%d base-def entries created\n" ), 541 lastdfa + numtemps, current_max_dfas ); 542 fprintf( stderr, 543 _( " %d/%d (peak %d) nxt-chk entries created\n" ), 544 tblend, current_max_xpairs, peakpairs ); 545 fprintf( stderr, 546 _( " %d/%d (peak %d) template nxt-chk entries created\n" ), 547 numtemps * nummecs, 548 current_max_template_xpairs, 549 numtemps * numecs ); 550 fprintf( stderr, _( " %d empty table entries\n" ), 551 nummt ); 552 fprintf( stderr, _( " %d protos created\n" ), 553 numprots ); 554 fprintf( stderr, 555 _( " %d templates created, %d uses\n" ), 556 numtemps, tmpuses ); 557 } 558 559 if ( useecs ) 560 { 561 tblsiz = tblsiz + csize; 562 fprintf( stderr, 563 _( " %d/%d equivalence classes created\n" ), 564 numecs, csize ); 565 } 566 567 if ( usemecs ) 568 { 569 tblsiz = tblsiz + numecs; 570 fprintf( stderr, 571 _( " %d/%d meta-equivalence classes created\n" ), 572 nummecs, csize ); 573 } 574 575 fprintf( stderr, 576 _( " %d (%d saved) hash collisions, %d DFAs equal\n" ), 577 hshcol, hshsave, dfaeql ); 578 fprintf( stderr, _( " %d sets of reallocations needed\n" ), 579 num_reallocs ); 580 fprintf( stderr, _( " %d total table entries needed\n" ), 581 tblsiz ); 582 } 583 584 exit( exit_status ); 585 } 586 587 588 /* flexinit - initialize flex */ 589 590 void flexinit( argc, argv ) 591 int argc; 592 char **argv; 593 { 594 int i, sawcmpflag; 595 char *arg; 596 597 printstats = syntaxerror = trace = spprdflt = caseins = false; 598 lex_compat = C_plus_plus = backing_up_report = ddebug = fulltbl = false; 599 fullspd = long_align = nowarn = yymore_used = continued_action = false; 600 do_yylineno = yytext_is_array = in_rule = reject = do_stdinit = false; 601 yymore_really_used = reject_really_used = unspecified; 602 interactive = csize = unspecified; 603 do_yywrap = gen_line_dirs = usemecs = useecs = true; 604 performance_report = 0; 605 did_outfilename = 0; 606 prefix = "yy"; 607 yyclass = 0; 608 use_read = use_stdout = false; 609 610 sawcmpflag = false; 611 612 /* Initialize dynamic array for holding the rule actions. */ 613 action_size = 2048; /* default size of action array in bytes */ 614 action_array = allocate_character_array( action_size ); 615 defs1_offset = prolog_offset = action_offset = action_index = 0; 616 action_array[0] = '\0'; 617 618 program_name = argv[0]; 619 620 if ( program_name[0] != '\0' && 621 program_name[strlen( program_name ) - 1] == '+' ) 622 C_plus_plus = true; 623 624 /* read flags */ 625 for ( --argc, ++argv; argc ; --argc, ++argv ) 626 { 627 arg = argv[0]; 628 629 if ( arg[0] != '-' || arg[1] == '\0' ) 630 break; 631 632 if ( arg[1] == '-' ) 633 { /* --option */ 634 if ( ! strcmp( arg, "--help" ) ) 635 arg = "-h"; 636 637 else if ( ! strcmp( arg, "--version" ) ) 638 arg = "-V"; 639 640 else if ( ! strcmp( arg, "--" ) ) 641 { /* end of options */ 642 --argc; 643 ++argv; 644 break; 645 } 646 } 647 648 for ( i = 1; arg[i] != '\0'; ++i ) 649 switch ( arg[i] ) 650 { 651 case '+': 652 C_plus_plus = true; 653 break; 654 655 case 'B': 656 interactive = false; 657 break; 658 659 case 'b': 660 backing_up_report = true; 661 break; 662 663 case 'c': 664 break; 665 666 case 'C': 667 if ( i != 1 ) 668 flexerror( 669 _( "-C flag must be given separately" ) ); 670 671 if ( ! sawcmpflag ) 672 { 673 useecs = false; 674 usemecs = false; 675 fulltbl = false; 676 sawcmpflag = true; 677 } 678 679 for ( ++i; arg[i] != '\0'; ++i ) 680 switch ( arg[i] ) 681 { 682 case 'a': 683 long_align = 684 true; 685 break; 686 687 case 'e': 688 useecs = true; 689 break; 690 691 case 'F': 692 fullspd = true; 693 break; 694 695 case 'f': 696 fulltbl = true; 697 break; 698 699 case 'm': 700 usemecs = true; 701 break; 702 703 case 'r': 704 use_read = true; 705 break; 706 707 default: 708 lerrif( 709 _( "unknown -C option '%c'" ), 710 (int) arg[i] ); 711 break; 712 } 713 714 goto get_next_arg; 715 716 case 'd': 717 ddebug = true; 718 break; 719 720 case 'f': 721 useecs = usemecs = false; 722 use_read = fulltbl = true; 723 break; 724 725 case 'F': 726 useecs = usemecs = false; 727 use_read = fullspd = true; 728 break; 729 730 case '?': 731 case 'h': 732 usage(); 733 exit( 0 ); 734 735 case 'I': 736 interactive = true; 737 break; 738 739 case 'i': 740 caseins = true; 741 break; 742 743 case 'l': 744 lex_compat = true; 745 break; 746 747 case 'L': 748 gen_line_dirs = false; 749 break; 750 751 case 'n': 752 /* Stupid do-nothing deprecated 753 * option. 754 */ 755 break; 756 757 case 'o': 758 if ( i != 1 ) 759 flexerror( 760 _( "-o flag must be given separately" ) ); 761 762 outfilename = arg + i + 1; 763 did_outfilename = 1; 764 goto get_next_arg; 765 766 case 'P': 767 if ( i != 1 ) 768 flexerror( 769 _( "-P flag must be given separately" ) ); 770 771 prefix = arg + i + 1; 772 goto get_next_arg; 773 774 case 'p': 775 ++performance_report; 776 break; 777 778 case 'S': 779 if ( i != 1 ) 780 flexerror( 781 _( "-S flag must be given separately" ) ); 782 783 skelname = arg + i + 1; 784 goto get_next_arg; 785 786 case 's': 787 spprdflt = true; 788 break; 789 790 case 't': 791 use_stdout = true; 792 break; 793 794 case 'T': 795 trace = true; 796 break; 797 798 case 'v': 799 printstats = true; 800 break; 801 802 case 'V': 803 printf( _( "%s version %s\n" ), 804 program_name, flex_version ); 805 exit( 0 ); 806 807 case 'w': 808 nowarn = true; 809 break; 810 811 case '7': 812 csize = 128; 813 break; 814 815 case '8': 816 csize = CSIZE; 817 break; 818 819 default: 820 fprintf( stderr, 821 _( "%s: unknown flag '%c'. For usage, try\n\t%s --help\n" ), 822 program_name, (int) arg[i], 823 program_name ); 824 exit( 1 ); 825 } 826 827 /* Used by -C, -S, -o, and -P flags in lieu of a "continue 2" 828 * control. 829 */ 830 get_next_arg: ; 831 } 832 833 num_input_files = argc; 834 input_files = argv; 835 set_input_file( num_input_files > 0 ? input_files[0] : NULL ); 836 837 lastccl = lastsc = lastdfa = lastnfa = 0; 838 num_rules = num_eof_rules = default_rule = 0; 839 numas = numsnpairs = tmpuses = 0; 840 numecs = numeps = eps2 = num_reallocs = hshcol = dfaeql = totnst = 0; 841 numuniq = numdup = hshsave = eofseen = datapos = dataline = 0; 842 num_backing_up = onesp = numprots = 0; 843 variable_trailing_context_rules = bol_needed = false; 844 845 out_linenum = linenum = sectnum = 1; 846 firstprot = NIL; 847 848 /* Used in mkprot() so that the first proto goes in slot 1 849 * of the proto queue. 850 */ 851 lastprot = 1; 852 853 set_up_initial_allocations(); 854 } 855 856 857 /* readin - read in the rules section of the input file(s) */ 858 859 void readin() 860 { 861 static char yy_stdinit[] = "FILE *yyin = stdin, *yyout = stdout;"; 862 static char yy_nostdinit[] = 863 "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;"; 864 865 line_directive_out( (FILE *) 0, 1 ); 866 867 if ( yyparse() ) 868 { 869 pinpoint_message( _( "fatal parse error" ) ); 870 flexend( 1 ); 871 } 872 873 if ( syntaxerror ) 874 flexend( 1 ); 875 876 if ( backing_up_report ) 877 { 878 backing_up_file = fopen( backing_name, "w" ); 879 if ( backing_up_file == NULL ) 880 lerrsf( 881 _( "could not create backing-up info file %s" ), 882 backing_name ); 883 } 884 885 else 886 backing_up_file = NULL; 887 888 if ( yymore_really_used == true ) 889 yymore_used = true; 890 else if ( yymore_really_used == false ) 891 yymore_used = false; 892 893 if ( reject_really_used == true ) 894 reject = true; 895 else if ( reject_really_used == false ) 896 reject = false; 897 898 if ( performance_report > 0 ) 899 { 900 if ( lex_compat ) 901 { 902 fprintf( stderr, 903 _( "-l AT&T lex compatibility option entails a large performance penalty\n" ) ); 904 fprintf( stderr, 905 _( " and may be the actual source of other reported performance penalties\n" ) ); 906 } 907 908 else if ( do_yylineno ) 909 { 910 fprintf( stderr, 911 _( "%%option yylineno entails a large performance penalty\n" ) ); 912 } 913 914 if ( performance_report > 1 ) 915 { 916 if ( interactive ) 917 fprintf( stderr, 918 _( "-I (interactive) entails a minor performance penalty\n" ) ); 919 920 if ( yymore_used ) 921 fprintf( stderr, 922 _( "yymore() entails a minor performance penalty\n" ) ); 923 } 924 925 if ( reject ) 926 fprintf( stderr, 927 _( "REJECT entails a large performance penalty\n" ) ); 928 929 if ( variable_trailing_context_rules ) 930 fprintf( stderr, 931 _( "Variable trailing context rules entail a large performance penalty\n" ) ); 932 } 933 934 if ( reject ) 935 real_reject = true; 936 937 if ( variable_trailing_context_rules ) 938 reject = true; 939 940 if ( (fulltbl || fullspd) && reject ) 941 { 942 if ( real_reject ) 943 flexerror( 944 _( "REJECT cannot be used with -f or -F" ) ); 945 else if ( do_yylineno ) 946 flexerror( 947 _( "%option yylineno cannot be used with -f or -F" ) ); 948 else 949 flexerror( 950 _( "variable trailing context rules cannot be used with -f or -F" ) ); 951 } 952 953 if ( reject ) 954 outn( "\n#define YY_USES_REJECT" ); 955 956 if ( ! do_yywrap ) 957 { 958 outn( "\n#define yywrap() 1" ); 959 outn( "#define YY_SKIP_YYWRAP" ); 960 } 961 962 if ( ddebug ) 963 outn( "\n#define FLEX_DEBUG" ); 964 965 if ( csize == 256 ) 966 outn( "typedef unsigned char YY_CHAR;" ); 967 else 968 outn( "typedef char YY_CHAR;" ); 969 970 if ( C_plus_plus ) 971 { 972 outn( "#define yytext_ptr yytext" ); 973 974 if ( interactive ) 975 outn( "#define YY_INTERACTIVE" ); 976 } 977 978 else 979 { 980 if ( do_stdinit ) 981 { 982 outn( "#ifdef VMS" ); 983 outn( "#ifndef __VMS_POSIX" ); 984 outn( yy_nostdinit ); 985 outn( "#else" ); 986 outn( yy_stdinit ); 987 outn( "#endif" ); 988 outn( "#else" ); 989 outn( yy_stdinit ); 990 outn( "#endif" ); 991 } 992 993 else 994 outn( yy_nostdinit ); 995 } 996 997 if ( fullspd ) 998 outn( "typedef yyconst struct yy_trans_info *yy_state_type;" ); 999 else if ( ! C_plus_plus ) 1000 outn( "typedef int yy_state_type;" ); 1001 1002 if ( ddebug ) 1003 outn( "\n#define FLEX_DEBUG" ); 1004 1005 if ( lex_compat ) 1006 outn( "#define YY_FLEX_LEX_COMPAT" ); 1007 1008 if ( do_yylineno && ! C_plus_plus ) 1009 { 1010 outn( "extern int yylineno;" ); 1011 outn( "int yylineno = 1;" ); 1012 } 1013 1014 if ( C_plus_plus ) 1015 { 1016 outn( "\n#include <FlexLexer.h>" ); 1017 1018 if ( yyclass ) 1019 { 1020 outn( "int yyFlexLexer::yylex()" ); 1021 outn( "\t{" ); 1022 outn( 1023 "\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );" ); 1024 outn( "\treturn 0;" ); 1025 outn( "\t}" ); 1026 1027 out_str( "\n#define YY_DECL int %s::yylex()\n", 1028 yyclass ); 1029 } 1030 } 1031 1032 else 1033 { 1034 if ( yytext_is_array ) 1035 outn( "extern char yytext[];\n" ); 1036 1037 else 1038 { 1039 outn( "extern char *yytext;" ); 1040 outn( "#define yytext_ptr yytext" ); 1041 } 1042 1043 if ( yyclass ) 1044 flexerror( 1045 _( "%option yyclass only meaningful for C++ scanners" ) ); 1046 } 1047 1048 if ( useecs ) 1049 numecs = cre8ecs( nextecm, ecgroup, csize ); 1050 else 1051 numecs = csize; 1052 1053 /* Now map the equivalence class for NUL to its expected place. */ 1054 ecgroup[0] = ecgroup[csize]; 1055 NUL_ec = ABS( ecgroup[0] ); 1056 1057 if ( useecs ) 1058 ccl2ecl(); 1059 } 1060 1061 1062 /* set_up_initial_allocations - allocate memory for internal tables */ 1063 1064 void set_up_initial_allocations() 1065 { 1066 current_mns = INITIAL_MNS; 1067 firstst = allocate_integer_array( current_mns ); 1068 lastst = allocate_integer_array( current_mns ); 1069 finalst = allocate_integer_array( current_mns ); 1070 transchar = allocate_integer_array( current_mns ); 1071 trans1 = allocate_integer_array( current_mns ); 1072 trans2 = allocate_integer_array( current_mns ); 1073 accptnum = allocate_integer_array( current_mns ); 1074 assoc_rule = allocate_integer_array( current_mns ); 1075 state_type = allocate_integer_array( current_mns ); 1076 1077 current_max_rules = INITIAL_MAX_RULES; 1078 rule_type = allocate_integer_array( current_max_rules ); 1079 rule_linenum = allocate_integer_array( current_max_rules ); 1080 rule_useful = allocate_integer_array( current_max_rules ); 1081 1082 current_max_scs = INITIAL_MAX_SCS; 1083 scset = allocate_integer_array( current_max_scs ); 1084 scbol = allocate_integer_array( current_max_scs ); 1085 scxclu = allocate_integer_array( current_max_scs ); 1086 sceof = allocate_integer_array( current_max_scs ); 1087 scname = allocate_char_ptr_array( current_max_scs ); 1088 1089 current_maxccls = INITIAL_MAX_CCLS; 1090 cclmap = allocate_integer_array( current_maxccls ); 1091 ccllen = allocate_integer_array( current_maxccls ); 1092 cclng = allocate_integer_array( current_maxccls ); 1093 1094 current_max_ccl_tbl_size = INITIAL_MAX_CCL_TBL_SIZE; 1095 ccltbl = allocate_Character_array( current_max_ccl_tbl_size ); 1096 1097 current_max_dfa_size = INITIAL_MAX_DFA_SIZE; 1098 1099 current_max_xpairs = INITIAL_MAX_XPAIRS; 1100 nxt = allocate_integer_array( current_max_xpairs ); 1101 chk = allocate_integer_array( current_max_xpairs ); 1102 1103 current_max_template_xpairs = INITIAL_MAX_TEMPLATE_XPAIRS; 1104 tnxt = allocate_integer_array( current_max_template_xpairs ); 1105 1106 current_max_dfas = INITIAL_MAX_DFAS; 1107 base = allocate_integer_array( current_max_dfas ); 1108 def = allocate_integer_array( current_max_dfas ); 1109 dfasiz = allocate_integer_array( current_max_dfas ); 1110 accsiz = allocate_integer_array( current_max_dfas ); 1111 dhash = allocate_integer_array( current_max_dfas ); 1112 dss = allocate_int_ptr_array( current_max_dfas ); 1113 dfaacc = allocate_dfaacc_union( current_max_dfas ); 1114 1115 nultrans = (int *) 0; 1116 } 1117 1118 1119 void usage() 1120 { 1121 FILE *f = stdout; 1122 1123 fprintf( f, 1124 _( "%s [-bcdfhilnpstvwBFILTV78+? -C[aefFmr] -ooutput -Pprefix -Sskeleton]\n" ), 1125 program_name ); 1126 fprintf( f, _( "\t[--help --version] [file ...]\n" ) ); 1127 1128 fprintf( f, _( "\t-b generate backing-up information to %s\n" ), 1129 backing_name ); 1130 fprintf( f, _( "\t-c do-nothing POSIX option\n" ) ); 1131 fprintf( f, _( "\t-d turn on debug mode in generated scanner\n" ) ); 1132 fprintf( f, _( "\t-f generate fast, large scanner\n" ) ); 1133 fprintf( f, _( "\t-h produce this help message\n" ) ); 1134 fprintf( f, _( "\t-i generate case-insensitive scanner\n" ) ); 1135 fprintf( f, _( "\t-l maximal compatibility with original lex\n" ) ); 1136 fprintf( f, _( "\t-n do-nothing POSIX option\n" ) ); 1137 fprintf( f, _( "\t-p generate performance report to stderr\n" ) ); 1138 fprintf( f, 1139 _( "\t-s suppress default rule to ECHO unmatched text\n" ) ); 1140 1141 if ( ! did_outfilename ) 1142 { 1143 snprintf( outfile_path, sizeof outfile_path, outfile_template, 1144 prefix, C_plus_plus ? "cc" : "c" ); 1145 outfilename = outfile_path; 1146 } 1147 1148 fprintf( f, 1149 _( "\t-t write generated scanner on stdout instead of %s\n" ), 1150 outfilename ); 1151 1152 fprintf( f, 1153 _( "\t-v write summary of scanner statistics to f\n" ) ); 1154 fprintf( f, _( "\t-w do not generate warnings\n" ) ); 1155 fprintf( f, _( "\t-B generate batch scanner (opposite of -I)\n" ) ); 1156 fprintf( f, 1157 _( "\t-F use alternative fast scanner representation\n" ) ); 1158 fprintf( f, 1159 _( "\t-I generate interactive scanner (opposite of -B)\n" ) ); 1160 fprintf( f, _( "\t-L suppress #line directives in scanner\n" ) ); 1161 fprintf( f, _( "\t-T %s should run in trace mode\n" ), program_name ); 1162 fprintf( f, _( "\t-V report %s version\n" ), program_name ); 1163 fprintf( f, _( "\t-7 generate 7-bit scanner\n" ) ); 1164 fprintf( f, _( "\t-8 generate 8-bit scanner\n" ) ); 1165 fprintf( f, _( "\t-+ generate C++ scanner class\n" ) ); 1166 fprintf( f, _( "\t-? produce this help message\n" ) ); 1167 fprintf( f, 1168 _( "\t-C specify degree of table compression (default is -Cem):\n" ) ); 1169 fprintf( f, 1170 _( "\t\t-Ca trade off larger tables for better memory alignment\n" ) ); 1171 fprintf( f, _( "\t\t-Ce construct equivalence classes\n" ) ); 1172 fprintf( f, 1173 _( "\t\t-Cf do not compress scanner tables; use -f representation\n" ) ); 1174 fprintf( f, 1175 _( "\t\t-CF do not compress scanner tables; use -F representation\n" ) ); 1176 fprintf( f, _( "\t\t-Cm construct meta-equivalence classes\n" ) ); 1177 fprintf( f, 1178 _( "\t\t-Cr use read() instead of stdio for scanner input\n" ) ); 1179 fprintf( f, _( "\t-o specify output filename\n" ) ); 1180 fprintf( f, _( "\t-P specify scanner prefix other than \"yy\"\n" ) ); 1181 fprintf( f, _( "\t-S specify skeleton file\n" ) ); 1182 fprintf( f, _( "\t--help produce this help message\n" ) ); 1183 fprintf( f, _( "\t--version report %s version\n" ), program_name ); 1184 } 1185