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