1 /* gen - actual generation (writing) of flex scanners */ 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 /* $Header: /home/daffy/u0/vern/flex/RCS/gen.c,v 2.56 96/05/25 20:43:38 vern Exp $ */ 30 31 #include "flexdef.h" 32 33 34 /* declare functions that have forward references */ 35 36 void gen_next_state PROTO((int)); 37 void genecs PROTO((void)); 38 void indent_put2s PROTO((char [], char [])); 39 void indent_puts PROTO((char [])); 40 41 42 static int indent_level = 0; /* each level is 8 spaces */ 43 44 #define indent_up() (++indent_level) 45 #define indent_down() (--indent_level) 46 #define set_indent(indent_val) indent_level = indent_val 47 48 /* Almost everything is done in terms of arrays starting at 1, so provide 49 * a null entry for the zero element of all C arrays. (The exception 50 * to this is that the fast table representation generally uses the 51 * 0 elements of its arrays, too.) 52 */ 53 static char C_int_decl[] = "static yyconst int %s[%d] =\n { 0,\n"; 54 static char C_short_decl[] = "static yyconst short int %s[%d] =\n { 0,\n"; 55 static char C_long_decl[] = "static yyconst long int %s[%d] =\n { 0,\n"; 56 static char C_state_decl[] = 57 "static yyconst yy_state_type %s[%d] =\n { 0,\n"; 58 59 60 /* Indent to the current level. */ 61 62 void do_indent() 63 { 64 register int i = indent_level * 8; 65 66 while ( i >= 8 ) 67 { 68 outc( '\t' ); 69 i -= 8; 70 } 71 72 while ( i > 0 ) 73 { 74 outc( ' ' ); 75 --i; 76 } 77 } 78 79 80 /* Generate the code to keep backing-up information. */ 81 82 void gen_backing_up() 83 { 84 if ( reject || num_backing_up == 0 ) 85 return; 86 87 if ( fullspd ) 88 indent_puts( "if ( yy_current_state[-1].yy_nxt )" ); 89 else 90 indent_puts( "if ( yy_accept[yy_current_state] )" ); 91 92 indent_up(); 93 indent_puts( "{" ); 94 indent_puts( "yy_last_accepting_state = yy_current_state;" ); 95 indent_puts( "yy_last_accepting_cpos = yy_cp;" ); 96 indent_puts( "}" ); 97 indent_down(); 98 } 99 100 101 /* Generate the code to perform the backing up. */ 102 103 void gen_bu_action() 104 { 105 if ( reject || num_backing_up == 0 ) 106 return; 107 108 set_indent( 3 ); 109 110 indent_puts( "case 0: /* must back up */" ); 111 indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" ); 112 indent_puts( "*yy_cp = yy_hold_char;" ); 113 114 if ( fullspd || fulltbl ) 115 indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" ); 116 else 117 /* Backing-up info for compressed tables is taken \after/ 118 * yy_cp has been incremented for the next state. 119 */ 120 indent_puts( "yy_cp = yy_last_accepting_cpos;" ); 121 122 indent_puts( "yy_current_state = yy_last_accepting_state;" ); 123 indent_puts( "goto yy_find_action;" ); 124 outc( '\n' ); 125 126 set_indent( 0 ); 127 } 128 129 130 /* genctbl - generates full speed compressed transition table */ 131 132 void genctbl() 133 { 134 register int i; 135 int end_of_buffer_action = num_rules + 1; 136 137 /* Table of verify for transition and offset to next state. */ 138 out_dec( "static yyconst struct yy_trans_info yy_transition[%d] =\n", 139 tblend + numecs + 1 ); 140 outn( " {" ); 141 142 /* We want the transition to be represented as the offset to the 143 * next state, not the actual state number, which is what it currently 144 * is. The offset is base[nxt[i]] - (base of current state)]. That's 145 * just the difference between the starting points of the two involved 146 * states (to - from). 147 * 148 * First, though, we need to find some way to put in our end-of-buffer 149 * flags and states. We do this by making a state with absolutely no 150 * transitions. We put it at the end of the table. 151 */ 152 153 /* We need to have room in nxt/chk for two more slots: One for the 154 * action and one for the end-of-buffer transition. We now *assume* 155 * that we're guaranteed the only character we'll try to index this 156 * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure 157 * there's room for jam entries for other characters. 158 */ 159 160 while ( tblend + 2 >= current_max_xpairs ) 161 expand_nxt_chk(); 162 163 while ( lastdfa + 1 >= current_max_dfas ) 164 increase_max_dfas(); 165 166 base[lastdfa + 1] = tblend + 2; 167 nxt[tblend + 1] = end_of_buffer_action; 168 chk[tblend + 1] = numecs + 1; 169 chk[tblend + 2] = 1; /* anything but EOB */ 170 171 /* So that "make test" won't show arb. differences. */ 172 nxt[tblend + 2] = 0; 173 174 /* Make sure every state has an end-of-buffer transition and an 175 * action #. 176 */ 177 for ( i = 0; i <= lastdfa; ++i ) 178 { 179 int anum = dfaacc[i].dfaacc_state; 180 int offset = base[i]; 181 182 chk[offset] = EOB_POSITION; 183 chk[offset - 1] = ACTION_POSITION; 184 nxt[offset - 1] = anum; /* action number */ 185 } 186 187 for ( i = 0; i <= tblend; ++i ) 188 { 189 if ( chk[i] == EOB_POSITION ) 190 transition_struct_out( 0, base[lastdfa + 1] - i ); 191 192 else if ( chk[i] == ACTION_POSITION ) 193 transition_struct_out( 0, nxt[i] ); 194 195 else if ( chk[i] > numecs || chk[i] == 0 ) 196 transition_struct_out( 0, 0 ); /* unused slot */ 197 198 else /* verify, transition */ 199 transition_struct_out( chk[i], 200 base[nxt[i]] - (i - chk[i]) ); 201 } 202 203 204 /* Here's the final, end-of-buffer state. */ 205 transition_struct_out( chk[tblend + 1], nxt[tblend + 1] ); 206 transition_struct_out( chk[tblend + 2], nxt[tblend + 2] ); 207 208 outn( " };\n" ); 209 210 /* Table of pointers to start states. */ 211 out_dec( 212 "static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", 213 lastsc * 2 + 1 ); 214 outn( " {" ); /* } so vi doesn't get confused */ 215 216 for ( i = 0; i <= lastsc * 2; ++i ) 217 out_dec( " &yy_transition[%d],\n", base[i] ); 218 219 dataend(); 220 221 if ( useecs ) 222 genecs(); 223 } 224 225 226 /* Generate equivalence-class tables. */ 227 228 void genecs() 229 { 230 register int i, j; 231 int numrows; 232 233 out_str_dec( C_int_decl, "yy_ec", csize ); 234 235 for ( i = 1; i < csize; ++i ) 236 { 237 if ( caseins && (i >= 'A') && (i <= 'Z') ) 238 ecgroup[i] = ecgroup[clower( i )]; 239 240 ecgroup[i] = ABS( ecgroup[i] ); 241 mkdata( ecgroup[i] ); 242 } 243 244 dataend(); 245 246 if ( trace ) 247 { 248 fputs( _( "\n\nEquivalence Classes:\n\n" ), stderr ); 249 250 numrows = csize / 8; 251 252 for ( j = 0; j < numrows; ++j ) 253 { 254 for ( i = j; i < csize; i = i + numrows ) 255 { 256 fprintf( stderr, "%4s = %-2d", 257 readable_form( i ), ecgroup[i] ); 258 259 putc( ' ', stderr ); 260 } 261 262 putc( '\n', stderr ); 263 } 264 } 265 } 266 267 268 /* Generate the code to find the action number. */ 269 270 void gen_find_action() 271 { 272 if ( fullspd ) 273 indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" ); 274 275 else if ( fulltbl ) 276 indent_puts( "yy_act = yy_accept[yy_current_state];" ); 277 278 else if ( reject ) 279 { 280 indent_puts( "yy_current_state = *--yy_state_ptr;" ); 281 indent_puts( "yy_lp = yy_accept[yy_current_state];" ); 282 283 outn( 284 "find_rule: /* we branch to this label when backing up */" ); 285 286 indent_puts( 287 "for ( ; ; ) /* until we find what rule we matched */" ); 288 289 indent_up(); 290 291 indent_puts( "{" ); 292 293 indent_puts( 294 "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" ); 295 indent_up(); 296 indent_puts( "{" ); 297 indent_puts( "yy_act = yy_acclist[yy_lp];" ); 298 299 if ( variable_trailing_context_rules ) 300 { 301 indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" ); 302 indent_puts( " yy_looking_for_trail_begin )" ); 303 indent_up(); 304 indent_puts( "{" ); 305 306 indent_puts( 307 "if ( yy_act == yy_looking_for_trail_begin )" ); 308 indent_up(); 309 indent_puts( "{" ); 310 indent_puts( "yy_looking_for_trail_begin = 0;" ); 311 indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" ); 312 indent_puts( "break;" ); 313 indent_puts( "}" ); 314 indent_down(); 315 316 indent_puts( "}" ); 317 indent_down(); 318 319 indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" ); 320 indent_up(); 321 indent_puts( "{" ); 322 indent_puts( 323 "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" ); 324 indent_puts( 325 "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" ); 326 327 if ( real_reject ) 328 { 329 /* Remember matched text in case we back up 330 * due to REJECT. 331 */ 332 indent_puts( "yy_full_match = yy_cp;" ); 333 indent_puts( "yy_full_state = yy_state_ptr;" ); 334 indent_puts( "yy_full_lp = yy_lp;" ); 335 } 336 337 indent_puts( "}" ); 338 indent_down(); 339 340 indent_puts( "else" ); 341 indent_up(); 342 indent_puts( "{" ); 343 indent_puts( "yy_full_match = yy_cp;" ); 344 indent_puts( "yy_full_state = yy_state_ptr;" ); 345 indent_puts( "yy_full_lp = yy_lp;" ); 346 indent_puts( "break;" ); 347 indent_puts( "}" ); 348 indent_down(); 349 350 indent_puts( "++yy_lp;" ); 351 indent_puts( "goto find_rule;" ); 352 } 353 354 else 355 { 356 /* Remember matched text in case we back up due to 357 * trailing context plus REJECT. 358 */ 359 indent_up(); 360 indent_puts( "{" ); 361 indent_puts( "yy_full_match = yy_cp;" ); 362 indent_puts( "break;" ); 363 indent_puts( "}" ); 364 indent_down(); 365 } 366 367 indent_puts( "}" ); 368 indent_down(); 369 370 indent_puts( "--yy_cp;" ); 371 372 /* We could consolidate the following two lines with those at 373 * the beginning, but at the cost of complaints that we're 374 * branching inside a loop. 375 */ 376 indent_puts( "yy_current_state = *--yy_state_ptr;" ); 377 indent_puts( "yy_lp = yy_accept[yy_current_state];" ); 378 379 indent_puts( "}" ); 380 381 indent_down(); 382 } 383 384 else 385 { /* compressed */ 386 indent_puts( "yy_act = yy_accept[yy_current_state];" ); 387 388 if ( interactive && ! reject ) 389 { 390 /* Do the guaranteed-needed backing up to figure out 391 * the match. 392 */ 393 indent_puts( "if ( yy_act == 0 )" ); 394 indent_up(); 395 indent_puts( "{ /* have to back up */" ); 396 indent_puts( "yy_cp = yy_last_accepting_cpos;" ); 397 indent_puts( 398 "yy_current_state = yy_last_accepting_state;" ); 399 indent_puts( "yy_act = yy_accept[yy_current_state];" ); 400 indent_puts( "}" ); 401 indent_down(); 402 } 403 } 404 } 405 406 407 /* genftbl - generate full transition table */ 408 409 void genftbl() 410 { 411 register int i; 412 int end_of_buffer_action = num_rules + 1; 413 414 out_str_dec( long_align ? C_long_decl : C_short_decl, 415 "yy_accept", lastdfa + 1 ); 416 417 dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; 418 419 for ( i = 1; i <= lastdfa; ++i ) 420 { 421 register int anum = dfaacc[i].dfaacc_state; 422 423 mkdata( anum ); 424 425 if ( trace && anum ) 426 fprintf( stderr, _( "state # %d accepts: [%d]\n" ), 427 i, anum ); 428 } 429 430 dataend(); 431 432 if ( useecs ) 433 genecs(); 434 435 /* Don't have to dump the actual full table entries - they were 436 * created on-the-fly. 437 */ 438 } 439 440 441 /* Generate the code to find the next compressed-table state. */ 442 443 void gen_next_compressed_state( char_map ) 444 char *char_map; 445 { 446 indent_put2s( "register YY_CHAR yy_c = %s;", char_map ); 447 448 /* Save the backing-up info \before/ computing the next state 449 * because we always compute one more state than needed - we 450 * always proceed until we reach a jam state 451 */ 452 gen_backing_up(); 453 454 indent_puts( 455 "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" ); 456 indent_up(); 457 indent_puts( "{" ); 458 indent_puts( "yy_current_state = (int) yy_def[yy_current_state];" ); 459 460 if ( usemecs ) 461 { 462 /* We've arrange it so that templates are never chained 463 * to one another. This means we can afford to make a 464 * very simple test to see if we need to convert to 465 * yy_c's meta-equivalence class without worrying 466 * about erroneously looking up the meta-equivalence 467 * class twice 468 */ 469 do_indent(); 470 471 /* lastdfa + 2 is the beginning of the templates */ 472 out_dec( "if ( yy_current_state >= %d )\n", lastdfa + 2 ); 473 474 indent_up(); 475 indent_puts( "yy_c = yy_meta[(unsigned int) yy_c];" ); 476 indent_down(); 477 } 478 479 indent_puts( "}" ); 480 indent_down(); 481 482 indent_puts( 483 "yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];" ); 484 } 485 486 487 /* Generate the code to find the next match. */ 488 489 void gen_next_match() 490 { 491 /* NOTE - changes in here should be reflected in gen_next_state() and 492 * gen_NUL_trans(). 493 */ 494 char *char_map = useecs ? 495 "yy_ec[YY_SC_TO_UI(*yy_cp)]" : 496 "YY_SC_TO_UI(*yy_cp)"; 497 498 char *char_map_2 = useecs ? 499 "yy_ec[YY_SC_TO_UI(*++yy_cp)]" : 500 "YY_SC_TO_UI(*++yy_cp)"; 501 502 if ( fulltbl ) 503 { 504 indent_put2s( 505 "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )", 506 char_map ); 507 508 indent_up(); 509 510 if ( num_backing_up > 0 ) 511 { 512 indent_puts( "{" ); /* } for vi */ 513 gen_backing_up(); 514 outc( '\n' ); 515 } 516 517 indent_puts( "++yy_cp;" ); 518 519 if ( num_backing_up > 0 ) 520 /* { for vi */ 521 indent_puts( "}" ); 522 523 indent_down(); 524 525 outc( '\n' ); 526 indent_puts( "yy_current_state = -yy_current_state;" ); 527 } 528 529 else if ( fullspd ) 530 { 531 indent_puts( "{" ); /* } for vi */ 532 indent_puts( 533 "register yyconst struct yy_trans_info *yy_trans_info;\n" ); 534 indent_puts( "register YY_CHAR yy_c;\n" ); 535 indent_put2s( "for ( yy_c = %s;", char_map ); 536 indent_puts( 537 " (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->" ); 538 indent_puts( "yy_verify == yy_c;" ); 539 indent_put2s( " yy_c = %s )", char_map_2 ); 540 541 indent_up(); 542 543 if ( num_backing_up > 0 ) 544 indent_puts( "{" ); /* } for vi */ 545 546 indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); 547 548 if ( num_backing_up > 0 ) 549 { 550 outc( '\n' ); 551 gen_backing_up(); /* { for vi */ 552 indent_puts( "}" ); 553 } 554 555 indent_down(); /* { for vi */ 556 indent_puts( "}" ); 557 } 558 559 else 560 { /* compressed */ 561 indent_puts( "do" ); 562 563 indent_up(); 564 indent_puts( "{" ); /* } for vi */ 565 566 gen_next_state( false ); 567 568 indent_puts( "++yy_cp;" ); 569 570 /* { for vi */ 571 indent_puts( "}" ); 572 indent_down(); 573 574 do_indent(); 575 576 if ( interactive ) 577 out_dec( "while ( yy_base[yy_current_state] != %d );\n", 578 jambase ); 579 else 580 out_dec( "while ( yy_current_state != %d );\n", 581 jamstate ); 582 583 if ( ! reject && ! interactive ) 584 { 585 /* Do the guaranteed-needed backing up to figure out 586 * the match. 587 */ 588 indent_puts( "yy_cp = yy_last_accepting_cpos;" ); 589 indent_puts( 590 "yy_current_state = yy_last_accepting_state;" ); 591 } 592 } 593 } 594 595 596 /* Generate the code to find the next state. */ 597 598 void gen_next_state( worry_about_NULs ) 599 int worry_about_NULs; 600 { /* NOTE - changes in here should be reflected in gen_next_match() */ 601 char char_map[256]; 602 603 if ( worry_about_NULs && ! nultrans ) 604 { 605 if ( useecs ) 606 (void) sprintf( char_map, 607 "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)", 608 NUL_ec ); 609 else 610 (void) sprintf( char_map, 611 "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)", NUL_ec ); 612 } 613 614 else 615 strcpy( char_map, useecs ? 616 "yy_ec[YY_SC_TO_UI(*yy_cp)]" : "YY_SC_TO_UI(*yy_cp)" ); 617 618 if ( worry_about_NULs && nultrans ) 619 { 620 if ( ! fulltbl && ! fullspd ) 621 /* Compressed tables back up *before* they match. */ 622 gen_backing_up(); 623 624 indent_puts( "if ( *yy_cp )" ); 625 indent_up(); 626 indent_puts( "{" ); /* } for vi */ 627 } 628 629 if ( fulltbl ) 630 indent_put2s( 631 "yy_current_state = yy_nxt[yy_current_state][%s];", 632 char_map ); 633 634 else if ( fullspd ) 635 indent_put2s( 636 "yy_current_state += yy_current_state[%s].yy_nxt;", 637 char_map ); 638 639 else 640 gen_next_compressed_state( char_map ); 641 642 if ( worry_about_NULs && nultrans ) 643 { 644 /* { for vi */ 645 indent_puts( "}" ); 646 indent_down(); 647 indent_puts( "else" ); 648 indent_up(); 649 indent_puts( 650 "yy_current_state = yy_NUL_trans[yy_current_state];" ); 651 indent_down(); 652 } 653 654 if ( fullspd || fulltbl ) 655 gen_backing_up(); 656 657 if ( reject ) 658 indent_puts( "*yy_state_ptr++ = yy_current_state;" ); 659 } 660 661 662 /* Generate the code to make a NUL transition. */ 663 664 void gen_NUL_trans() 665 { /* NOTE - changes in here should be reflected in gen_next_match() */ 666 /* Only generate a definition for "yy_cp" if we'll generate code 667 * that uses it. Otherwise lint and the like complain. 668 */ 669 int need_backing_up = (num_backing_up > 0 && ! reject); 670 671 if ( need_backing_up && (! nultrans || fullspd || fulltbl) ) 672 /* We're going to need yy_cp lying around for the call 673 * below to gen_backing_up(). 674 */ 675 indent_puts( "register char *yy_cp = yy_c_buf_p;" ); 676 677 outc( '\n' ); 678 679 if ( nultrans ) 680 { 681 indent_puts( 682 "yy_current_state = yy_NUL_trans[yy_current_state];" ); 683 indent_puts( "yy_is_jam = (yy_current_state == 0);" ); 684 } 685 686 else if ( fulltbl ) 687 { 688 do_indent(); 689 out_dec( "yy_current_state = yy_nxt[yy_current_state][%d];\n", 690 NUL_ec ); 691 indent_puts( "yy_is_jam = (yy_current_state <= 0);" ); 692 } 693 694 else if ( fullspd ) 695 { 696 do_indent(); 697 out_dec( "register int yy_c = %d;\n", NUL_ec ); 698 699 indent_puts( 700 "register yyconst struct yy_trans_info *yy_trans_info;\n" ); 701 indent_puts( 702 "yy_trans_info = &yy_current_state[(unsigned int) yy_c];" ); 703 indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); 704 705 indent_puts( 706 "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" ); 707 } 708 709 else 710 { 711 char NUL_ec_str[20]; 712 713 (void) sprintf( NUL_ec_str, "%d", NUL_ec ); 714 gen_next_compressed_state( NUL_ec_str ); 715 716 do_indent(); 717 out_dec( "yy_is_jam = (yy_current_state == %d);\n", jamstate ); 718 719 if ( reject ) 720 { 721 /* Only stack this state if it's a transition we 722 * actually make. If we stack it on a jam, then 723 * the state stack and yy_c_buf_p get out of sync. 724 */ 725 indent_puts( "if ( ! yy_is_jam )" ); 726 indent_up(); 727 indent_puts( "*yy_state_ptr++ = yy_current_state;" ); 728 indent_down(); 729 } 730 } 731 732 /* If we've entered an accepting state, back up; note that 733 * compressed tables have *already* done such backing up, so 734 * we needn't bother with it again. 735 */ 736 if ( need_backing_up && (fullspd || fulltbl) ) 737 { 738 outc( '\n' ); 739 indent_puts( "if ( ! yy_is_jam )" ); 740 indent_up(); 741 indent_puts( "{" ); 742 gen_backing_up(); 743 indent_puts( "}" ); 744 indent_down(); 745 } 746 } 747 748 749 /* Generate the code to find the start state. */ 750 751 void gen_start_state() 752 { 753 if ( fullspd ) 754 { 755 if ( bol_needed ) 756 { 757 indent_puts( 758 "yy_current_state = yy_start_state_list[yy_start + YY_AT_BOL()];" ); 759 } 760 else 761 indent_puts( 762 "yy_current_state = yy_start_state_list[yy_start];" ); 763 } 764 765 else 766 { 767 indent_puts( "yy_current_state = yy_start;" ); 768 769 if ( bol_needed ) 770 indent_puts( "yy_current_state += YY_AT_BOL();" ); 771 772 if ( reject ) 773 { 774 /* Set up for storing up states. */ 775 indent_puts( "yy_state_ptr = yy_state_buf;" ); 776 indent_puts( "*yy_state_ptr++ = yy_current_state;" ); 777 } 778 } 779 } 780 781 782 /* gentabs - generate data statements for the transition tables */ 783 784 void gentabs() 785 { 786 int i, j, k, *accset, nacc, *acc_array, total_states; 787 int end_of_buffer_action = num_rules + 1; 788 789 acc_array = allocate_integer_array( current_max_dfas ); 790 nummt = 0; 791 792 /* The compressed table format jams by entering the "jam state", 793 * losing information about the previous state in the process. 794 * In order to recover the previous state, we effectively need 795 * to keep backing-up information. 796 */ 797 ++num_backing_up; 798 799 if ( reject ) 800 { 801 /* Write out accepting list and pointer list. 802 * 803 * First we generate the "yy_acclist" array. In the process, 804 * we compute the indices that will go into the "yy_accept" 805 * array, and save the indices in the dfaacc array. 806 */ 807 int EOB_accepting_list[2]; 808 809 /* Set up accepting structures for the End Of Buffer state. */ 810 EOB_accepting_list[0] = 0; 811 EOB_accepting_list[1] = end_of_buffer_action; 812 accsiz[end_of_buffer_state] = 1; 813 dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list; 814 815 out_str_dec( long_align ? C_long_decl : C_short_decl, 816 "yy_acclist", MAX( numas, 1 ) + 1 ); 817 818 j = 1; /* index into "yy_acclist" array */ 819 820 for ( i = 1; i <= lastdfa; ++i ) 821 { 822 acc_array[i] = j; 823 824 if ( accsiz[i] != 0 ) 825 { 826 accset = dfaacc[i].dfaacc_set; 827 nacc = accsiz[i]; 828 829 if ( trace ) 830 fprintf( stderr, 831 _( "state # %d accepts: " ), 832 i ); 833 834 for ( k = 1; k <= nacc; ++k ) 835 { 836 int accnum = accset[k]; 837 838 ++j; 839 840 if ( variable_trailing_context_rules && 841 ! (accnum & YY_TRAILING_HEAD_MASK) && 842 accnum > 0 && accnum <= num_rules && 843 rule_type[accnum] == RULE_VARIABLE ) 844 { 845 /* Special hack to flag 846 * accepting number as part 847 * of trailing context rule. 848 */ 849 accnum |= YY_TRAILING_MASK; 850 } 851 852 mkdata( accnum ); 853 854 if ( trace ) 855 { 856 fprintf( stderr, "[%d]", 857 accset[k] ); 858 859 if ( k < nacc ) 860 fputs( ", ", stderr ); 861 else 862 putc( '\n', stderr ); 863 } 864 } 865 } 866 } 867 868 /* add accepting number for the "jam" state */ 869 acc_array[i] = j; 870 871 dataend(); 872 } 873 874 else 875 { 876 dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; 877 878 for ( i = 1; i <= lastdfa; ++i ) 879 acc_array[i] = dfaacc[i].dfaacc_state; 880 881 /* add accepting number for jam state */ 882 acc_array[i] = 0; 883 } 884 885 /* Spit out "yy_accept" array. If we're doing "reject", it'll be 886 * pointers into the "yy_acclist" array. Otherwise it's actual 887 * accepting numbers. In either case, we just dump the numbers. 888 */ 889 890 /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays 891 * beginning at 0 and for "jam" state. 892 */ 893 k = lastdfa + 2; 894 895 if ( reject ) 896 /* We put a "cap" on the table associating lists of accepting 897 * numbers with state numbers. This is needed because we tell 898 * where the end of an accepting list is by looking at where 899 * the list for the next state starts. 900 */ 901 ++k; 902 903 out_str_dec( long_align ? C_long_decl : C_short_decl, "yy_accept", k ); 904 905 for ( i = 1; i <= lastdfa; ++i ) 906 { 907 mkdata( acc_array[i] ); 908 909 if ( ! reject && trace && acc_array[i] ) 910 fprintf( stderr, _( "state # %d accepts: [%d]\n" ), 911 i, acc_array[i] ); 912 } 913 914 /* Add entry for "jam" state. */ 915 mkdata( acc_array[i] ); 916 917 if ( reject ) 918 /* Add "cap" for the list. */ 919 mkdata( acc_array[i] ); 920 921 dataend(); 922 923 if ( useecs ) 924 genecs(); 925 926 if ( usemecs ) 927 { 928 /* Write out meta-equivalence classes (used to index 929 * templates with). 930 */ 931 932 if ( trace ) 933 fputs( _( "\n\nMeta-Equivalence Classes:\n" ), 934 stderr ); 935 936 out_str_dec( C_int_decl, "yy_meta", numecs + 1 ); 937 938 for ( i = 1; i <= numecs; ++i ) 939 { 940 if ( trace ) 941 fprintf( stderr, "%d = %d\n", 942 i, ABS( tecbck[i] ) ); 943 944 mkdata( ABS( tecbck[i] ) ); 945 } 946 947 dataend(); 948 } 949 950 total_states = lastdfa + numtemps; 951 952 out_str_dec( (tblend >= MAX_SHORT || long_align) ? 953 C_long_decl : C_short_decl, 954 "yy_base", total_states + 1 ); 955 956 for ( i = 1; i <= lastdfa; ++i ) 957 { 958 register int d = def[i]; 959 960 if ( base[i] == JAMSTATE ) 961 base[i] = jambase; 962 963 if ( d == JAMSTATE ) 964 def[i] = jamstate; 965 966 else if ( d < 0 ) 967 { 968 /* Template reference. */ 969 ++tmpuses; 970 def[i] = lastdfa - d + 1; 971 } 972 973 mkdata( base[i] ); 974 } 975 976 /* Generate jam state's base index. */ 977 mkdata( base[i] ); 978 979 for ( ++i /* skip jam state */; i <= total_states; ++i ) 980 { 981 mkdata( base[i] ); 982 def[i] = jamstate; 983 } 984 985 dataend(); 986 987 out_str_dec( (total_states >= MAX_SHORT || long_align) ? 988 C_long_decl : C_short_decl, 989 "yy_def", total_states + 1 ); 990 991 for ( i = 1; i <= total_states; ++i ) 992 mkdata( def[i] ); 993 994 dataend(); 995 996 out_str_dec( (total_states >= MAX_SHORT || long_align) ? 997 C_long_decl : C_short_decl, 998 "yy_nxt", tblend + 1 ); 999 1000 for ( i = 1; i <= tblend; ++i ) 1001 { 1002 /* Note, the order of the following test is important. 1003 * If chk[i] is 0, then nxt[i] is undefined. 1004 */ 1005 if ( chk[i] == 0 || nxt[i] == 0 ) 1006 nxt[i] = jamstate; /* new state is the JAM state */ 1007 1008 mkdata( nxt[i] ); 1009 } 1010 1011 dataend(); 1012 1013 out_str_dec( (total_states >= MAX_SHORT || long_align) ? 1014 C_long_decl : C_short_decl, 1015 "yy_chk", tblend + 1 ); 1016 1017 for ( i = 1; i <= tblend; ++i ) 1018 { 1019 if ( chk[i] == 0 ) 1020 ++nummt; 1021 1022 mkdata( chk[i] ); 1023 } 1024 1025 dataend(); 1026 } 1027 1028 1029 /* Write out a formatted string (with a secondary string argument) at the 1030 * current indentation level, adding a final newline. 1031 */ 1032 1033 void indent_put2s( fmt, arg ) 1034 char fmt[], arg[]; 1035 { 1036 do_indent(); 1037 out_str( fmt, arg ); 1038 outn( "" ); 1039 } 1040 1041 1042 /* Write out a string at the current indentation level, adding a final 1043 * newline. 1044 */ 1045 1046 void indent_puts( str ) 1047 char str[]; 1048 { 1049 do_indent(); 1050 outn( str ); 1051 } 1052 1053 1054 /* make_tables - generate transition tables and finishes generating output file 1055 */ 1056 1057 void make_tables() 1058 { 1059 register int i; 1060 int did_eof_rule = false; 1061 1062 skelout(); 1063 1064 /* First, take care of YY_DO_BEFORE_ACTION depending on yymore 1065 * being used. 1066 */ 1067 set_indent( 1 ); 1068 1069 if ( yymore_used && ! yytext_is_array ) 1070 { 1071 indent_puts( "yytext_ptr -= yy_more_len; \\" ); 1072 indent_puts( "yyleng = (int) (yy_cp - yytext_ptr); \\" ); 1073 } 1074 1075 else 1076 indent_puts( "yyleng = (int) (yy_cp - yy_bp); \\" ); 1077 1078 /* Now also deal with copying yytext_ptr to yytext if needed. */ 1079 skelout(); 1080 if ( yytext_is_array ) 1081 { 1082 if ( yymore_used ) 1083 indent_puts( 1084 "if ( yyleng + yy_more_offset >= YYLMAX ) \\" ); 1085 else 1086 indent_puts( "if ( yyleng >= YYLMAX ) \\" ); 1087 1088 indent_up(); 1089 indent_puts( 1090 "YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\" ); 1091 indent_down(); 1092 1093 if ( yymore_used ) 1094 { 1095 indent_puts( 1096 "yy_flex_strncpy( &yytext[yy_more_offset], yytext_ptr, yyleng + 1 ); \\" ); 1097 indent_puts( "yyleng += yy_more_offset; \\" ); 1098 indent_puts( 1099 "yy_prev_more_offset = yy_more_offset; \\" ); 1100 indent_puts( "yy_more_offset = 0; \\" ); 1101 } 1102 else 1103 { 1104 indent_puts( 1105 "yy_flex_strncpy( yytext, yytext_ptr, yyleng + 1 ); \\" ); 1106 } 1107 } 1108 1109 set_indent( 0 ); 1110 1111 skelout(); 1112 1113 1114 out_dec( "#define YY_NUM_RULES %d\n", num_rules ); 1115 out_dec( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 ); 1116 1117 if ( fullspd ) 1118 { 1119 /* Need to define the transet type as a size large 1120 * enough to hold the biggest offset. 1121 */ 1122 int total_table_size = tblend + numecs + 1; 1123 char *trans_offset_type = 1124 (total_table_size >= MAX_SHORT || long_align) ? 1125 "long" : "short"; 1126 1127 set_indent( 0 ); 1128 indent_puts( "struct yy_trans_info" ); 1129 indent_up(); 1130 indent_puts( "{" ); /* } for vi */ 1131 1132 if ( long_align ) 1133 indent_puts( "long yy_verify;" ); 1134 else 1135 indent_puts( "short yy_verify;" ); 1136 1137 /* In cases where its sister yy_verify *is* a "yes, there is 1138 * a transition", yy_nxt is the offset (in records) to the 1139 * next state. In most cases where there is no transition, 1140 * the value of yy_nxt is irrelevant. If yy_nxt is the -1th 1141 * record of a state, though, then yy_nxt is the action number 1142 * for that state. 1143 */ 1144 1145 indent_put2s( "%s yy_nxt;", trans_offset_type ); 1146 indent_puts( "};" ); 1147 indent_down(); 1148 } 1149 1150 if ( fullspd ) 1151 genctbl(); 1152 else if ( fulltbl ) 1153 genftbl(); 1154 else 1155 gentabs(); 1156 1157 /* Definitions for backing up. We don't need them if REJECT 1158 * is being used because then we use an alternative backin-up 1159 * technique instead. 1160 */ 1161 if ( num_backing_up > 0 && ! reject ) 1162 { 1163 if ( ! C_plus_plus ) 1164 { 1165 indent_puts( 1166 "static yy_state_type yy_last_accepting_state;" ); 1167 indent_puts( 1168 "static char *yy_last_accepting_cpos;\n" ); 1169 } 1170 } 1171 1172 if ( nultrans ) 1173 { 1174 out_str_dec( C_state_decl, "yy_NUL_trans", lastdfa + 1 ); 1175 1176 for ( i = 1; i <= lastdfa; ++i ) 1177 { 1178 if ( fullspd ) 1179 out_dec( " &yy_transition[%d],\n", base[i] ); 1180 else 1181 mkdata( nultrans[i] ); 1182 } 1183 1184 dataend(); 1185 } 1186 1187 if ( ddebug ) 1188 { /* Spit out table mapping rules to line numbers. */ 1189 if ( ! C_plus_plus ) 1190 { 1191 indent_puts( "extern int yy_flex_debug;" ); 1192 indent_puts( "int yy_flex_debug = 1;\n" ); 1193 } 1194 1195 out_str_dec( long_align ? C_long_decl : C_short_decl, 1196 "yy_rule_linenum", num_rules ); 1197 for ( i = 1; i < num_rules; ++i ) 1198 mkdata( rule_linenum[i] ); 1199 dataend(); 1200 } 1201 1202 if ( reject ) 1203 { 1204 /* Declare state buffer variables. */ 1205 if ( ! C_plus_plus ) 1206 { 1207 outn( 1208 "static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" ); 1209 outn( "static char *yy_full_match;" ); 1210 outn( "static int yy_lp;" ); 1211 } 1212 1213 if ( variable_trailing_context_rules ) 1214 { 1215 if ( ! C_plus_plus ) 1216 { 1217 outn( 1218 "static int yy_looking_for_trail_begin = 0;" ); 1219 outn( "static int yy_full_lp;" ); 1220 outn( "static int *yy_full_state;" ); 1221 } 1222 1223 out_hex( "#define YY_TRAILING_MASK 0x%x\n", 1224 (unsigned int) YY_TRAILING_MASK ); 1225 out_hex( "#define YY_TRAILING_HEAD_MASK 0x%x\n", 1226 (unsigned int) YY_TRAILING_HEAD_MASK ); 1227 } 1228 1229 outn( "#define REJECT \\" ); 1230 outn( "{ \\" ); /* } for vi */ 1231 outn( 1232 "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" ); 1233 outn( 1234 "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" ); 1235 1236 if ( variable_trailing_context_rules ) 1237 { 1238 outn( 1239 "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" ); 1240 outn( 1241 "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" ); 1242 outn( 1243 "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" ); 1244 } 1245 1246 outn( "++yy_lp; \\" ); 1247 outn( "goto find_rule; \\" ); 1248 /* { for vi */ 1249 outn( "}" ); 1250 } 1251 1252 else 1253 { 1254 outn( 1255 "/* The intent behind this definition is that it'll catch" ); 1256 outn( " * any uses of REJECT which flex missed." ); 1257 outn( " */" ); 1258 outn( "#define REJECT reject_used_but_not_detected" ); 1259 } 1260 1261 if ( yymore_used ) 1262 { 1263 if ( ! C_plus_plus ) 1264 { 1265 if ( yytext_is_array ) 1266 { 1267 indent_puts( "static int yy_more_offset = 0;" ); 1268 indent_puts( 1269 "static int yy_prev_more_offset = 0;" ); 1270 } 1271 else 1272 { 1273 indent_puts( "static int yy_more_flag = 0;" ); 1274 indent_puts( "static int yy_more_len = 0;" ); 1275 } 1276 } 1277 1278 if ( yytext_is_array ) 1279 { 1280 indent_puts( 1281 "#define yymore() (yy_more_offset = yy_flex_strlen( yytext ))" ); 1282 indent_puts( "#define YY_NEED_STRLEN" ); 1283 indent_puts( "#define YY_MORE_ADJ 0" ); 1284 indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET \\" ); 1285 indent_up(); 1286 indent_puts( "{ \\" ); 1287 indent_puts( "yy_more_offset = yy_prev_more_offset; \\" ); 1288 indent_puts( "yyleng -= yy_more_offset; \\" ); 1289 indent_puts( "}" ); 1290 indent_down(); 1291 } 1292 else 1293 { 1294 indent_puts( "#define yymore() (yy_more_flag = 1)" ); 1295 indent_puts( "#define YY_MORE_ADJ yy_more_len" ); 1296 indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET" ); 1297 } 1298 } 1299 1300 else 1301 { 1302 indent_puts( "#define yymore() yymore_used_but_not_detected" ); 1303 indent_puts( "#define YY_MORE_ADJ 0" ); 1304 indent_puts( "#define YY_RESTORE_YY_MORE_OFFSET" ); 1305 } 1306 1307 if ( ! C_plus_plus ) 1308 { 1309 if ( yytext_is_array ) 1310 { 1311 outn( "#ifndef YYLMAX" ); 1312 outn( "#define YYLMAX 8192" ); 1313 outn( "#endif\n" ); 1314 outn( "char yytext[YYLMAX];" ); 1315 outn( "char *yytext_ptr;" ); 1316 } 1317 1318 else 1319 outn( "char *yytext;" ); 1320 } 1321 1322 out( &action_array[defs1_offset] ); 1323 1324 line_directive_out( stdout, 0 ); 1325 1326 skelout(); 1327 1328 if ( ! C_plus_plus ) 1329 { 1330 if ( use_read ) 1331 { 1332 outn( 1333 "\tif ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\" ); 1334 outn( 1335 "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );" ); 1336 } 1337 1338 else 1339 { 1340 outn( 1341 "\tif ( yy_current_buffer->yy_is_interactive ) \\" ); 1342 outn( "\t\t{ \\" ); 1343 outn( "\t\tint c = '*', n; \\" ); 1344 outn( "\t\tfor ( n = 0; n < max_size && \\" ); 1345 outn( "\t\t\t (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\" ); 1346 outn( "\t\t\tbuf[n] = (char) c; \\" ); 1347 outn( "\t\tif ( c == '\\n' ) \\" ); 1348 outn( "\t\t\tbuf[n++] = (char) c; \\" ); 1349 outn( "\t\tif ( c == EOF && ferror( yyin ) ) \\" ); 1350 outn( 1351 "\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\" ); 1352 outn( "\t\tresult = n; \\" ); 1353 outn( "\t\t} \\" ); 1354 outn( 1355 "\telse if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \\" ); 1356 outn( "\t\t && ferror( yyin ) ) \\" ); 1357 outn( 1358 "\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" );" ); 1359 } 1360 } 1361 1362 skelout(); 1363 1364 indent_puts( "#define YY_RULE_SETUP \\" ); 1365 indent_up(); 1366 if ( bol_needed ) 1367 { 1368 indent_puts( "if ( yyleng > 0 ) \\" ); 1369 indent_up(); 1370 indent_puts( "yy_current_buffer->yy_at_bol = \\" ); 1371 indent_puts( "\t\t(yytext[yyleng - 1] == '\\n'); \\" ); 1372 indent_down(); 1373 } 1374 indent_puts( "YY_USER_ACTION" ); 1375 indent_down(); 1376 1377 skelout(); 1378 1379 /* Copy prolog to output file. */ 1380 out( &action_array[prolog_offset] ); 1381 1382 line_directive_out( stdout, 0 ); 1383 1384 skelout(); 1385 1386 set_indent( 2 ); 1387 1388 if ( yymore_used && ! yytext_is_array ) 1389 { 1390 indent_puts( "yy_more_len = 0;" ); 1391 indent_puts( "if ( yy_more_flag )" ); 1392 indent_up(); 1393 indent_puts( "{" ); 1394 indent_puts( "yy_more_len = yy_c_buf_p - yytext_ptr;" ); 1395 indent_puts( "yy_more_flag = 0;" ); 1396 indent_puts( "}" ); 1397 indent_down(); 1398 } 1399 1400 skelout(); 1401 1402 gen_start_state(); 1403 1404 /* Note, don't use any indentation. */ 1405 outn( "yy_match:" ); 1406 gen_next_match(); 1407 1408 skelout(); 1409 set_indent( 2 ); 1410 gen_find_action(); 1411 1412 skelout(); 1413 if ( do_yylineno ) 1414 { 1415 indent_puts( "if ( yy_act != YY_END_OF_BUFFER )" ); 1416 indent_up(); 1417 indent_puts( "{" ); 1418 indent_puts( "int yyl;" ); 1419 indent_puts( "for ( yyl = 0; yyl < yyleng; ++yyl )" ); 1420 indent_up(); 1421 indent_puts( "if ( yytext[yyl] == '\\n' )" ); 1422 indent_up(); 1423 indent_puts( "++yylineno;" ); 1424 indent_down(); 1425 indent_down(); 1426 indent_puts( "}" ); 1427 indent_down(); 1428 } 1429 1430 skelout(); 1431 if ( ddebug ) 1432 { 1433 indent_puts( "if ( yy_flex_debug )" ); 1434 indent_up(); 1435 1436 indent_puts( "{" ); 1437 indent_puts( "if ( yy_act == 0 )" ); 1438 indent_up(); 1439 indent_puts( C_plus_plus ? 1440 "cerr << \"--scanner backing up\\n\";" : 1441 "fprintf( stderr, \"--scanner backing up\\n\" );" ); 1442 indent_down(); 1443 1444 do_indent(); 1445 out_dec( "else if ( yy_act < %d )\n", num_rules ); 1446 indent_up(); 1447 1448 if ( C_plus_plus ) 1449 { 1450 indent_puts( 1451 "cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<" ); 1452 indent_puts( 1453 " \"(\\\"\" << yytext << \"\\\")\\n\";" ); 1454 } 1455 else 1456 { 1457 indent_puts( 1458 "fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," ); 1459 1460 indent_puts( 1461 " yy_rule_linenum[yy_act], yytext );" ); 1462 } 1463 1464 indent_down(); 1465 1466 do_indent(); 1467 out_dec( "else if ( yy_act == %d )\n", num_rules ); 1468 indent_up(); 1469 1470 if ( C_plus_plus ) 1471 { 1472 indent_puts( 1473 "cerr << \"--accepting default rule (\\\"\" << yytext << \"\\\")\\n\";" ); 1474 } 1475 else 1476 { 1477 indent_puts( 1478 "fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," ); 1479 indent_puts( " yytext );" ); 1480 } 1481 1482 indent_down(); 1483 1484 do_indent(); 1485 out_dec( "else if ( yy_act == %d )\n", num_rules + 1 ); 1486 indent_up(); 1487 1488 indent_puts( C_plus_plus ? 1489 "cerr << \"--(end of buffer or a NUL)\\n\";" : 1490 "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" ); 1491 1492 indent_down(); 1493 1494 do_indent(); 1495 outn( "else" ); 1496 indent_up(); 1497 1498 if ( C_plus_plus ) 1499 { 1500 indent_puts( 1501 "cerr << \"--EOF (start condition \" << YY_START << \")\\n\";" ); 1502 } 1503 else 1504 { 1505 indent_puts( 1506 "fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );" ); 1507 } 1508 1509 indent_down(); 1510 1511 indent_puts( "}" ); 1512 indent_down(); 1513 } 1514 1515 /* Copy actions to output file. */ 1516 skelout(); 1517 indent_up(); 1518 gen_bu_action(); 1519 out( &action_array[action_offset] ); 1520 1521 line_directive_out( stdout, 0 ); 1522 1523 /* generate cases for any missing EOF rules */ 1524 for ( i = 1; i <= lastsc; ++i ) 1525 if ( ! sceof[i] ) 1526 { 1527 do_indent(); 1528 out_str( "case YY_STATE_EOF(%s):\n", scname[i] ); 1529 did_eof_rule = true; 1530 } 1531 1532 if ( did_eof_rule ) 1533 { 1534 indent_up(); 1535 indent_puts( "yyterminate();" ); 1536 indent_down(); 1537 } 1538 1539 1540 /* Generate code for handling NUL's, if needed. */ 1541 1542 /* First, deal with backing up and setting up yy_cp if the scanner 1543 * finds that it should JAM on the NUL. 1544 */ 1545 skelout(); 1546 set_indent( 4 ); 1547 1548 if ( fullspd || fulltbl ) 1549 indent_puts( "yy_cp = yy_c_buf_p;" ); 1550 1551 else 1552 { /* compressed table */ 1553 if ( ! reject && ! interactive ) 1554 { 1555 /* Do the guaranteed-needed backing up to figure 1556 * out the match. 1557 */ 1558 indent_puts( "yy_cp = yy_last_accepting_cpos;" ); 1559 indent_puts( 1560 "yy_current_state = yy_last_accepting_state;" ); 1561 } 1562 1563 else 1564 /* Still need to initialize yy_cp, though 1565 * yy_current_state was set up by 1566 * yy_get_previous_state(). 1567 */ 1568 indent_puts( "yy_cp = yy_c_buf_p;" ); 1569 } 1570 1571 1572 /* Generate code for yy_get_previous_state(). */ 1573 set_indent( 1 ); 1574 skelout(); 1575 1576 gen_start_state(); 1577 1578 set_indent( 2 ); 1579 skelout(); 1580 gen_next_state( true ); 1581 1582 set_indent( 1 ); 1583 skelout(); 1584 gen_NUL_trans(); 1585 1586 skelout(); 1587 if ( do_yylineno ) 1588 { /* update yylineno inside of unput() */ 1589 indent_puts( "if ( c == '\\n' )" ); 1590 indent_up(); 1591 indent_puts( "--yylineno;" ); 1592 indent_down(); 1593 } 1594 1595 skelout(); 1596 /* Update BOL and yylineno inside of input(). */ 1597 if ( bol_needed ) 1598 { 1599 indent_puts( "yy_current_buffer->yy_at_bol = (c == '\\n');" ); 1600 if ( do_yylineno ) 1601 { 1602 indent_puts( "if ( yy_current_buffer->yy_at_bol )" ); 1603 indent_up(); 1604 indent_puts( "++yylineno;" ); 1605 indent_down(); 1606 } 1607 } 1608 1609 else if ( do_yylineno ) 1610 { 1611 indent_puts( "if ( c == '\\n' )" ); 1612 indent_up(); 1613 indent_puts( "++yylineno;" ); 1614 indent_down(); 1615 } 1616 1617 skelout(); 1618 1619 /* Copy remainder of input to output. */ 1620 1621 line_directive_out( stdout, 1 ); 1622 1623 if ( sectnum == 3 ) 1624 (void) flexscan(); /* copy remainder of input to output */ 1625 } 1626