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