1 /* $OpenBSD: gen.c,v 1.16 2024/11/09 18:03:44 op Exp $ */ 2 3 /* gen - actual generation (writing) of flex scanners */ 4 5 /* Copyright (c) 1990 The Regents of the University of California. */ 6 /* All rights reserved. */ 7 8 /* This code is derived from software contributed to Berkeley by */ 9 /* Vern Paxson. */ 10 11 /* The United States Government has rights in this work pursuant */ 12 /* to contract no. DE-AC03-76SF00098 between the United States */ 13 /* Department of Energy and the University of California. */ 14 15 /* This file is part of flex. */ 16 17 /* Redistribution and use in source and binary forms, with or without */ 18 /* modification, are permitted provided that the following conditions */ 19 /* are met: */ 20 21 /* 1. Redistributions of source code must retain the above copyright */ 22 /* notice, this list of conditions and the following disclaimer. */ 23 /* 2. Redistributions in binary form must reproduce the above copyright */ 24 /* notice, this list of conditions and the following disclaimer in the */ 25 /* documentation and/or other materials provided with the distribution. */ 26 27 /* Neither the name of the University nor the names of its contributors */ 28 /* may be used to endorse or promote products derived from this software */ 29 /* without specific prior written permission. */ 30 31 /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ 32 /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ 33 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ 34 /* PURPOSE. */ 35 36 #include "flexdef.h" 37 #include "tables.h" 38 39 40 /* declare functions that have forward references */ 41 42 void gen_next_state PROTO((int)); 43 void genecs PROTO((void)); 44 void indent_put2s PROTO((const char *, const char *)); 45 void indent_puts PROTO((const char *)); 46 47 48 static int indent_level = 0; /* each level is 8 spaces */ 49 50 #define indent_up() (++indent_level) 51 #define indent_down() (--indent_level) 52 #define set_indent(indent_val) indent_level = indent_val 53 54 /* Almost everything is done in terms of arrays starting at 1, so provide 55 * a null entry for the zero element of all C arrays. (The exception 56 * to this is that the fast table representation generally uses the 57 * 0 elements of its arrays, too.) 58 */ 59 60 static const char * 61 get_int16_decl(void) 62 { 63 return (gentables) 64 ? "static yyconst flex_int16_t %s[%d] =\n { 0,\n" 65 : "static yyconst flex_int16_t * %s = 0;\n"; 66 } 67 68 69 static const char * 70 get_int32_decl(void) 71 { 72 return (gentables) 73 ? "static yyconst flex_int32_t %s[%d] =\n { 0,\n" 74 : "static yyconst flex_int32_t * %s = 0;\n"; 75 } 76 77 static const char * 78 get_state_decl(void) 79 { 80 return (gentables) 81 ? "static yyconst yy_state_type %s[%d] =\n { 0,\n" 82 : "static yyconst yy_state_type * %s = 0;\n"; 83 } 84 85 /* Indent to the current level. */ 86 87 void 88 do_indent(void) 89 { 90 int i = indent_level * 8; 91 92 while (i >= 8) { 93 outc('\t'); 94 i -= 8; 95 } 96 97 while (i > 0) { 98 outc(' '); 99 --i; 100 } 101 } 102 103 104 /** Make the table for possible eol matches. 105 * @return the newly allocated rule_can_match_eol table 106 */ 107 static struct yytbl_data * 108 mkeoltbl(void) 109 { 110 int i; 111 flex_int8_t *tdata = NULL; 112 struct yytbl_data *tbl; 113 114 tbl = calloc(1, sizeof(struct yytbl_data)); 115 yytbl_data_init(tbl, YYTD_ID_RULE_CAN_MATCH_EOL); 116 tbl->td_flags = YYTD_DATA8; 117 tbl->td_lolen = num_rules + 1; 118 tbl->td_data = tdata = 119 calloc(tbl->td_lolen, sizeof(flex_int8_t)); 120 121 for (i = 1; i <= num_rules; i++) 122 tdata[i] = rule_has_nl[i] ? 1 : 0; 123 124 buf_prints(&yydmap_buf, 125 "\t{YYTD_ID_RULE_CAN_MATCH_EOL, (void**)&yy_rule_can_match_eol, sizeof(%s)},\n", 126 "flex_int32_t"); 127 return tbl; 128 } 129 130 /* Generate the table for possible eol matches. */ 131 static void 132 geneoltbl(void) 133 { 134 int i; 135 136 outn("m4_ifdef( [[M4_YY_USE_LINENO]],[["); 137 outn("/* Table of booleans, true if rule could match eol. */"); 138 out_str_dec(get_int32_decl(), "yy_rule_can_match_eol", 139 num_rules + 1); 140 141 if (gentables) { 142 for (i = 1; i <= num_rules; i++) { 143 out_dec("%d, ", rule_has_nl[i] ? 1 : 0); 144 /* format nicely, 20 numbers per line. */ 145 if ((i % 20) == 19) 146 out("\n "); 147 } 148 out(" };\n"); 149 } 150 outn("]])"); 151 } 152 153 154 /* Generate the code to keep backing-up information. */ 155 156 void 157 gen_backing_up(void) 158 { 159 if (reject || num_backing_up == 0) 160 return; 161 162 if (fullspd) 163 indent_puts("if ( yy_current_state[-1].yy_nxt )"); 164 else 165 indent_puts("if ( yy_accept[yy_current_state] )"); 166 167 indent_up(); 168 indent_puts("{"); 169 indent_puts("YY_G(yy_last_accepting_state) = yy_current_state;"); 170 indent_puts("YY_G(yy_last_accepting_cpos) = yy_cp;"); 171 indent_puts("}"); 172 indent_down(); 173 } 174 175 176 /* Generate the code to perform the backing up. */ 177 178 void 179 gen_bu_action(void) 180 { 181 if (reject || num_backing_up == 0) 182 return; 183 184 set_indent(3); 185 186 indent_puts("case 0: /* must back up */"); 187 indent_puts("/* undo the effects of YY_DO_BEFORE_ACTION */"); 188 indent_puts("*yy_cp = YY_G(yy_hold_char);"); 189 190 if (fullspd || fulltbl) 191 indent_puts("yy_cp = YY_G(yy_last_accepting_cpos) + 1;"); 192 else 193 /* 194 * Backing-up info for compressed tables is taken \after/ 195 * yy_cp has been incremented for the next state. 196 */ 197 indent_puts("yy_cp = YY_G(yy_last_accepting_cpos);"); 198 199 indent_puts("yy_current_state = YY_G(yy_last_accepting_state);"); 200 indent_puts("goto yy_find_action;"); 201 outc('\n'); 202 203 set_indent(0); 204 } 205 206 /** mkctbl - make full speed compressed transition table 207 * This is an array of structs; each struct a pair of integers. 208 * You should call mkssltbl() immediately after this. 209 * Then, I think, mkecstbl(). Arrrg. 210 * @return the newly allocated trans table 211 */ 212 213 static struct yytbl_data * 214 mkctbl(void) 215 { 216 int i; 217 struct yytbl_data *tbl = NULL; 218 flex_int32_t *tdata = NULL, curr = 0; 219 int end_of_buffer_action = num_rules + 1; 220 221 buf_prints(&yydmap_buf, 222 "\t{YYTD_ID_TRANSITION, (void**)&yy_transition, sizeof(%s)},\n", 223 ((tblend + numecs + 1) >= INT16_MAX 224 || long_align) ? "flex_int32_t" : "flex_int16_t"); 225 226 tbl = calloc(1, sizeof(struct yytbl_data)); 227 yytbl_data_init(tbl, YYTD_ID_TRANSITION); 228 tbl->td_flags = YYTD_DATA32 | YYTD_STRUCT; 229 tbl->td_hilen = 0; 230 tbl->td_lolen = tblend + numecs + 1; /* number of structs */ 231 232 tbl->td_data = tdata = 233 calloc(tbl->td_lolen * 2, sizeof(flex_int32_t)); 234 235 /* 236 * We want the transition to be represented as the offset to the next 237 * state, not the actual state number, which is what it currently is. 238 * The offset is base[nxt[i]] - (base of current state)]. That's 239 * just the difference between the starting points of the two 240 * involved states (to - from). 241 * 242 * First, though, we need to find some way to put in our end-of-buffer 243 * flags and states. We do this by making a state with absolutely no 244 * transitions. We put it at the end of the table. 245 */ 246 247 /* 248 * We need to have room in nxt/chk for two more slots: One for the 249 * action and one for the end-of-buffer transition. We now *assume* 250 * that we're guaranteed the only character we'll try to index this 251 * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure 252 * there's room for jam entries for other characters. 253 */ 254 255 while (tblend + 2 >= current_max_xpairs) 256 expand_nxt_chk(); 257 258 while (lastdfa + 1 >= current_max_dfas) 259 increase_max_dfas(); 260 261 base[lastdfa + 1] = tblend + 2; 262 nxt[tblend + 1] = end_of_buffer_action; 263 chk[tblend + 1] = numecs + 1; 264 chk[tblend + 2] = 1; /* anything but EOB */ 265 266 /* So that "make test" won't show arb. differences. */ 267 nxt[tblend + 2] = 0; 268 269 /* 270 * Make sure every state has an end-of-buffer transition and an 271 * action #. 272 */ 273 for (i = 0; i <= lastdfa; ++i) { 274 int anum = dfaacc[i].dfaacc_state; 275 int offset = base[i]; 276 277 chk[offset] = EOB_POSITION; 278 chk[offset - 1] = ACTION_POSITION; 279 nxt[offset - 1] = anum; /* action number */ 280 } 281 282 for (i = 0; i <= tblend; ++i) { 283 if (chk[i] == EOB_POSITION) { 284 tdata[curr++] = 0; 285 tdata[curr++] = base[lastdfa + 1] - i; 286 } else if (chk[i] == ACTION_POSITION) { 287 tdata[curr++] = 0; 288 tdata[curr++] = nxt[i]; 289 } else if (chk[i] > numecs || chk[i] == 0) { 290 tdata[curr++] = 0; 291 tdata[curr++] = 0; 292 } else { /* verify, transition */ 293 294 tdata[curr++] = chk[i]; 295 tdata[curr++] = base[nxt[i]] - (i - chk[i]); 296 } 297 } 298 299 300 /* Here's the final, end-of-buffer state. */ 301 tdata[curr++] = chk[tblend + 1]; 302 tdata[curr++] = nxt[tblend + 1]; 303 304 tdata[curr++] = chk[tblend + 2]; 305 tdata[curr++] = nxt[tblend + 2]; 306 307 return tbl; 308 } 309 310 311 /** Make start_state_list table. 312 * @return the newly allocated start_state_list table 313 */ 314 static struct yytbl_data * 315 mkssltbl(void) 316 { 317 struct yytbl_data *tbl = NULL; 318 flex_int32_t *tdata = NULL; 319 flex_int32_t i; 320 321 tbl = calloc(1, sizeof(struct yytbl_data)); 322 yytbl_data_init(tbl, YYTD_ID_START_STATE_LIST); 323 tbl->td_flags = YYTD_DATA32 | YYTD_PTRANS; 324 tbl->td_hilen = 0; 325 tbl->td_lolen = lastsc * 2 + 1; 326 327 tbl->td_data = tdata = 328 calloc(tbl->td_lolen, sizeof(flex_int32_t)); 329 330 for (i = 0; i <= lastsc * 2; ++i) 331 tdata[i] = base[i]; 332 333 buf_prints(&yydmap_buf, 334 "\t{YYTD_ID_START_STATE_LIST, (void**)&yy_start_state_list, sizeof(%s)},\n", 335 "struct yy_trans_info*"); 336 337 return tbl; 338 } 339 340 341 342 /* genctbl - generates full speed compressed transition table */ 343 344 void 345 genctbl(void) 346 { 347 int i; 348 int end_of_buffer_action = num_rules + 1; 349 350 /* Table of verify for transition and offset to next state. */ 351 if (gentables) 352 out_dec("static yyconst struct yy_trans_info yy_transition[%d] =\n {\n", tblend + numecs + 1); 353 else 354 outn("static yyconst struct yy_trans_info *yy_transition = 0;"); 355 356 /* 357 * We want the transition to be represented as the offset to the next 358 * state, not the actual state number, which is what it currently is. 359 * The offset is base[nxt[i]] - (base of current state)]. That's 360 * just the difference between the starting points of the two 361 * involved states (to - from). 362 * 363 * First, though, we need to find some way to put in our end-of-buffer 364 * flags and states. We do this by making a state with absolutely no 365 * transitions. We put it at the end of the table. 366 */ 367 368 /* 369 * We need to have room in nxt/chk for two more slots: One for the 370 * action and one for the end-of-buffer transition. We now *assume* 371 * that we're guaranteed the only character we'll try to index this 372 * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure 373 * there's room for jam entries for other characters. 374 */ 375 376 while (tblend + 2 >= current_max_xpairs) 377 expand_nxt_chk(); 378 379 while (lastdfa + 1 >= current_max_dfas) 380 increase_max_dfas(); 381 382 base[lastdfa + 1] = tblend + 2; 383 nxt[tblend + 1] = end_of_buffer_action; 384 chk[tblend + 1] = numecs + 1; 385 chk[tblend + 2] = 1; /* anything but EOB */ 386 387 /* So that "make test" won't show arb. differences. */ 388 nxt[tblend + 2] = 0; 389 390 /* 391 * Make sure every state has an end-of-buffer transition and an 392 * action #. 393 */ 394 for (i = 0; i <= lastdfa; ++i) { 395 int anum = dfaacc[i].dfaacc_state; 396 int offset = base[i]; 397 398 chk[offset] = EOB_POSITION; 399 chk[offset - 1] = ACTION_POSITION; 400 nxt[offset - 1] = anum; /* action number */ 401 } 402 403 for (i = 0; i <= tblend; ++i) { 404 if (chk[i] == EOB_POSITION) 405 transition_struct_out(0, base[lastdfa + 1] - i); 406 407 else if (chk[i] == ACTION_POSITION) 408 transition_struct_out(0, nxt[i]); 409 410 else if (chk[i] > numecs || chk[i] == 0) 411 transition_struct_out(0, 0); /* unused slot */ 412 413 else /* verify, transition */ 414 transition_struct_out(chk[i], 415 base[nxt[i]] - (i - 416 chk[i])); 417 } 418 419 420 /* Here's the final, end-of-buffer state. */ 421 transition_struct_out(chk[tblend + 1], nxt[tblend + 1]); 422 transition_struct_out(chk[tblend + 2], nxt[tblend + 2]); 423 424 if (gentables) 425 outn(" };\n"); 426 427 /* Table of pointers to start states. */ 428 if (gentables) 429 out_dec("static yyconst struct yy_trans_info *yy_start_state_list[%d] =\n", lastsc * 2 + 1); 430 else 431 outn("static yyconst struct yy_trans_info **yy_start_state_list =0;"); 432 433 if (gentables) { 434 outn(" {"); 435 436 for (i = 0; i <= lastsc * 2; ++i) 437 out_dec(" &yy_transition[%d],\n", base[i]); 438 439 dataend(); 440 } 441 if (useecs) 442 genecs(); 443 } 444 445 446 /* mkecstbl - Make equivalence-class tables. */ 447 448 static struct yytbl_data * 449 mkecstbl(void) 450 { 451 int i; 452 struct yytbl_data *tbl = NULL; 453 flex_int32_t *tdata = NULL; 454 455 tbl = calloc(1, sizeof(struct yytbl_data)); 456 yytbl_data_init(tbl, YYTD_ID_EC); 457 tbl->td_flags |= YYTD_DATA32; 458 tbl->td_hilen = 0; 459 tbl->td_lolen = csize; 460 461 tbl->td_data = tdata = 462 calloc(tbl->td_lolen, sizeof(flex_int32_t)); 463 464 for (i = 1; i < csize; ++i) { 465 ecgroup[i] = ABS(ecgroup[i]); 466 tdata[i] = ecgroup[i]; 467 } 468 469 buf_prints(&yydmap_buf, 470 "\t{YYTD_ID_EC, (void**)&yy_ec, sizeof(%s)},\n", 471 "flex_int32_t"); 472 473 return tbl; 474 } 475 476 /* Generate equivalence-class tables. */ 477 478 void 479 genecs(void) 480 { 481 int i, j; 482 int numrows; 483 484 out_str_dec(get_int32_decl(), "yy_ec", csize); 485 486 for (i = 1; i < csize; ++i) { 487 ecgroup[i] = ABS(ecgroup[i]); 488 mkdata(ecgroup[i]); 489 } 490 491 dataend(); 492 493 if (trace) { 494 fputs(_("\n\nEquivalence Classes:\n\n"), stderr); 495 496 numrows = csize / 8; 497 498 for (j = 0; j < numrows; ++j) { 499 for (i = j; i < csize; i = i + numrows) { 500 fprintf(stderr, "%4s = %-2d", 501 readable_form(i), ecgroup[i]); 502 503 putc(' ', stderr); 504 } 505 506 putc('\n', stderr); 507 } 508 } 509 } 510 511 512 /* Generate the code to find the action number. */ 513 514 void 515 gen_find_action(void) 516 { 517 if (fullspd) 518 indent_puts("yy_act = yy_current_state[-1].yy_nxt;"); 519 520 else if (fulltbl) 521 indent_puts("yy_act = yy_accept[yy_current_state];"); 522 523 else if (reject) { 524 indent_puts("yy_current_state = *--YY_G(yy_state_ptr);"); 525 indent_puts("YY_G(yy_lp) = yy_accept[yy_current_state];"); 526 527 outn("find_rule: /* we branch to this label when backing up */"); 528 529 indent_puts 530 ("for ( ; ; ) /* until we find what rule we matched */"); 531 532 indent_up(); 533 534 indent_puts("{"); 535 536 indent_puts 537 ("if ( YY_G(yy_lp) && YY_G(yy_lp) < yy_accept[yy_current_state + 1] )"); 538 indent_up(); 539 indent_puts("{"); 540 indent_puts("yy_act = yy_acclist[YY_G(yy_lp)];"); 541 542 if (variable_trailing_context_rules) { 543 indent_puts 544 ("if ( yy_act & YY_TRAILING_HEAD_MASK ||"); 545 indent_puts(" YY_G(yy_looking_for_trail_begin) )"); 546 indent_up(); 547 indent_puts("{"); 548 549 indent_puts 550 ("if ( yy_act == YY_G(yy_looking_for_trail_begin) )"); 551 indent_up(); 552 indent_puts("{"); 553 indent_puts("YY_G(yy_looking_for_trail_begin) = 0;"); 554 indent_puts("yy_act &= ~YY_TRAILING_HEAD_MASK;"); 555 indent_puts("break;"); 556 indent_puts("}"); 557 indent_down(); 558 559 indent_puts("}"); 560 indent_down(); 561 562 indent_puts 563 ("else if ( yy_act & YY_TRAILING_MASK )"); 564 indent_up(); 565 indent_puts("{"); 566 indent_puts 567 ("YY_G(yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK;"); 568 indent_puts 569 ("YY_G(yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK;"); 570 571 if (real_reject) { 572 /* 573 * Remember matched text in case we back up 574 * due to REJECT. 575 */ 576 indent_puts 577 ("YY_G(yy_full_match) = yy_cp;"); 578 indent_puts 579 ("YY_G(yy_full_state) = YY_G(yy_state_ptr);"); 580 indent_puts("YY_G(yy_full_lp) = YY_G(yy_lp);"); 581 } 582 indent_puts("}"); 583 indent_down(); 584 585 indent_puts("else"); 586 indent_up(); 587 indent_puts("{"); 588 indent_puts("YY_G(yy_full_match) = yy_cp;"); 589 indent_puts 590 ("YY_G(yy_full_state) = YY_G(yy_state_ptr);"); 591 indent_puts("YY_G(yy_full_lp) = YY_G(yy_lp);"); 592 indent_puts("break;"); 593 indent_puts("}"); 594 indent_down(); 595 596 indent_puts("++YY_G(yy_lp);"); 597 indent_puts("goto find_rule;"); 598 } else { 599 /* 600 * Remember matched text in case we back up due to 601 * trailing context plus REJECT. 602 */ 603 indent_up(); 604 indent_puts("{"); 605 indent_puts("YY_G(yy_full_match) = yy_cp;"); 606 indent_puts("break;"); 607 indent_puts("}"); 608 indent_down(); 609 } 610 611 indent_puts("}"); 612 indent_down(); 613 614 indent_puts("--yy_cp;"); 615 616 /* 617 * We could consolidate the following two lines with those at 618 * the beginning, but at the cost of complaints that we're 619 * branching inside a loop. 620 */ 621 indent_puts("yy_current_state = *--YY_G(yy_state_ptr);"); 622 indent_puts("YY_G(yy_lp) = yy_accept[yy_current_state];"); 623 624 indent_puts("}"); 625 626 indent_down(); 627 } else { /* compressed */ 628 indent_puts("yy_act = yy_accept[yy_current_state];"); 629 630 if (interactive && !reject) { 631 /* 632 * Do the guaranteed-needed backing up to figure out 633 * the match. 634 */ 635 indent_puts("if ( yy_act == 0 )"); 636 indent_up(); 637 indent_puts("{ /* have to back up */"); 638 indent_puts 639 ("yy_cp = YY_G(yy_last_accepting_cpos);"); 640 indent_puts 641 ("yy_current_state = YY_G(yy_last_accepting_state);"); 642 indent_puts 643 ("yy_act = yy_accept[yy_current_state];"); 644 indent_puts("}"); 645 indent_down(); 646 } 647 } 648 } 649 650 /* mkftbl - make the full table and return the struct . 651 * you should call mkecstbl() after this. 652 */ 653 654 struct yytbl_data * 655 mkftbl(void) 656 { 657 int i; 658 int end_of_buffer_action = num_rules + 1; 659 struct yytbl_data *tbl; 660 flex_int32_t *tdata = NULL; 661 662 tbl = calloc(1, sizeof(struct yytbl_data)); 663 yytbl_data_init(tbl, YYTD_ID_ACCEPT); 664 tbl->td_flags |= YYTD_DATA32; 665 tbl->td_hilen = 0; /* it's a one-dimensional array */ 666 tbl->td_lolen = lastdfa + 1; 667 668 tbl->td_data = tdata = 669 calloc(tbl->td_lolen, sizeof(flex_int32_t)); 670 671 dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; 672 673 for (i = 1; i <= lastdfa; ++i) { 674 int anum = dfaacc[i].dfaacc_state; 675 676 tdata[i] = anum; 677 678 if (trace && anum) 679 fprintf(stderr, _("state # %d accepts: [%d]\n"), 680 i, anum); 681 } 682 683 buf_prints(&yydmap_buf, 684 "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", 685 long_align ? "flex_int32_t" : "flex_int16_t"); 686 return tbl; 687 } 688 689 690 /* genftbl - generate full transition table */ 691 692 void 693 genftbl(void) 694 { 695 int i; 696 int end_of_buffer_action = num_rules + 1; 697 698 out_str_dec(long_align ? get_int32_decl() : get_int16_decl(), 699 "yy_accept", lastdfa + 1); 700 701 dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; 702 703 for (i = 1; i <= lastdfa; ++i) { 704 int anum = dfaacc[i].dfaacc_state; 705 706 mkdata(anum); 707 708 if (trace && anum) 709 fprintf(stderr, _("state # %d accepts: [%d]\n"), 710 i, anum); 711 } 712 713 dataend(); 714 715 if (useecs) 716 genecs(); 717 718 /* 719 * Don't have to dump the actual full table entries - they were 720 * created on-the-fly. 721 */ 722 } 723 724 725 /* Generate the code to find the next compressed-table state. */ 726 727 void 728 gen_next_compressed_state(char *char_map) 729 { 730 indent_put2s("YY_CHAR yy_c = %s;", char_map); 731 732 /* 733 * Save the backing-up info \before/ computing the next state because 734 * we always compute one more state than needed - we always proceed 735 * until we reach a jam state 736 */ 737 gen_backing_up(); 738 739 indent_puts 740 ("while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )"); 741 indent_up(); 742 indent_puts("{"); 743 indent_puts("yy_current_state = (int) yy_def[yy_current_state];"); 744 745 if (usemecs) { 746 /* 747 * We've arrange it so that templates are never chained to 748 * one another. This means we can afford to make a very 749 * simple test to see if we need to convert to yy_c's 750 * meta-equivalence class without worrying about erroneously 751 * looking up the meta-equivalence class twice 752 */ 753 do_indent(); 754 755 /* lastdfa + 2 is the beginning of the templates */ 756 out_dec("if ( yy_current_state >= %d )\n", lastdfa + 2); 757 758 indent_up(); 759 indent_puts("yy_c = yy_meta[(unsigned int) yy_c];"); 760 indent_down(); 761 } 762 indent_puts("}"); 763 indent_down(); 764 765 indent_puts 766 ("yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];"); 767 } 768 769 770 /* Generate the code to find the next match. */ 771 772 void 773 gen_next_match(void) 774 { 775 /* 776 * NOTE - changes in here should be reflected in gen_next_state() and 777 * gen_NUL_trans(). 778 */ 779 char *char_map = useecs ? 780 "yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)"; 781 782 char *char_map_2 = useecs ? 783 "yy_ec[YY_SC_TO_UI(*++yy_cp)] " : "YY_SC_TO_UI(*++yy_cp)"; 784 785 if (fulltbl) { 786 if (gentables) 787 indent_put2s 788 ("while ( (yy_current_state = yy_nxt[yy_current_state][ %s ]) > 0 )", 789 char_map); 790 else 791 indent_put2s 792 ("while ( (yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s ]) > 0 )", 793 char_map); 794 795 indent_up(); 796 797 if (num_backing_up > 0) { 798 indent_puts("{"); 799 gen_backing_up(); 800 outc('\n'); 801 } 802 indent_puts("++yy_cp;"); 803 804 if (num_backing_up > 0) 805 indent_puts("}"); 806 807 indent_down(); 808 809 outc('\n'); 810 indent_puts("yy_current_state = -yy_current_state;"); 811 } else if (fullspd) { 812 indent_puts("{"); 813 indent_puts 814 ("yyconst struct yy_trans_info *yy_trans_info;\n"); 815 indent_puts("YY_CHAR yy_c;\n"); 816 indent_put2s("for ( yy_c = %s;", char_map); 817 indent_puts 818 (" (yy_trans_info = &yy_current_state[(unsigned int) yy_c])->"); 819 indent_puts("yy_verify == yy_c;"); 820 indent_put2s(" yy_c = %s )", char_map_2); 821 822 indent_up(); 823 824 if (num_backing_up > 0) 825 indent_puts("{"); 826 827 indent_puts("yy_current_state += yy_trans_info->yy_nxt;"); 828 829 if (num_backing_up > 0) { 830 outc('\n'); 831 gen_backing_up(); 832 indent_puts("}"); 833 } 834 indent_down(); 835 indent_puts("}"); 836 } else { /* compressed */ 837 indent_puts("do"); 838 839 indent_up(); 840 indent_puts("{"); 841 842 gen_next_state(false); 843 844 indent_puts("++yy_cp;"); 845 846 847 indent_puts("}"); 848 indent_down(); 849 850 do_indent(); 851 852 if (interactive) 853 out_dec("while ( yy_base[yy_current_state] != %d );\n", jambase); 854 else 855 out_dec("while ( yy_current_state != %d );\n", 856 jamstate); 857 858 if (!reject && !interactive) { 859 /* 860 * Do the guaranteed-needed backing up to figure out 861 * the match. 862 */ 863 indent_puts 864 ("yy_cp = YY_G(yy_last_accepting_cpos);"); 865 indent_puts 866 ("yy_current_state = YY_G(yy_last_accepting_state);"); 867 } 868 } 869 } 870 871 872 /* Generate the code to find the next state. */ 873 874 void 875 gen_next_state(int worry_about_NULs) 876 { /* NOTE - changes in here should be reflected 877 * in gen_next_match() */ 878 char char_map[256]; 879 880 if (worry_about_NULs && !nultrans) { 881 if (useecs) 882 snprintf(char_map, sizeof(char_map), 883 "(*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : %d)", 884 NUL_ec); 885 else 886 snprintf(char_map, sizeof(char_map), 887 "(*yy_cp ? YY_SC_TO_UI(*yy_cp) : %d)", 888 NUL_ec); 889 } else 890 strlcpy(char_map, useecs ? 891 "yy_ec[YY_SC_TO_UI(*yy_cp)] " : "YY_SC_TO_UI(*yy_cp)", 892 sizeof char_map); 893 894 if (worry_about_NULs && nultrans) { 895 if (!fulltbl && !fullspd) 896 /* Compressed tables back up *before* they match. */ 897 gen_backing_up(); 898 899 indent_puts("if ( *yy_cp )"); 900 indent_up(); 901 indent_puts("{"); 902 } 903 if (fulltbl) { 904 if (gentables) 905 indent_put2s 906 ("yy_current_state = yy_nxt[yy_current_state][%s];", 907 char_map); 908 else 909 indent_put2s 910 ("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %s];", 911 char_map); 912 } else if (fullspd) 913 indent_put2s 914 ("yy_current_state += yy_current_state[%s].yy_nxt;", 915 char_map); 916 917 else 918 gen_next_compressed_state(char_map); 919 920 if (worry_about_NULs && nultrans) { 921 922 indent_puts("}"); 923 indent_down(); 924 indent_puts("else"); 925 indent_up(); 926 indent_puts 927 ("yy_current_state = yy_NUL_trans[yy_current_state];"); 928 indent_down(); 929 } 930 if (fullspd || fulltbl) 931 gen_backing_up(); 932 933 if (reject) 934 indent_puts("*YY_G(yy_state_ptr)++ = yy_current_state;"); 935 } 936 937 938 /* Generate the code to make a NUL transition. */ 939 940 void 941 gen_NUL_trans(void) 942 { /* NOTE - changes in here should be reflected 943 * in gen_next_match() */ 944 /* 945 * Only generate a definition for "yy_cp" if we'll generate code that 946 * uses it. Otherwise lint and the like complain. 947 */ 948 int need_backing_up = (num_backing_up > 0 && !reject); 949 950 if (need_backing_up && (!nultrans || fullspd || fulltbl)) 951 /* 952 * We're going to need yy_cp lying around for the call below 953 * to gen_backing_up(). 954 */ 955 indent_puts("char *yy_cp = YY_G(yy_c_buf_p);"); 956 957 outc('\n'); 958 959 if (nultrans) { 960 indent_puts 961 ("yy_current_state = yy_NUL_trans[yy_current_state];"); 962 indent_puts("yy_is_jam = (yy_current_state == 0);"); 963 } else if (fulltbl) { 964 do_indent(); 965 if (gentables) 966 out_dec("yy_current_state = yy_nxt[yy_current_state][%d];\n", NUL_ec); 967 else 968 out_dec("yy_current_state = yy_nxt[yy_current_state*YY_NXT_LOLEN + %d];\n", NUL_ec); 969 indent_puts("yy_is_jam = (yy_current_state <= 0);"); 970 } else if (fullspd) { 971 do_indent(); 972 out_dec("int yy_c = %d;\n", NUL_ec); 973 974 indent_puts 975 ("yyconst struct yy_trans_info *yy_trans_info;\n"); 976 indent_puts 977 ("yy_trans_info = &yy_current_state[(unsigned int) yy_c];"); 978 indent_puts("yy_current_state += yy_trans_info->yy_nxt;"); 979 980 indent_puts 981 ("yy_is_jam = (yy_trans_info->yy_verify != yy_c);"); 982 } else { 983 char NUL_ec_str[20]; 984 985 snprintf(NUL_ec_str, sizeof(NUL_ec_str), "%d", NUL_ec); 986 gen_next_compressed_state(NUL_ec_str); 987 988 do_indent(); 989 out_dec("yy_is_jam = (yy_current_state == %d);\n", 990 jamstate); 991 992 if (reject) { 993 /* 994 * Only stack this state if it's a transition we 995 * actually make. If we stack it on a jam, then the 996 * state stack and yy_c_buf_p get out of sync. 997 */ 998 indent_puts("if ( ! yy_is_jam )"); 999 indent_up(); 1000 indent_puts 1001 ("*YY_G(yy_state_ptr)++ = yy_current_state;"); 1002 indent_down(); 1003 } 1004 } 1005 1006 /* 1007 * If we've entered an accepting state, back up; note that compressed 1008 * tables have *already* done such backing up, so we needn't bother 1009 * with it again. 1010 */ 1011 if (need_backing_up && (fullspd || fulltbl)) { 1012 outc('\n'); 1013 indent_puts("if ( ! yy_is_jam )"); 1014 indent_up(); 1015 indent_puts("{"); 1016 gen_backing_up(); 1017 indent_puts("}"); 1018 indent_down(); 1019 } 1020 } 1021 1022 1023 /* Generate the code to find the start state. */ 1024 1025 void 1026 gen_start_state(void) 1027 { 1028 if (fullspd) { 1029 if (bol_needed) { 1030 indent_puts 1031 ("yy_current_state = yy_start_state_list[YY_G(yy_start) + YY_AT_BOL()];"); 1032 } else 1033 indent_puts 1034 ("yy_current_state = yy_start_state_list[YY_G(yy_start)];"); 1035 } else { 1036 indent_puts("yy_current_state = YY_G(yy_start);"); 1037 1038 if (bol_needed) 1039 indent_puts("yy_current_state += YY_AT_BOL();"); 1040 1041 if (reject) { 1042 /* Set up for storing up states. */ 1043 outn("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); 1044 indent_puts 1045 ("YY_G(yy_state_ptr) = YY_G(yy_state_buf);"); 1046 indent_puts 1047 ("*YY_G(yy_state_ptr)++ = yy_current_state;"); 1048 outn("]])"); 1049 } 1050 } 1051 } 1052 1053 1054 /* gentabs - generate data statements for the transition tables */ 1055 1056 void 1057 gentabs(void) 1058 { 1059 int i, j, k, *accset, nacc, *acc_array, total_states; 1060 int end_of_buffer_action = num_rules + 1; 1061 struct yytbl_data *yyacc_tbl = 0, *yymeta_tbl = 0, *yybase_tbl = 0, *yydef_tbl = 0, 1062 *yynxt_tbl = 0, *yychk_tbl = 0, *yyacclist_tbl = 0; 1063 flex_int32_t *yyacc_data = 0, *yybase_data = 0, *yydef_data = 0, *yynxt_data = 0, 1064 *yychk_data = 0, *yyacclist_data = 0; 1065 flex_int32_t yybase_curr = 0, yyacclist_curr = 0, yyacc_curr = 0; 1066 1067 acc_array = allocate_integer_array(current_max_dfas); 1068 nummt = 0; 1069 1070 /* 1071 * The compressed table format jams by entering the "jam state", 1072 * losing information about the previous state in the process. In 1073 * order to recover the previous state, we effectively need to keep 1074 * backing-up information. 1075 */ 1076 ++num_backing_up; 1077 1078 if (reject) { 1079 /* 1080 * Write out accepting list and pointer list. 1081 * 1082 * First we generate the "yy_acclist" array. In the process, we 1083 * compute the indices that will go into the "yy_accept" 1084 * array, and save the indices in the dfaacc array. 1085 */ 1086 int EOB_accepting_list[2]; 1087 1088 /* Set up accepting structures for the End Of Buffer state. */ 1089 EOB_accepting_list[0] = 0; 1090 EOB_accepting_list[1] = end_of_buffer_action; 1091 accsiz[end_of_buffer_state] = 1; 1092 dfaacc[end_of_buffer_state].dfaacc_set = 1093 EOB_accepting_list; 1094 1095 out_str_dec(long_align ? get_int32_decl() : 1096 get_int16_decl(), "yy_acclist", MAX(numas, 1097 1) + 1); 1098 1099 buf_prints(&yydmap_buf, 1100 "\t{YYTD_ID_ACCLIST, (void**)&yy_acclist, sizeof(%s)},\n", 1101 long_align ? "flex_int32_t" : "flex_int16_t"); 1102 1103 yyacclist_tbl = calloc(1, sizeof(struct yytbl_data)); 1104 yytbl_data_init(yyacclist_tbl, YYTD_ID_ACCLIST); 1105 yyacclist_tbl->td_lolen = MAX(numas, 1) + 1; 1106 yyacclist_tbl->td_data = yyacclist_data = 1107 calloc(yyacclist_tbl->td_lolen, sizeof(flex_int32_t)); 1108 yyacclist_curr = 1; 1109 1110 j = 1; /* index into "yy_acclist" array */ 1111 1112 for (i = 1; i <= lastdfa; ++i) { 1113 acc_array[i] = j; 1114 1115 if (accsiz[i] != 0) { 1116 accset = dfaacc[i].dfaacc_set; 1117 nacc = accsiz[i]; 1118 1119 if (trace) 1120 fprintf(stderr, 1121 _("state # %d accepts: "), 1122 i); 1123 1124 for (k = 1; k <= nacc; ++k) { 1125 int accnum = accset[k]; 1126 1127 ++j; 1128 1129 if (variable_trailing_context_rules 1130 && !(accnum & 1131 YY_TRAILING_HEAD_MASK) 1132 && accnum > 0 1133 && accnum <= num_rules 1134 && rule_type[accnum] == 1135 RULE_VARIABLE) { 1136 /* 1137 * Special hack to flag 1138 * accepting number as part 1139 * of trailing context rule. 1140 */ 1141 accnum |= YY_TRAILING_MASK; 1142 } 1143 mkdata(accnum); 1144 yyacclist_data[yyacclist_curr++] = accnum; 1145 1146 if (trace) { 1147 fprintf(stderr, "[%d]", 1148 accset[k]); 1149 1150 if (k < nacc) 1151 fputs(", ", 1152 stderr); 1153 else 1154 putc('\n', 1155 stderr); 1156 } 1157 } 1158 } 1159 } 1160 1161 /* add accepting number for the "jam" state */ 1162 acc_array[i] = j; 1163 1164 dataend(); 1165 if (tablesext) { 1166 yytbl_data_compress(yyacclist_tbl); 1167 if (yytbl_data_fwrite(&tableswr, yyacclist_tbl) < 0) 1168 flexerror(_("Could not write yyacclist_tbl")); 1169 yytbl_data_destroy(yyacclist_tbl); 1170 yyacclist_tbl = NULL; 1171 } 1172 } else { 1173 dfaacc[end_of_buffer_state].dfaacc_state = 1174 end_of_buffer_action; 1175 1176 for (i = 1; i <= lastdfa; ++i) 1177 acc_array[i] = dfaacc[i].dfaacc_state; 1178 1179 /* add accepting number for jam state */ 1180 acc_array[i] = 0; 1181 } 1182 1183 /* Begin generating yy_accept */ 1184 1185 /* 1186 * Spit out "yy_accept" array. If we're doing "reject", it'll be 1187 * pointers into the "yy_acclist" array. Otherwise it's actual 1188 * accepting numbers. In either case, we just dump the numbers. 1189 */ 1190 1191 /* 1192 * "lastdfa + 2" is the size of "yy_accept"; includes room for C 1193 * arrays beginning at 0 and for "jam" state. 1194 */ 1195 k = lastdfa + 2; 1196 1197 if (reject) 1198 /* 1199 * We put a "cap" on the table associating lists of accepting 1200 * numbers with state numbers. This is needed because we 1201 * tell where the end of an accepting list is by looking at 1202 * where the list for the next state starts. 1203 */ 1204 ++k; 1205 1206 out_str_dec(long_align ? get_int32_decl() : get_int16_decl(), 1207 "yy_accept", k); 1208 1209 buf_prints(&yydmap_buf, 1210 "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", 1211 long_align ? "flex_int32_t" : "flex_int16_t"); 1212 1213 yyacc_tbl = calloc(1, sizeof(struct yytbl_data)); 1214 yytbl_data_init(yyacc_tbl, YYTD_ID_ACCEPT); 1215 yyacc_tbl->td_lolen = k; 1216 yyacc_tbl->td_data = yyacc_data = 1217 calloc(yyacc_tbl->td_lolen, sizeof(flex_int32_t)); 1218 yyacc_curr = 1; 1219 1220 for (i = 1; i <= lastdfa; ++i) { 1221 mkdata(acc_array[i]); 1222 yyacc_data[yyacc_curr++] = acc_array[i]; 1223 1224 if (!reject && trace && acc_array[i]) 1225 fprintf(stderr, _("state # %d accepts: [%d]\n"), 1226 i, acc_array[i]); 1227 } 1228 1229 /* Add entry for "jam" state. */ 1230 mkdata(acc_array[i]); 1231 yyacc_data[yyacc_curr++] = acc_array[i]; 1232 1233 if (reject) { 1234 /* Add "cap" for the list. */ 1235 mkdata(acc_array[i]); 1236 yyacc_data[yyacc_curr++] = acc_array[i]; 1237 } 1238 dataend(); 1239 if (tablesext) { 1240 yytbl_data_compress(yyacc_tbl); 1241 if (yytbl_data_fwrite(&tableswr, yyacc_tbl) < 0) 1242 flexerror(_("Could not write yyacc_tbl")); 1243 yytbl_data_destroy(yyacc_tbl); 1244 yyacc_tbl = NULL; 1245 } 1246 /* End generating yy_accept */ 1247 1248 if (useecs) { 1249 1250 genecs(); 1251 if (tablesext) { 1252 struct yytbl_data *tbl; 1253 1254 tbl = mkecstbl(); 1255 yytbl_data_compress(tbl); 1256 if (yytbl_data_fwrite(&tableswr, tbl) < 0) 1257 flexerror(_("Could not write ecstbl")); 1258 yytbl_data_destroy(tbl); 1259 tbl = 0; 1260 } 1261 } 1262 if (usemecs) { 1263 /* Begin generating yy_meta */ 1264 /* 1265 * Write out meta-equivalence classes (used to index 1266 * templates with). 1267 */ 1268 flex_int32_t *yymecs_data = NULL; 1269 yymeta_tbl = calloc(1, sizeof(struct yytbl_data)); 1270 yytbl_data_init(yymeta_tbl, YYTD_ID_META); 1271 yymeta_tbl->td_lolen = numecs + 1; 1272 yymeta_tbl->td_data = yymecs_data = 1273 calloc(yymeta_tbl->td_lolen, 1274 sizeof(flex_int32_t)); 1275 1276 if (trace) 1277 fputs(_("\n\nMeta-Equivalence Classes:\n"), 1278 stderr); 1279 1280 out_str_dec(get_int32_decl(), "yy_meta", numecs + 1); 1281 buf_prints(&yydmap_buf, 1282 "\t{YYTD_ID_META, (void**)&yy_meta, sizeof(%s)},\n", 1283 "flex_int32_t"); 1284 1285 for (i = 1; i <= numecs; ++i) { 1286 if (trace) 1287 fprintf(stderr, "%d = %d\n", 1288 i, ABS(tecbck[i])); 1289 1290 mkdata(ABS(tecbck[i])); 1291 yymecs_data[i] = ABS(tecbck[i]); 1292 } 1293 1294 dataend(); 1295 if (tablesext) { 1296 yytbl_data_compress(yymeta_tbl); 1297 if (yytbl_data_fwrite(&tableswr, yymeta_tbl) < 0) 1298 flexerror(_ 1299 ("Could not write yymeta_tbl")); 1300 yytbl_data_destroy(yymeta_tbl); 1301 yymeta_tbl = NULL; 1302 } 1303 /* End generating yy_meta */ 1304 } 1305 total_states = lastdfa + numtemps; 1306 1307 /* Begin generating yy_base */ 1308 out_str_dec((tblend >= INT16_MAX || long_align) ? 1309 get_int32_decl() : get_int16_decl(), 1310 "yy_base", total_states + 1); 1311 1312 buf_prints(&yydmap_buf, 1313 "\t{YYTD_ID_BASE, (void**)&yy_base, sizeof(%s)},\n", 1314 (tblend >= INT16_MAX 1315 || long_align) ? "flex_int32_t" : "flex_int16_t"); 1316 yybase_tbl = calloc(1, sizeof(struct yytbl_data)); 1317 yytbl_data_init(yybase_tbl, YYTD_ID_BASE); 1318 yybase_tbl->td_lolen = total_states + 1; 1319 yybase_tbl->td_data = yybase_data = 1320 calloc(yybase_tbl->td_lolen, 1321 sizeof(flex_int32_t)); 1322 yybase_curr = 1; 1323 1324 for (i = 1; i <= lastdfa; ++i) { 1325 int d = def[i]; 1326 1327 if (base[i] == JAMSTATE) 1328 base[i] = jambase; 1329 1330 if (d == JAMSTATE) 1331 def[i] = jamstate; 1332 1333 else if (d < 0) { 1334 /* Template reference. */ 1335 ++tmpuses; 1336 def[i] = lastdfa - d + 1; 1337 } 1338 mkdata(base[i]); 1339 yybase_data[yybase_curr++] = base[i]; 1340 } 1341 1342 /* Generate jam state's base index. */ 1343 mkdata(base[i]); 1344 yybase_data[yybase_curr++] = base[i]; 1345 1346 for (++i /* skip jam state */ ; i <= total_states; ++i) { 1347 mkdata(base[i]); 1348 yybase_data[yybase_curr++] = base[i]; 1349 def[i] = jamstate; 1350 } 1351 1352 dataend(); 1353 if (tablesext) { 1354 yytbl_data_compress(yybase_tbl); 1355 if (yytbl_data_fwrite(&tableswr, yybase_tbl) < 0) 1356 flexerror(_("Could not write yybase_tbl")); 1357 yytbl_data_destroy(yybase_tbl); 1358 yybase_tbl = NULL; 1359 } 1360 /* End generating yy_base */ 1361 1362 1363 /* Begin generating yy_def */ 1364 out_str_dec((total_states >= INT16_MAX || long_align) ? 1365 get_int32_decl() : get_int16_decl(), 1366 "yy_def", total_states + 1); 1367 1368 buf_prints(&yydmap_buf, 1369 "\t{YYTD_ID_DEF, (void**)&yy_def, sizeof(%s)},\n", 1370 (total_states >= INT16_MAX 1371 || long_align) ? "flex_int32_t" : "flex_int16_t"); 1372 1373 yydef_tbl = calloc(1, sizeof(struct yytbl_data)); 1374 yytbl_data_init(yydef_tbl, YYTD_ID_DEF); 1375 yydef_tbl->td_lolen = total_states + 1; 1376 yydef_tbl->td_data = yydef_data = 1377 calloc(yydef_tbl->td_lolen, sizeof(flex_int32_t)); 1378 1379 for (i = 1; i <= total_states; ++i) { 1380 mkdata(def[i]); 1381 yydef_data[i] = def[i]; 1382 } 1383 1384 dataend(); 1385 if (tablesext) { 1386 yytbl_data_compress(yydef_tbl); 1387 if (yytbl_data_fwrite(&tableswr, yydef_tbl) < 0) 1388 flexerror(_("Could not write yydef_tbl")); 1389 yytbl_data_destroy(yydef_tbl); 1390 yydef_tbl = NULL; 1391 } 1392 /* End generating yy_def */ 1393 1394 1395 /* Begin generating yy_nxt */ 1396 out_str_dec((total_states >= INT16_MAX || long_align) ? 1397 get_int32_decl() : get_int16_decl(), "yy_nxt", 1398 tblend + 1); 1399 1400 buf_prints(&yydmap_buf, 1401 "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n", 1402 (total_states >= INT16_MAX 1403 || long_align) ? "flex_int32_t" : "flex_int16_t"); 1404 1405 yynxt_tbl = calloc(1, sizeof(struct yytbl_data)); 1406 yytbl_data_init(yynxt_tbl, YYTD_ID_NXT); 1407 yynxt_tbl->td_lolen = tblend + 1; 1408 yynxt_tbl->td_data = yynxt_data = 1409 calloc(yynxt_tbl->td_lolen, sizeof(flex_int32_t)); 1410 1411 for (i = 1; i <= tblend; ++i) { 1412 /* 1413 * Note, the order of the following test is important. If 1414 * chk[i] is 0, then nxt[i] is undefined. 1415 */ 1416 if (chk[i] == 0 || nxt[i] == 0) 1417 nxt[i] = jamstate; /* new state is the JAM state */ 1418 1419 mkdata(nxt[i]); 1420 yynxt_data[i] = nxt[i]; 1421 } 1422 1423 dataend(); 1424 if (tablesext) { 1425 yytbl_data_compress(yynxt_tbl); 1426 if (yytbl_data_fwrite(&tableswr, yynxt_tbl) < 0) 1427 flexerror(_("Could not write yynxt_tbl")); 1428 yytbl_data_destroy(yynxt_tbl); 1429 yynxt_tbl = NULL; 1430 } 1431 /* End generating yy_nxt */ 1432 1433 /* Begin generating yy_chk */ 1434 out_str_dec((total_states >= INT16_MAX || long_align) ? 1435 get_int32_decl() : get_int16_decl(), "yy_chk", 1436 tblend + 1); 1437 1438 buf_prints(&yydmap_buf, 1439 "\t{YYTD_ID_CHK, (void**)&yy_chk, sizeof(%s)},\n", 1440 (total_states >= INT16_MAX 1441 || long_align) ? "flex_int32_t" : "flex_int16_t"); 1442 1443 yychk_tbl = calloc(1, sizeof(struct yytbl_data)); 1444 yytbl_data_init(yychk_tbl, YYTD_ID_CHK); 1445 yychk_tbl->td_lolen = tblend + 1; 1446 yychk_tbl->td_data = yychk_data = 1447 calloc(yychk_tbl->td_lolen, sizeof(flex_int32_t)); 1448 1449 for (i = 1; i <= tblend; ++i) { 1450 if (chk[i] == 0) 1451 ++nummt; 1452 1453 mkdata(chk[i]); 1454 yychk_data[i] = chk[i]; 1455 } 1456 1457 dataend(); 1458 if (tablesext) { 1459 yytbl_data_compress(yychk_tbl); 1460 if (yytbl_data_fwrite(&tableswr, yychk_tbl) < 0) 1461 flexerror(_("Could not write yychk_tbl")); 1462 yytbl_data_destroy(yychk_tbl); 1463 yychk_tbl = NULL; 1464 } 1465 /* End generating yy_chk */ 1466 1467 free(acc_array); 1468 } 1469 1470 1471 /* Write out a formatted string (with a secondary string argument) at the 1472 * current indentation level, adding a final newline. 1473 */ 1474 1475 void 1476 indent_put2s(const char *fmt, const char *arg) 1477 { 1478 do_indent(); 1479 out_str(fmt, arg); 1480 outn(""); 1481 } 1482 1483 1484 /* Write out a string at the current indentation level, adding a final 1485 * newline. 1486 */ 1487 1488 void 1489 indent_puts(const char *str) 1490 { 1491 do_indent(); 1492 outn(str); 1493 } 1494 1495 1496 /* make_tables - generate transition tables and finishes generating output file 1497 */ 1498 1499 void 1500 make_tables(void) 1501 { 1502 int i; 1503 int did_eof_rule = false; 1504 struct yytbl_data *yynultrans_tbl; 1505 1506 1507 skelout(); /* %% [2.0] - break point in skel */ 1508 1509 /* 1510 * First, take care of YY_DO_BEFORE_ACTION depending on yymore being 1511 * used. 1512 */ 1513 set_indent(1); 1514 1515 if (yymore_used && !yytext_is_array) { 1516 indent_puts("YY_G(yytext_ptr) -= YY_G(yy_more_len); \\"); 1517 indent_puts 1518 ("yyleng = (size_t) (yy_cp - YY_G(yytext_ptr)); \\"); 1519 } else 1520 indent_puts("yyleng = (size_t) (yy_cp - yy_bp); \\"); 1521 1522 /* Now also deal with copying yytext_ptr to yytext if needed. */ 1523 skelout(); /* %% [3.0] - break point in skel */ 1524 if (yytext_is_array) { 1525 if (yymore_used) 1526 indent_puts 1527 ("if ( yyleng + YY_G(yy_more_offset) >= YYLMAX ) \\"); 1528 else 1529 indent_puts("if ( yyleng >= YYLMAX ) \\"); 1530 1531 indent_up(); 1532 indent_puts 1533 ("YY_FATAL_ERROR( \"token too large, exceeds YYLMAX\" ); \\"); 1534 indent_down(); 1535 1536 if (yymore_used) { 1537 indent_puts 1538 ("yy_flex_strncpy( &yytext[YY_G(yy_more_offset)], YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); 1539 indent_puts("yyleng += YY_G(yy_more_offset); \\"); 1540 indent_puts 1541 ("YY_G(yy_prev_more_offset) = YY_G(yy_more_offset); \\"); 1542 indent_puts("YY_G(yy_more_offset) = 0; \\"); 1543 } else { 1544 indent_puts 1545 ("yy_flex_strncpy( yytext, YY_G(yytext_ptr), yyleng + 1 M4_YY_CALL_LAST_ARG); \\"); 1546 } 1547 } 1548 set_indent(0); 1549 1550 skelout(); /* %% [4.0] - break point in skel */ 1551 1552 1553 /* This is where we REALLY begin generating the tables. */ 1554 1555 out_dec("#define YY_NUM_RULES %d\n", num_rules); 1556 out_dec("#define YY_END_OF_BUFFER %d\n", num_rules + 1); 1557 1558 if (fullspd) { 1559 /* 1560 * Need to define the transet type as a size large enough to 1561 * hold the biggest offset. 1562 */ 1563 int total_table_size = tblend + numecs + 1; 1564 char *trans_offset_type = 1565 (total_table_size >= INT16_MAX || long_align) ? 1566 "flex_int32_t" : "flex_int16_t"; 1567 1568 set_indent(0); 1569 indent_puts("struct yy_trans_info"); 1570 indent_up(); 1571 indent_puts("{"); 1572 1573 /* 1574 * We require that yy_verify and yy_nxt must be of the same 1575 * size int. 1576 */ 1577 indent_put2s("%s yy_verify;", trans_offset_type); 1578 1579 /* 1580 * In cases where its sister yy_verify *is* a "yes, there is 1581 * a transition", yy_nxt is the offset (in records) to the 1582 * next state. In most cases where there is no transition, 1583 * the value of yy_nxt is irrelevant. If yy_nxt is the -1th 1584 * record of a state, though, then yy_nxt is the action 1585 * number for that state. 1586 */ 1587 1588 indent_put2s("%s yy_nxt;", trans_offset_type); 1589 indent_puts("};"); 1590 indent_down(); 1591 } else { 1592 /* 1593 * We generate a bogus 'struct yy_trans_info' data type so we 1594 * can guarantee that it is always declared in the skel. This 1595 * is so we can compile "sizeof(struct yy_trans_info)" in any 1596 * scanner. 1597 */ 1598 indent_puts 1599 ("/* This struct is not used in this scanner,"); 1600 indent_puts(" but its presence is necessary. */"); 1601 indent_puts("struct yy_trans_info"); 1602 indent_up(); 1603 indent_puts("{"); 1604 indent_puts("flex_int32_t yy_verify;"); 1605 indent_puts("flex_int32_t yy_nxt;"); 1606 indent_puts("};"); 1607 indent_down(); 1608 } 1609 1610 if (fullspd) { 1611 genctbl(); 1612 if (tablesext) { 1613 struct yytbl_data *tbl; 1614 1615 tbl = mkctbl(); 1616 yytbl_data_compress(tbl); 1617 if (yytbl_data_fwrite(&tableswr, tbl) < 0) 1618 flexerror(_("Could not write ftbl")); 1619 yytbl_data_destroy(tbl); 1620 1621 tbl = mkssltbl(); 1622 yytbl_data_compress(tbl); 1623 if (yytbl_data_fwrite(&tableswr, tbl) < 0) 1624 flexerror(_("Could not write ssltbl")); 1625 yytbl_data_destroy(tbl); 1626 tbl = 0; 1627 1628 if (useecs) { 1629 tbl = mkecstbl(); 1630 yytbl_data_compress(tbl); 1631 if (yytbl_data_fwrite(&tableswr, tbl) < 0) 1632 flexerror(_ 1633 ("Could not write ecstbl")); 1634 yytbl_data_destroy(tbl); 1635 tbl = 0; 1636 } 1637 } 1638 } else if (fulltbl) { 1639 genftbl(); 1640 if (tablesext) { 1641 struct yytbl_data *tbl; 1642 1643 tbl = mkftbl(); 1644 yytbl_data_compress(tbl); 1645 if (yytbl_data_fwrite(&tableswr, tbl) < 0) 1646 flexerror(_("Could not write ftbl")); 1647 yytbl_data_destroy(tbl); 1648 tbl = 0; 1649 1650 if (useecs) { 1651 tbl = mkecstbl(); 1652 yytbl_data_compress(tbl); 1653 if (yytbl_data_fwrite(&tableswr, tbl) < 0) 1654 flexerror(_ 1655 ("Could not write ecstbl")); 1656 yytbl_data_destroy(tbl); 1657 tbl = 0; 1658 } 1659 } 1660 } else 1661 gentabs(); 1662 1663 if (do_yylineno) { 1664 1665 geneoltbl(); 1666 1667 if (tablesext) { 1668 struct yytbl_data *tbl; 1669 1670 tbl = mkeoltbl(); 1671 yytbl_data_compress(tbl); 1672 if (yytbl_data_fwrite(&tableswr, tbl) < 0) 1673 flexerror(_("Could not write eoltbl")); 1674 yytbl_data_destroy(tbl); 1675 tbl = 0; 1676 } 1677 } 1678 /* 1679 * Definitions for backing up. We don't need them if REJECT is being 1680 * used because then we use an alternative backin-up technique 1681 * instead. 1682 */ 1683 if (num_backing_up > 0 && !reject) { 1684 if (!C_plus_plus && !reentrant) { 1685 indent_puts 1686 ("static yy_state_type yy_last_accepting_state;"); 1687 indent_puts 1688 ("static char *yy_last_accepting_cpos;\n"); 1689 } 1690 } 1691 if (nultrans) { 1692 flex_int32_t *yynultrans_data = NULL; 1693 1694 /* Begin generating yy_NUL_trans */ 1695 out_str_dec(get_state_decl(), "yy_NUL_trans", 1696 lastdfa + 1); 1697 buf_prints(&yydmap_buf, 1698 "\t{YYTD_ID_NUL_TRANS, (void**)&yy_NUL_trans, sizeof(%s)},\n", 1699 (fullspd) ? "struct yy_trans_info*" : 1700 "flex_int32_t"); 1701 1702 yynultrans_tbl = calloc(1, sizeof(struct yytbl_data)); 1703 yytbl_data_init(yynultrans_tbl, YYTD_ID_NUL_TRANS); 1704 if (fullspd) 1705 yynultrans_tbl->td_flags |= YYTD_PTRANS; 1706 yynultrans_tbl->td_lolen = lastdfa + 1; 1707 yynultrans_tbl->td_data = yynultrans_data = 1708 calloc(yynultrans_tbl->td_lolen, 1709 sizeof(flex_int32_t)); 1710 1711 for (i = 1; i <= lastdfa; ++i) { 1712 if (fullspd) { 1713 out_dec(" &yy_transition[%d],\n", 1714 base[i]); 1715 yynultrans_data[i] = base[i]; 1716 } else { 1717 mkdata(nultrans[i]); 1718 yynultrans_data[i] = nultrans[i]; 1719 } 1720 } 1721 1722 dataend(); 1723 if (tablesext) { 1724 yytbl_data_compress(yynultrans_tbl); 1725 if (yytbl_data_fwrite(&tableswr, yynultrans_tbl) < 0) 1726 flexerror(_ 1727 ("Could not write yynultrans_tbl")); 1728 yytbl_data_destroy(yynultrans_tbl); 1729 yynultrans_tbl = NULL; 1730 } 1731 /* End generating yy_NUL_trans */ 1732 } 1733 if (!C_plus_plus && !reentrant) { 1734 indent_puts("extern int yy_flex_debug;"); 1735 indent_put2s("int yy_flex_debug = %s;\n", 1736 ddebug ? "1" : "0"); 1737 } 1738 if (ddebug) { /* Spit out table mapping rules to line 1739 * numbers. */ 1740 out_str_dec(long_align ? get_int32_decl() : 1741 get_int16_decl(), "yy_rule_linenum", 1742 num_rules); 1743 for (i = 1; i < num_rules; ++i) 1744 mkdata(rule_linenum[i]); 1745 dataend(); 1746 } 1747 if (reject) { 1748 outn("m4_ifdef( [[M4_YY_USES_REJECT]],\n[["); 1749 /* Declare state buffer variables. */ 1750 if (!C_plus_plus && !reentrant) { 1751 outn("static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;"); 1752 outn("static char *yy_full_match;"); 1753 outn("static int yy_lp;"); 1754 } 1755 if (variable_trailing_context_rules) { 1756 if (!C_plus_plus && !reentrant) { 1757 outn("static int yy_looking_for_trail_begin = 0;"); 1758 outn("static int yy_full_lp;"); 1759 outn("static int *yy_full_state;"); 1760 } 1761 out_hex("#define YY_TRAILING_MASK 0x%x\n", 1762 (unsigned int) YY_TRAILING_MASK); 1763 out_hex("#define YY_TRAILING_HEAD_MASK 0x%x\n", 1764 (unsigned int) YY_TRAILING_HEAD_MASK); 1765 } 1766 outn("#define REJECT \\"); 1767 outn("{ \\"); 1768 outn("*yy_cp = YY_G(yy_hold_char); /* undo effects of setting up yytext */ \\"); 1769 outn("yy_cp = YY_G(yy_full_match); /* restore poss. backed-over text */ \\"); 1770 1771 if (variable_trailing_context_rules) { 1772 outn("YY_G(yy_lp) = YY_G(yy_full_lp); /* restore orig. accepting pos. */ \\"); 1773 outn("YY_G(yy_state_ptr) = YY_G(yy_full_state); /* restore orig. state */ \\"); 1774 outn("yy_current_state = *YY_G(yy_state_ptr); /* restore curr. state */ \\"); 1775 } 1776 outn("++YY_G(yy_lp); \\"); 1777 outn("goto find_rule; \\"); 1778 1779 outn("}"); 1780 outn("]])\n"); 1781 } else { 1782 outn("/* The intent behind this definition is that it'll catch"); 1783 outn(" * any uses of REJECT which flex missed."); 1784 outn(" */"); 1785 outn("#define REJECT reject_used_but_not_detected"); 1786 } 1787 1788 if (yymore_used) { 1789 if (!C_plus_plus) { 1790 if (yytext_is_array) { 1791 if (!reentrant) { 1792 indent_puts("static int yy_more_offset = 0;"); 1793 indent_puts("static int yy_prev_more_offset = 0;"); 1794 } 1795 } else if (!reentrant) { 1796 indent_puts 1797 ("static int yy_more_flag = 0;"); 1798 indent_puts 1799 ("static int yy_more_len = 0;"); 1800 } 1801 } 1802 if (yytext_is_array) { 1803 indent_puts 1804 ("#define yymore() (YY_G(yy_more_offset) = yy_flex_strlen( yytext M4_YY_CALL_LAST_ARG))"); 1805 indent_puts("#define YY_NEED_STRLEN"); 1806 indent_puts("#define YY_MORE_ADJ 0"); 1807 indent_puts 1808 ("#define YY_RESTORE_YY_MORE_OFFSET \\"); 1809 indent_up(); 1810 indent_puts("{ \\"); 1811 indent_puts 1812 ("YY_G(yy_more_offset) = YY_G(yy_prev_more_offset); \\"); 1813 indent_puts("yyleng -= YY_G(yy_more_offset); \\"); 1814 indent_puts("}"); 1815 indent_down(); 1816 } else { 1817 indent_puts 1818 ("#define yymore() (YY_G(yy_more_flag) = 1)"); 1819 indent_puts 1820 ("#define YY_MORE_ADJ YY_G(yy_more_len)"); 1821 indent_puts("#define YY_RESTORE_YY_MORE_OFFSET"); 1822 } 1823 } else { 1824 indent_puts 1825 ("#define yymore() yymore_used_but_not_detected"); 1826 indent_puts("#define YY_MORE_ADJ 0"); 1827 indent_puts("#define YY_RESTORE_YY_MORE_OFFSET"); 1828 } 1829 1830 if (!C_plus_plus) { 1831 if (yytext_is_array) { 1832 outn("#ifndef YYLMAX"); 1833 outn("#define YYLMAX 8192"); 1834 outn("#endif\n"); 1835 if (!reentrant) { 1836 outn("char yytext[YYLMAX];"); 1837 outn("char *yytext_ptr;"); 1838 } 1839 } else { 1840 if (!reentrant) 1841 outn("char *yytext;"); 1842 } 1843 } 1844 out(&action_array[defs1_offset]); 1845 1846 line_directive_out(stdout, 0); 1847 1848 skelout(); /* %% [5.0] - break point in skel */ 1849 1850 if (!C_plus_plus) { 1851 if (use_read) { 1852 outn("\terrno=0; \\"); 1853 outn("\twhile ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \\"); 1854 outn("\t{ \\"); 1855 outn("\t\tif( errno != EINTR) \\"); 1856 outn("\t\t{ \\"); 1857 outn("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); 1858 outn("\t\t\tbreak; \\"); 1859 outn("\t\t} \\"); 1860 outn("\t\terrno=0; \\"); 1861 outn("\t\tclearerr(yyin); \\"); 1862 outn("\t}\\"); 1863 } else { 1864 outn("\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\"); 1865 outn("\t\t{ \\"); 1866 outn("\t\tint c = '*'; \\"); 1867 outn("\t\tsize_t n; \\"); 1868 outn("\t\tfor ( n = 0; n < max_size && \\"); 1869 outn("\t\t\t (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\"); 1870 outn("\t\t\tbuf[n] = (char) c; \\"); 1871 outn("\t\tif ( c == '\\n' ) \\"); 1872 outn("\t\t\tbuf[n++] = (char) c; \\"); 1873 outn("\t\tif ( c == EOF && ferror( yyin ) ) \\"); 1874 outn("\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); 1875 outn("\t\tresult = n; \\"); 1876 outn("\t\t} \\"); 1877 outn("\telse \\"); 1878 outn("\t\t{ \\"); 1879 outn("\t\terrno=0; \\"); 1880 outn("\t\twhile ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \\"); 1881 outn("\t\t\t{ \\"); 1882 outn("\t\t\tif( errno != EINTR) \\"); 1883 outn("\t\t\t\t{ \\"); 1884 outn("\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\"); 1885 outn("\t\t\t\tbreak; \\"); 1886 outn("\t\t\t\t} \\"); 1887 outn("\t\t\terrno=0; \\"); 1888 outn("\t\t\tclearerr(yyin); \\"); 1889 outn("\t\t\t} \\"); 1890 outn("\t\t}\\"); 1891 } 1892 } 1893 skelout(); /* %% [6.0] - break point in skel */ 1894 1895 indent_puts("#define YY_RULE_SETUP \\"); 1896 indent_up(); 1897 if (bol_needed) { 1898 indent_puts("if ( yyleng > 0 ) \\"); 1899 indent_up(); 1900 indent_puts("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \\"); 1901 indent_puts("\t\t(yytext[yyleng - 1] == '\\n'); \\"); 1902 indent_down(); 1903 } 1904 indent_puts("YY_USER_ACTION"); 1905 indent_down(); 1906 1907 skelout(); /* %% [7.0] - break point in skel */ 1908 1909 /* Copy prolog to output file. */ 1910 out(&action_array[prolog_offset]); 1911 1912 line_directive_out(stdout, 0); 1913 1914 skelout(); /* %% [8.0] - break point in skel */ 1915 1916 set_indent(2); 1917 1918 if (yymore_used && !yytext_is_array) { 1919 indent_puts("YY_G(yy_more_len) = 0;"); 1920 indent_puts("if ( YY_G(yy_more_flag) )"); 1921 indent_up(); 1922 indent_puts("{"); 1923 indent_puts 1924 ("YY_G(yy_more_len) = YY_G(yy_c_buf_p) - YY_G(yytext_ptr);"); 1925 indent_puts("YY_G(yy_more_flag) = 0;"); 1926 indent_puts("}"); 1927 indent_down(); 1928 } 1929 skelout(); /* %% [9.0] - break point in skel */ 1930 1931 gen_start_state(); 1932 1933 /* Note, don't use any indentation. */ 1934 outn("yy_match:"); 1935 gen_next_match(); 1936 1937 skelout(); /* %% [10.0] - break point in skel */ 1938 set_indent(2); 1939 gen_find_action(); 1940 1941 skelout(); /* %% [11.0] - break point in skel */ 1942 outn("m4_ifdef( [[M4_YY_USE_LINENO]],[["); 1943 indent_puts 1944 ("if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )"); 1945 indent_up(); 1946 indent_puts("{"); 1947 indent_puts("yy_size_t yyl;"); 1948 do_indent(); 1949 out_str("for ( yyl = %s; yyl < yyleng; ++yyl )\n", 1950 yymore_used ? (yytext_is_array ? "YY_G(yy_prev_more_offset)" : 1951 "YY_G(yy_more_len)") : "0"); 1952 indent_up(); 1953 indent_puts("if ( yytext[yyl] == '\\n' )"); 1954 indent_up(); 1955 indent_puts("M4_YY_INCR_LINENO();"); 1956 indent_down(); 1957 indent_down(); 1958 indent_puts("}"); 1959 indent_down(); 1960 outn("]])"); 1961 1962 skelout(); /* %% [12.0] - break point in skel */ 1963 if (ddebug) { 1964 indent_puts("if ( yy_flex_debug )"); 1965 indent_up(); 1966 1967 indent_puts("{"); 1968 indent_puts("if ( yy_act == 0 )"); 1969 indent_up(); 1970 indent_puts(C_plus_plus ? 1971 "std::cerr << \"--scanner backing up\\n\";" : 1972 "fprintf( stderr, \"--scanner backing up\\n\" );"); 1973 indent_down(); 1974 1975 do_indent(); 1976 out_dec("else if ( yy_act < %d )\n", num_rules); 1977 indent_up(); 1978 1979 if (C_plus_plus) { 1980 indent_puts 1981 ("std::cerr << \"--accepting rule at line \" << yy_rule_linenum[yy_act] <<"); 1982 indent_puts 1983 (" \"(\\\"\" << yytext << \"\\\")\\n\";"); 1984 } else { 1985 indent_puts 1986 ("fprintf( stderr, \"--accepting rule at line %ld (\\\"%s\\\")\\n\","); 1987 1988 indent_puts 1989 (" (long)yy_rule_linenum[yy_act], yytext );"); 1990 } 1991 1992 indent_down(); 1993 1994 do_indent(); 1995 out_dec("else if ( yy_act == %d )\n", num_rules); 1996 indent_up(); 1997 1998 if (C_plus_plus) { 1999 indent_puts 2000 ("std::cerr << \"--accepting default rule (\\\"\" << yytext << \"\\\")\\n\";"); 2001 } else { 2002 indent_puts 2003 ("fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\","); 2004 indent_puts(" yytext );"); 2005 } 2006 2007 indent_down(); 2008 2009 do_indent(); 2010 out_dec("else if ( yy_act == %d )\n", num_rules + 1); 2011 indent_up(); 2012 2013 indent_puts(C_plus_plus ? 2014 "std::cerr << \"--(end of buffer or a NUL)\\n\";" : 2015 "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );"); 2016 2017 indent_down(); 2018 2019 do_indent(); 2020 outn("else"); 2021 indent_up(); 2022 2023 if (C_plus_plus) { 2024 indent_puts 2025 ("std::cerr << \"--EOF (start condition \" << YY_START << \")\\n\";"); 2026 } else { 2027 indent_puts 2028 ("fprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );"); 2029 } 2030 2031 indent_down(); 2032 2033 indent_puts("}"); 2034 indent_down(); 2035 } 2036 /* Copy actions to output file. */ 2037 skelout(); /* %% [13.0] - break point in skel */ 2038 indent_up(); 2039 gen_bu_action(); 2040 out(&action_array[action_offset]); 2041 2042 line_directive_out(stdout, 0); 2043 2044 /* generate cases for any missing EOF rules */ 2045 for (i = 1; i <= lastsc; ++i) 2046 if (!sceof[i]) { 2047 do_indent(); 2048 out_str("case YY_STATE_EOF(%s):\n", scname[i]); 2049 did_eof_rule = true; 2050 } 2051 if (did_eof_rule) { 2052 indent_up(); 2053 indent_puts("yyterminate();"); 2054 indent_down(); 2055 } 2056 /* Generate code for handling NUL's, if needed. */ 2057 2058 /* 2059 * First, deal with backing up and setting up yy_cp if the scanner 2060 * finds that it should JAM on the NUL. 2061 */ 2062 skelout(); /* %% [14.0] - break point in skel */ 2063 set_indent(4); 2064 2065 if (fullspd || fulltbl) 2066 indent_puts("yy_cp = YY_G(yy_c_buf_p);"); 2067 2068 else { /* compressed table */ 2069 if (!reject && !interactive) { 2070 /* 2071 * Do the guaranteed-needed backing up to figure out 2072 * the match. 2073 */ 2074 indent_puts 2075 ("yy_cp = YY_G(yy_last_accepting_cpos);"); 2076 indent_puts 2077 ("yy_current_state = YY_G(yy_last_accepting_state);"); 2078 } else 2079 /* 2080 * Still need to initialize yy_cp, though 2081 * yy_current_state was set up by 2082 * yy_get_previous_state(). 2083 */ 2084 indent_puts("yy_cp = YY_G(yy_c_buf_p);"); 2085 } 2086 2087 2088 /* Generate code for yy_get_previous_state(). */ 2089 set_indent(1); 2090 skelout(); /* %% [15.0] - break point in skel */ 2091 2092 gen_start_state(); 2093 2094 set_indent(2); 2095 skelout(); /* %% [16.0] - break point in skel */ 2096 gen_next_state(true); 2097 2098 set_indent(1); 2099 skelout(); /* %% [17.0] - break point in skel */ 2100 gen_NUL_trans(); 2101 2102 skelout(); /* %% [18.0] - break point in skel */ 2103 skelout(); /* %% [19.0] - break point in skel */ 2104 /* Update BOL and yylineno inside of input(). */ 2105 if (bol_needed) { 2106 indent_puts 2107 ("YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\\n');"); 2108 if (do_yylineno) { 2109 indent_puts 2110 ("if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol )"); 2111 indent_up(); 2112 indent_puts("M4_YY_INCR_LINENO();"); 2113 indent_down(); 2114 } 2115 } else if (do_yylineno) { 2116 indent_puts("if ( c == '\\n' )"); 2117 indent_up(); 2118 indent_puts("M4_YY_INCR_LINENO();"); 2119 indent_down(); 2120 } 2121 skelout(); 2122 2123 /* Copy remainder of input to output. */ 2124 2125 line_directive_out(stdout, 1); 2126 2127 if (sectnum == 3) { 2128 OUT_BEGIN_CODE(); 2129 (void) flexscan(); /* copy remainder of input to output */ 2130 OUT_END_CODE(); 2131 } 2132 } 2133