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