|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1990 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Vern Paxson. ! 7: * ! 8: * The United States Government has rights in this work pursuant ! 9: * to contract no. DE-AC03-76SF00098 between the United States ! 10: * Department of Energy and the University of California. ! 11: * ! 12: * Redistribution and use in source and binary forms are permitted provided ! 13: * that: (1) source distributions retain this entire copyright notice and ! 14: * comment, and (2) distributions including binaries display the following ! 15: * acknowledgement: ``This product includes software developed by the ! 16: * University of California, Berkeley and its contributors'' in the ! 17: * documentation or other materials provided with the distribution and in ! 18: * all advertising materials mentioning features or use of this software. ! 19: * Neither the name of the University nor the names of its contributors may ! 20: * be used to endorse or promote products derived from this software without ! 21: * specific prior written permission. ! 22: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 23: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 24: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 25: */ ! 26: ! 27: #ifndef lint ! 28: static char sccsid[] = "@(#)gen.c 5.2 (Berkeley) 6/18/90"; ! 29: #endif /* not lint */ ! 30: ! 31: /* gen - actual generation (writing) of flex scanners */ ! 32: ! 33: #include "flexdef.h" ! 34: ! 35: /* declare functions that have forward references */ ! 36: ! 37: void gen_next_state PROTO((int)); ! 38: void genecs PROTO(()); ! 39: void indent_put2s PROTO((char [], char [])); ! 40: void indent_puts PROTO((char [])); ! 41: ! 42: ! 43: static int indent_level = 0; /* each level is 4 spaces */ ! 44: ! 45: #define indent_up() (++indent_level) ! 46: #define indent_down() (--indent_level) ! 47: #define set_indent(indent_val) indent_level = indent_val ! 48: ! 49: /* *everything* is done in terms of arrays starting at 1, so provide ! 50: * a null entry for the zero element of all C arrays ! 51: */ ! 52: static char C_short_decl[] = "static const short int %s[%d] =\n { 0,\n"; ! 53: static char C_long_decl[] = "static const long int %s[%d] =\n { 0,\n"; ! 54: static char C_state_decl[] = ! 55: "static const yy_state_type %s[%d] =\n { 0,\n"; ! 56: ! 57: ! 58: /* indent to the current level */ ! 59: ! 60: void do_indent() ! 61: ! 62: { ! 63: register int i = indent_level * 4; ! 64: ! 65: while ( i >= 8 ) ! 66: { ! 67: putchar( '\t' ); ! 68: i -= 8; ! 69: } ! 70: ! 71: while ( i > 0 ) ! 72: { ! 73: putchar( ' ' ); ! 74: --i; ! 75: } ! 76: } ! 77: ! 78: ! 79: /* generate the code to keep backtracking information */ ! 80: ! 81: void gen_backtracking() ! 82: ! 83: { ! 84: if ( reject || num_backtracking == 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 backtrack */ ! 102: ! 103: void gen_bt_action() ! 104: ! 105: { ! 106: if ( reject || num_backtracking == 0 ) ! 107: return; ! 108: ! 109: set_indent( 3 ); ! 110: ! 111: indent_puts( "case 0: /* must backtrack */" ); ! 112: indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" ); ! 113: indent_puts( "*yy_cp = yy_hold_char;" ); ! 114: ! 115: if ( fullspd || fulltbl ) ! 116: indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" ); ! 117: else ! 118: /* backtracking info for compressed tables is taken \after/ ! 119: * yy_cp has been incremented for the next state ! 120: */ ! 121: indent_puts( "yy_cp = yy_last_accepting_cpos;" ); ! 122: ! 123: indent_puts( "yy_current_state = yy_last_accepting_state;" ); ! 124: indent_puts( "goto yy_find_action;" ); ! 125: putchar( '\n' ); ! 126: ! 127: set_indent( 0 ); ! 128: } ! 129: ! 130: ! 131: /* genctbl - generates full speed compressed transition table ! 132: * ! 133: * synopsis ! 134: * genctbl(); ! 135: */ ! 136: ! 137: void genctbl() ! 138: ! 139: { ! 140: register int i; ! 141: int end_of_buffer_action = num_rules + 1; ! 142: ! 143: /* table of verify for transition and offset to next state */ ! 144: printf( "static const struct yy_trans_info yy_transition[%d] =\n", ! 145: tblend + numecs + 1 ); ! 146: printf( " {\n" ); ! 147: ! 148: /* We want the transition to be represented as the offset to the ! 149: * next state, not the actual state number, which is what it currently is. ! 150: * The offset is base[nxt[i]] - base[chk[i]]. That's just the ! 151: * difference between the starting points of the two involved states ! 152: * (to - from). ! 153: * ! 154: * first, though, we need to find some way to put in our end-of-buffer ! 155: * flags and states. We do this by making a state with absolutely no ! 156: * transitions. We put it at the end of the table. ! 157: */ ! 158: /* at this point, we're guaranteed that there's enough room in nxt[] ! 159: * and chk[] to hold tblend + numecs entries. We need just two slots. ! 160: * One for the action and one for the end-of-buffer transition. We ! 161: * now *assume* that we're guaranteed the only character we'll try to ! 162: * index this nxt/chk pair with is EOB, i.e., 0, so we don't have to ! 163: * make sure there's room for jam entries for other characters. ! 164: */ ! 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: nxt[tblend + 2] = 0; /* so that "make test" won't show arb. differences */ ! 171: ! 172: /* make sure every state has a end-of-buffer transition and an action # */ ! 173: for ( i = 0; i <= lastdfa; ++i ) ! 174: { ! 175: register int anum = dfaacc[i].dfaacc_state; ! 176: ! 177: chk[base[i]] = EOB_POSITION; ! 178: chk[base[i] - 1] = ACTION_POSITION; ! 179: nxt[base[i] - 1] = anum; /* action number */ ! 180: } ! 181: ! 182: for ( i = 0; i <= tblend; ++i ) ! 183: { ! 184: if ( chk[i] == EOB_POSITION ) ! 185: transition_struct_out( 0, base[lastdfa + 1] - i ); ! 186: ! 187: else if ( chk[i] == ACTION_POSITION ) ! 188: transition_struct_out( 0, nxt[i] ); ! 189: ! 190: else if ( chk[i] > numecs || chk[i] == 0 ) ! 191: transition_struct_out( 0, 0 ); /* unused slot */ ! 192: ! 193: else /* verify, transition */ ! 194: transition_struct_out( chk[i], base[nxt[i]] - (i - chk[i]) ); ! 195: } ! 196: ! 197: ! 198: /* here's the final, end-of-buffer state */ ! 199: transition_struct_out( chk[tblend + 1], nxt[tblend + 1] ); ! 200: transition_struct_out( chk[tblend + 2], nxt[tblend + 2] ); ! 201: ! 202: printf( " };\n" ); ! 203: printf( "\n" ); ! 204: ! 205: /* table of pointers to start states */ ! 206: printf( "static const struct yy_trans_info *yy_start_state_list[%d] =\n", ! 207: lastsc * 2 + 1 ); ! 208: printf( " {\n" ); ! 209: ! 210: for ( i = 0; i <= lastsc * 2; ++i ) ! 211: printf( " &yy_transition[%d],\n", base[i] ); ! 212: ! 213: dataend(); ! 214: ! 215: if ( useecs ) ! 216: genecs(); ! 217: } ! 218: ! 219: ! 220: /* generate equivalence-class tables */ ! 221: ! 222: void genecs() ! 223: ! 224: { ! 225: register int i, j; ! 226: static char C_char_decl[] = "static const %s %s[%d] =\n { 0,\n"; ! 227: int numrows; ! 228: Char clower(); ! 229: ! 230: if ( numecs < csize ) ! 231: printf( C_char_decl, "YY_CHAR", "yy_ec", csize ); ! 232: else ! 233: printf( C_char_decl, "short", "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: char *readable_form(); ! 249: ! 250: fputs( "\n\nEquivalence Classes:\n\n", stderr ); ! 251: ! 252: numrows = csize / 8; ! 253: ! 254: for ( j = 0; j < numrows; ++j ) ! 255: { ! 256: for ( i = j; i < csize; i = i + numrows ) ! 257: { ! 258: fprintf( stderr, "%4s = %-2d", readable_form( i ), ecgroup[i] ); ! 259: ! 260: putc( ' ', stderr ); ! 261: } ! 262: ! 263: putc( '\n', stderr ); ! 264: } ! 265: } ! 266: } ! 267: ! 268: ! 269: /* generate the code to find the action number */ ! 270: ! 271: void gen_find_action() ! 272: ! 273: { ! 274: if ( fullspd ) ! 275: indent_puts( "yy_act = yy_current_state[-1].yy_nxt;" ); ! 276: ! 277: else if ( fulltbl ) ! 278: indent_puts( "yy_act = yy_accept[yy_current_state];" ); ! 279: ! 280: else if ( reject ) ! 281: { ! 282: indent_puts( "yy_current_state = *--yy_state_ptr;" ); ! 283: indent_puts( "yy_lp = yy_accept[yy_current_state];" ); ! 284: ! 285: puts( "find_rule: /* we branch to this label when backtracking */" ); ! 286: ! 287: indent_puts( "for ( ; ; ) /* until we find what rule we matched */" ); ! 288: ! 289: indent_up(); ! 290: ! 291: indent_puts( "{" ); ! 292: ! 293: indent_puts( "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" ); ! 294: indent_up(); ! 295: indent_puts( "{" ); ! 296: indent_puts( "yy_act = yy_acclist[yy_lp];" ); ! 297: ! 298: if ( variable_trailing_context_rules ) ! 299: { ! 300: indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" ); ! 301: indent_puts( " yy_looking_for_trail_begin )" ); ! 302: indent_up(); ! 303: indent_puts( "{" ); ! 304: ! 305: indent_puts( "if ( yy_act == yy_looking_for_trail_begin )" ); ! 306: indent_up(); ! 307: indent_puts( "{" ); ! 308: indent_puts( "yy_looking_for_trail_begin = 0;" ); ! 309: indent_puts( "yy_act &= ~YY_TRAILING_HEAD_MASK;" ); ! 310: indent_puts( "break;" ); ! 311: indent_puts( "}" ); ! 312: indent_down(); ! 313: ! 314: indent_puts( "}" ); ! 315: indent_down(); ! 316: ! 317: indent_puts( "else if ( yy_act & YY_TRAILING_MASK )" ); ! 318: indent_up(); ! 319: indent_puts( "{" ); ! 320: indent_puts( ! 321: "yy_looking_for_trail_begin = yy_act & ~YY_TRAILING_MASK;" ); ! 322: indent_puts( ! 323: "yy_looking_for_trail_begin |= YY_TRAILING_HEAD_MASK;" ); ! 324: ! 325: if ( real_reject ) ! 326: { ! 327: /* remember matched text in case we back up due to REJECT */ ! 328: indent_puts( "yy_full_match = yy_cp;" ); ! 329: indent_puts( "yy_full_state = yy_state_ptr;" ); ! 330: indent_puts( "yy_full_lp = yy_lp;" ); ! 331: } ! 332: ! 333: indent_puts( "}" ); ! 334: indent_down(); ! 335: ! 336: indent_puts( "else" ); ! 337: indent_up(); ! 338: indent_puts( "{" ); ! 339: indent_puts( "yy_full_match = yy_cp;" ); ! 340: indent_puts( "yy_full_state = yy_state_ptr;" ); ! 341: indent_puts( "yy_full_lp = yy_lp;" ); ! 342: indent_puts( "break;" ); ! 343: indent_puts( "}" ); ! 344: indent_down(); ! 345: ! 346: indent_puts( "++yy_lp;" ); ! 347: indent_puts( "goto find_rule;" ); ! 348: } ! 349: ! 350: else ! 351: { ! 352: /* remember matched text in case we back up due to trailing context ! 353: * plus REJECT ! 354: */ ! 355: indent_up(); ! 356: indent_puts( "{" ); ! 357: indent_puts( "yy_full_match = yy_cp;" ); ! 358: indent_puts( "break;" ); ! 359: indent_puts( "}" ); ! 360: indent_down(); ! 361: } ! 362: ! 363: indent_puts( "}" ); ! 364: indent_down(); ! 365: ! 366: indent_puts( "--yy_cp;" ); ! 367: ! 368: /* we could consolidate the following two lines with those at ! 369: * the beginning, but at the cost of complaints that we're ! 370: * branching inside a loop ! 371: */ ! 372: indent_puts( "yy_current_state = *--yy_state_ptr;" ); ! 373: indent_puts( "yy_lp = yy_accept[yy_current_state];" ); ! 374: ! 375: indent_puts( "}" ); ! 376: ! 377: indent_down(); ! 378: } ! 379: ! 380: else ! 381: /* compressed */ ! 382: indent_puts( "yy_act = yy_accept[yy_current_state];" ); ! 383: } ! 384: ! 385: ! 386: /* genftbl - generates full transition table ! 387: * ! 388: * synopsis ! 389: * genftbl(); ! 390: */ ! 391: ! 392: void genftbl() ! 393: ! 394: { ! 395: register int i; ! 396: int end_of_buffer_action = num_rules + 1; ! 397: ! 398: printf( C_short_decl, "yy_accept", lastdfa + 1 ); ! 399: ! 400: ! 401: dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; ! 402: ! 403: for ( i = 1; i <= lastdfa; ++i ) ! 404: { ! 405: register int anum = dfaacc[i].dfaacc_state; ! 406: ! 407: mkdata( anum ); ! 408: ! 409: if ( trace && anum ) ! 410: fprintf( stderr, "state # %d accepts: [%d]\n", i, anum ); ! 411: } ! 412: ! 413: dataend(); ! 414: ! 415: if ( useecs ) ! 416: genecs(); ! 417: ! 418: /* don't have to dump the actual full table entries - they were created ! 419: * on-the-fly ! 420: */ ! 421: } ! 422: ! 423: ! 424: /* generate the code to find the next compressed-table state */ ! 425: ! 426: void gen_next_compressed_state( char_map ) ! 427: char *char_map; ! 428: ! 429: { ! 430: indent_put2s( "register YY_CHAR yy_c = %s;", char_map ); ! 431: ! 432: /* save the backtracking info \before/ computing the next state ! 433: * because we always compute one more state than needed - we ! 434: * always proceed until we reach a jam state ! 435: */ ! 436: gen_backtracking(); ! 437: ! 438: indent_puts( ! 439: "while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )" ); ! 440: indent_up(); ! 441: indent_puts( "{" ); ! 442: indent_puts( "yy_current_state = yy_def[yy_current_state];" ); ! 443: ! 444: if ( usemecs ) ! 445: { ! 446: /* we've arrange it so that templates are never chained ! 447: * to one another. This means we can afford make a ! 448: * very simple test to see if we need to convert to ! 449: * yy_c's meta-equivalence class without worrying ! 450: * about erroneously looking up the meta-equivalence ! 451: * class twice ! 452: */ ! 453: do_indent(); ! 454: /* lastdfa + 2 is the beginning of the templates */ ! 455: printf( "if ( yy_current_state >= %d )\n", lastdfa + 2 ); ! 456: ! 457: indent_up(); ! 458: indent_puts( "yy_c = yy_meta[yy_c];" ); ! 459: indent_down(); ! 460: } ! 461: ! 462: indent_puts( "}" ); ! 463: indent_down(); ! 464: ! 465: indent_puts( ! 466: "yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];" ); ! 467: } ! 468: ! 469: ! 470: /* generate the code to find the next match */ ! 471: ! 472: void gen_next_match() ! 473: ! 474: { ! 475: /* NOTE - changes in here should be reflected in gen_next_state() and ! 476: * gen_NUL_trans() ! 477: */ ! 478: char *char_map = useecs ? "yy_ec[*yy_cp]" : "*yy_cp"; ! 479: char *char_map_2 = useecs ? "yy_ec[*++yy_cp]" : "*++yy_cp"; ! 480: ! 481: if ( fulltbl ) ! 482: { ! 483: indent_put2s( ! 484: "while ( (yy_current_state = yy_nxt[yy_current_state][%s]) > 0 )", ! 485: char_map ); ! 486: ! 487: indent_up(); ! 488: ! 489: if ( num_backtracking > 0 ) ! 490: { ! 491: indent_puts( "{" ); ! 492: gen_backtracking(); ! 493: putchar( '\n' ); ! 494: } ! 495: ! 496: indent_puts( "++yy_cp;" ); ! 497: ! 498: if ( num_backtracking > 0 ) ! 499: indent_puts( "}" ); ! 500: ! 501: indent_down(); ! 502: ! 503: putchar( '\n' ); ! 504: indent_puts( "yy_current_state = -yy_current_state;" ); ! 505: } ! 506: ! 507: else if ( fullspd ) ! 508: { ! 509: indent_puts( "{" ); ! 510: indent_puts( "register const struct yy_trans_info *yy_trans_info;\n" ); ! 511: indent_puts( "register YY_CHAR yy_c;\n" ); ! 512: indent_put2s( "for ( yy_c = %s;", char_map ); ! 513: indent_puts( ! 514: " (yy_trans_info = &yy_current_state[yy_c])->yy_verify == yy_c;" ); ! 515: indent_put2s( " yy_c = %s )", char_map_2 ); ! 516: ! 517: indent_up(); ! 518: ! 519: if ( num_backtracking > 0 ) ! 520: indent_puts( "{" ); ! 521: ! 522: indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); ! 523: ! 524: if ( num_backtracking > 0 ) ! 525: { ! 526: putchar( '\n' ); ! 527: gen_backtracking(); ! 528: indent_puts( "}" ); ! 529: } ! 530: ! 531: indent_down(); ! 532: indent_puts( "}" ); ! 533: } ! 534: ! 535: else ! 536: { /* compressed */ ! 537: indent_puts( "do" ); ! 538: ! 539: indent_up(); ! 540: indent_puts( "{" ); ! 541: ! 542: gen_next_state( false ); ! 543: ! 544: indent_puts( "++yy_cp;" ); ! 545: ! 546: indent_puts( "}" ); ! 547: indent_down(); ! 548: ! 549: do_indent(); ! 550: ! 551: if ( interactive ) ! 552: printf( "while ( yy_base[yy_current_state] != %d );\n", jambase ); ! 553: else ! 554: printf( "while ( yy_current_state != %d );\n", jamstate ); ! 555: ! 556: if ( ! reject && ! interactive ) ! 557: { ! 558: /* do the guaranteed-needed backtrack to figure out the match */ ! 559: indent_puts( "yy_cp = yy_last_accepting_cpos;" ); ! 560: indent_puts( "yy_current_state = yy_last_accepting_state;" ); ! 561: } ! 562: } ! 563: } ! 564: ! 565: ! 566: /* generate the code to find the next state */ ! 567: ! 568: void gen_next_state( worry_about_NULs ) ! 569: int worry_about_NULs; ! 570: ! 571: { /* NOTE - changes in here should be reflected in get_next_match() */ ! 572: char char_map[256]; ! 573: ! 574: if ( worry_about_NULs && ! nultrans ) ! 575: { ! 576: if ( useecs ) ! 577: (void) sprintf( char_map, "(*yy_cp ? yy_ec[*yy_cp] : %d)", NUL_ec ); ! 578: else ! 579: (void) sprintf( char_map, "(*yy_cp ? *yy_cp : %d)", NUL_ec ); ! 580: } ! 581: ! 582: else ! 583: (void) strcpy( char_map, useecs ? "yy_ec[*yy_cp]" : "*yy_cp" ); ! 584: ! 585: if ( worry_about_NULs && nultrans ) ! 586: { ! 587: if ( ! fulltbl && ! fullspd ) ! 588: /* compressed tables backtrack *before* they match */ ! 589: gen_backtracking(); ! 590: ! 591: indent_puts( "if ( *yy_cp )" ); ! 592: indent_up(); ! 593: indent_puts( "{" ); ! 594: } ! 595: ! 596: if ( fulltbl ) ! 597: indent_put2s( "yy_current_state = yy_nxt[yy_current_state][%s];", ! 598: char_map ); ! 599: ! 600: else if ( fullspd ) ! 601: indent_put2s( "yy_current_state += yy_current_state[%s].yy_nxt;", ! 602: char_map ); ! 603: ! 604: else ! 605: gen_next_compressed_state( char_map ); ! 606: ! 607: if ( worry_about_NULs && nultrans ) ! 608: { ! 609: indent_puts( "}" ); ! 610: indent_down(); ! 611: indent_puts( "else" ); ! 612: indent_up(); ! 613: indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" ); ! 614: indent_down(); ! 615: } ! 616: ! 617: if ( fullspd || fulltbl ) ! 618: gen_backtracking(); ! 619: ! 620: if ( reject ) ! 621: indent_puts( "*yy_state_ptr++ = yy_current_state;" ); ! 622: } ! 623: ! 624: ! 625: /* generate the code to make a NUL transition */ ! 626: ! 627: void gen_NUL_trans() ! 628: ! 629: { /* NOTE - changes in here should be reflected in get_next_match() */ ! 630: int need_backtracking = (num_backtracking > 0 && ! reject); ! 631: ! 632: if ( need_backtracking ) ! 633: /* we'll need yy_cp lying around for the gen_backtracking() */ ! 634: indent_puts( "register YY_CHAR *yy_cp = yy_c_buf_p;" ); ! 635: ! 636: putchar( '\n' ); ! 637: ! 638: if ( nultrans ) ! 639: { ! 640: indent_puts( "yy_current_state = yy_NUL_trans[yy_current_state];" ); ! 641: indent_puts( "yy_is_jam = (yy_current_state == 0);" ); ! 642: } ! 643: ! 644: else if ( fulltbl ) ! 645: { ! 646: do_indent(); ! 647: printf( "yy_current_state = yy_nxt[yy_current_state][%d];\n", ! 648: NUL_ec ); ! 649: indent_puts( "yy_is_jam = (yy_current_state <= 0);" ); ! 650: } ! 651: ! 652: else if ( fullspd ) ! 653: { ! 654: do_indent(); ! 655: printf( "register int yy_c = %d;\n", NUL_ec ); ! 656: ! 657: indent_puts( ! 658: "register const struct yy_trans_info *yy_trans_info;\n" ); ! 659: indent_puts( "yy_trans_info = &yy_current_state[yy_c];" ); ! 660: indent_puts( "yy_current_state += yy_trans_info->yy_nxt;" ); ! 661: ! 662: indent_puts( "yy_is_jam = (yy_trans_info->yy_verify != yy_c);" ); ! 663: } ! 664: ! 665: else ! 666: { ! 667: char NUL_ec_str[20]; ! 668: ! 669: (void) sprintf( NUL_ec_str, "%d", NUL_ec ); ! 670: gen_next_compressed_state( NUL_ec_str ); ! 671: ! 672: if ( reject ) ! 673: indent_puts( "*yy_state_ptr++ = yy_current_state;" ); ! 674: ! 675: do_indent(); ! 676: ! 677: if ( interactive ) ! 678: printf( "yy_is_jam = (yy_base[yy_current_state] == %d);\n", ! 679: jambase ); ! 680: else ! 681: printf( "yy_is_jam = (yy_current_state == %d);\n", jamstate ); ! 682: } ! 683: ! 684: /* if we've entered an accepting state, backtrack; note that ! 685: * compressed tables have *already* done such backtracking, so ! 686: * we needn't bother with it again ! 687: */ ! 688: if ( need_backtracking && (fullspd || fulltbl) ) ! 689: { ! 690: putchar( '\n' ); ! 691: indent_puts( "if ( ! yy_is_jam )" ); ! 692: indent_up(); ! 693: indent_puts( "{" ); ! 694: gen_backtracking(); ! 695: indent_puts( "}" ); ! 696: indent_down(); ! 697: } ! 698: } ! 699: ! 700: ! 701: /* generate the code to find the start state */ ! 702: ! 703: void gen_start_state() ! 704: ! 705: { ! 706: if ( fullspd ) ! 707: indent_put2s( "yy_current_state = yy_start_state_list[yy_start%s];", ! 708: bol_needed ? " + (yy_bp[-1] == '\\n' ? 1 : 0)" : "" ); ! 709: ! 710: else ! 711: { ! 712: indent_puts( "yy_current_state = yy_start;" ); ! 713: ! 714: if ( bol_needed ) ! 715: { ! 716: indent_puts( "if ( yy_bp[-1] == '\\n' )" ); ! 717: indent_up(); ! 718: indent_puts( "++yy_current_state;" ); ! 719: indent_down(); ! 720: } ! 721: ! 722: if ( reject ) ! 723: { ! 724: /* set up for storing up states */ ! 725: indent_puts( "yy_state_ptr = yy_state_buf;" ); ! 726: indent_puts( "*yy_state_ptr++ = yy_current_state;" ); ! 727: } ! 728: } ! 729: } ! 730: ! 731: ! 732: /* gentabs - generate data statements for the transition tables ! 733: * ! 734: * synopsis ! 735: * gentabs(); ! 736: */ ! 737: ! 738: void gentabs() ! 739: ! 740: { ! 741: int i, j, k, *accset, nacc, *acc_array, total_states; ! 742: int end_of_buffer_action = num_rules + 1; ! 743: ! 744: /* *everything* is done in terms of arrays starting at 1, so provide ! 745: * a null entry for the zero element of all C arrays ! 746: */ ! 747: static char C_char_decl[] = ! 748: "static const YY_CHAR %s[%d] =\n { 0,\n"; ! 749: ! 750: acc_array = allocate_integer_array( current_max_dfas ); ! 751: nummt = 0; ! 752: ! 753: /* the compressed table format jams by entering the "jam state", ! 754: * losing information about the previous state in the process. ! 755: * In order to recover the previous state, we effectively need ! 756: * to keep backtracking information. ! 757: */ ! 758: ++num_backtracking; ! 759: ! 760: if ( reject ) ! 761: { ! 762: /* write out accepting list and pointer list ! 763: * ! 764: * first we generate the "yy_acclist" array. In the process, we compute ! 765: * the indices that will go into the "yy_accept" array, and save the ! 766: * indices in the dfaacc array ! 767: */ ! 768: int EOB_accepting_list[2]; ! 769: ! 770: /* set up accepting structures for the End Of Buffer state */ ! 771: EOB_accepting_list[0] = 0; ! 772: EOB_accepting_list[1] = end_of_buffer_action; ! 773: accsiz[end_of_buffer_state] = 1; ! 774: dfaacc[end_of_buffer_state].dfaacc_set = EOB_accepting_list; ! 775: ! 776: printf( C_short_decl, "yy_acclist", max( numas, 1 ) + 1 ); ! 777: ! 778: j = 1; /* index into "yy_acclist" array */ ! 779: ! 780: for ( i = 1; i <= lastdfa; ++i ) ! 781: { ! 782: acc_array[i] = j; ! 783: ! 784: if ( accsiz[i] != 0 ) ! 785: { ! 786: accset = dfaacc[i].dfaacc_set; ! 787: nacc = accsiz[i]; ! 788: ! 789: if ( trace ) ! 790: fprintf( stderr, "state # %d accepts: ", i ); ! 791: ! 792: for ( k = 1; k <= nacc; ++k ) ! 793: { ! 794: int accnum = accset[k]; ! 795: ! 796: ++j; ! 797: ! 798: if ( variable_trailing_context_rules && ! 799: ! (accnum & YY_TRAILING_HEAD_MASK) && ! 800: accnum > 0 && ! 801: rule_type[accnum] == RULE_VARIABLE ) ! 802: { ! 803: /* special hack to flag accepting number as part ! 804: * of trailing context rule ! 805: */ ! 806: accnum |= YY_TRAILING_MASK; ! 807: } ! 808: ! 809: mkdata( accnum ); ! 810: ! 811: if ( trace ) ! 812: { ! 813: fprintf( stderr, "[%d]", accset[k] ); ! 814: ! 815: if ( k < nacc ) ! 816: fputs( ", ", stderr ); ! 817: else ! 818: putc( '\n', stderr ); ! 819: } ! 820: } ! 821: } ! 822: } ! 823: ! 824: /* add accepting number for the "jam" state */ ! 825: acc_array[i] = j; ! 826: ! 827: dataend(); ! 828: } ! 829: ! 830: else ! 831: { ! 832: dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; ! 833: ! 834: for ( i = 1; i <= lastdfa; ++i ) ! 835: acc_array[i] = dfaacc[i].dfaacc_state; ! 836: ! 837: /* add accepting number for jam state */ ! 838: acc_array[i] = 0; ! 839: } ! 840: ! 841: /* spit out "yy_accept" array. If we're doing "reject", it'll be pointers ! 842: * into the "yy_acclist" array. Otherwise it's actual accepting numbers. ! 843: * In either case, we just dump the numbers. ! 844: */ ! 845: ! 846: /* "lastdfa + 2" is the size of "yy_accept"; includes room for C arrays ! 847: * beginning at 0 and for "jam" state ! 848: */ ! 849: k = lastdfa + 2; ! 850: ! 851: if ( reject ) ! 852: /* we put a "cap" on the table associating lists of accepting ! 853: * numbers with state numbers. This is needed because we tell ! 854: * where the end of an accepting list is by looking at where ! 855: * the list for the next state starts. ! 856: */ ! 857: ++k; ! 858: ! 859: printf( C_short_decl, "yy_accept", k ); ! 860: ! 861: for ( i = 1; i <= lastdfa; ++i ) ! 862: { ! 863: mkdata( acc_array[i] ); ! 864: ! 865: if ( ! reject && trace && acc_array[i] ) ! 866: fprintf( stderr, "state # %d accepts: [%d]\n", i, acc_array[i] ); ! 867: } ! 868: ! 869: /* add entry for "jam" state */ ! 870: mkdata( acc_array[i] ); ! 871: ! 872: if ( reject ) ! 873: /* add "cap" for the list */ ! 874: mkdata( acc_array[i] ); ! 875: ! 876: dataend(); ! 877: ! 878: if ( useecs ) ! 879: genecs(); ! 880: ! 881: if ( usemecs ) ! 882: { ! 883: /* write out meta-equivalence classes (used to index templates with) */ ! 884: ! 885: if ( trace ) ! 886: fputs( "\n\nMeta-Equivalence Classes:\n", stderr ); ! 887: ! 888: printf( C_char_decl, "yy_meta", numecs + 1 ); ! 889: ! 890: for ( i = 1; i <= numecs; ++i ) ! 891: { ! 892: if ( trace ) ! 893: fprintf( stderr, "%d = %d\n", i, abs( tecbck[i] ) ); ! 894: ! 895: mkdata( abs( tecbck[i] ) ); ! 896: } ! 897: ! 898: dataend(); ! 899: } ! 900: ! 901: total_states = lastdfa + numtemps; ! 902: ! 903: printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl, ! 904: "yy_base", total_states + 1 ); ! 905: ! 906: for ( i = 1; i <= lastdfa; ++i ) ! 907: { ! 908: register int d = def[i]; ! 909: ! 910: if ( base[i] == JAMSTATE ) ! 911: base[i] = jambase; ! 912: ! 913: if ( d == JAMSTATE ) ! 914: def[i] = jamstate; ! 915: ! 916: else if ( d < 0 ) ! 917: { ! 918: /* template reference */ ! 919: ++tmpuses; ! 920: def[i] = lastdfa - d + 1; ! 921: } ! 922: ! 923: mkdata( base[i] ); ! 924: } ! 925: ! 926: /* generate jam state's base index */ ! 927: mkdata( base[i] ); ! 928: ! 929: for ( ++i /* skip jam state */; i <= total_states; ++i ) ! 930: { ! 931: mkdata( base[i] ); ! 932: def[i] = jamstate; ! 933: } ! 934: ! 935: dataend(); ! 936: ! 937: printf( tblend > MAX_SHORT ? C_long_decl : C_short_decl, ! 938: "yy_def", total_states + 1 ); ! 939: ! 940: for ( i = 1; i <= total_states; ++i ) ! 941: mkdata( def[i] ); ! 942: ! 943: dataend(); ! 944: ! 945: printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl, ! 946: "yy_nxt", tblend + 1 ); ! 947: ! 948: for ( i = 1; i <= tblend; ++i ) ! 949: { ! 950: if ( nxt[i] == 0 || chk[i] == 0 ) ! 951: nxt[i] = jamstate; /* new state is the JAM state */ ! 952: ! 953: mkdata( nxt[i] ); ! 954: } ! 955: ! 956: dataend(); ! 957: ! 958: printf( lastdfa > MAX_SHORT ? C_long_decl : C_short_decl, ! 959: "yy_chk", tblend + 1 ); ! 960: ! 961: for ( i = 1; i <= tblend; ++i ) ! 962: { ! 963: if ( chk[i] == 0 ) ! 964: ++nummt; ! 965: ! 966: mkdata( chk[i] ); ! 967: } ! 968: ! 969: dataend(); ! 970: } ! 971: ! 972: ! 973: /* write out a formatted string (with a secondary string argument) at the ! 974: * current indentation level, adding a final newline ! 975: */ ! 976: ! 977: void indent_put2s( fmt, arg ) ! 978: char fmt[], arg[]; ! 979: ! 980: { ! 981: do_indent(); ! 982: printf( fmt, arg ); ! 983: putchar( '\n' ); ! 984: } ! 985: ! 986: ! 987: /* write out a string at the current indentation level, adding a final ! 988: * newline ! 989: */ ! 990: ! 991: void indent_puts( str ) ! 992: char str[]; ! 993: ! 994: { ! 995: do_indent(); ! 996: puts( str ); ! 997: } ! 998: ! 999: ! 1000: /* make_tables - generate transition tables ! 1001: * ! 1002: * synopsis ! 1003: * make_tables(); ! 1004: * ! 1005: * Generates transition tables and finishes generating output file ! 1006: */ ! 1007: ! 1008: void make_tables() ! 1009: ! 1010: { ! 1011: register int i; ! 1012: int did_eof_rule = false; ! 1013: ! 1014: skelout(); ! 1015: ! 1016: /* first, take care of YY_DO_BEFORE_ACTION depending on yymore being used */ ! 1017: set_indent( 2 ); ! 1018: ! 1019: if ( yymore_used ) ! 1020: { ! 1021: indent_puts( "yytext -= yy_more_len; \\" ); ! 1022: indent_puts( "yyleng = yy_cp - yytext; \\" ); ! 1023: } ! 1024: ! 1025: else ! 1026: indent_puts( "yyleng = yy_cp - yy_bp; \\" ); ! 1027: ! 1028: set_indent( 0 ); ! 1029: ! 1030: skelout(); ! 1031: ! 1032: ! 1033: printf( "#define YY_END_OF_BUFFER %d\n", num_rules + 1 ); ! 1034: ! 1035: if ( fullspd ) ! 1036: { /* need to define the transet type as a size large ! 1037: * enough to hold the biggest offset ! 1038: */ ! 1039: int total_table_size = tblend + numecs + 1; ! 1040: char *trans_offset_type = ! 1041: total_table_size > MAX_SHORT ? "long" : "short"; ! 1042: ! 1043: set_indent( 0 ); ! 1044: indent_puts( "struct yy_trans_info" ); ! 1045: indent_up(); ! 1046: indent_puts( "{" ); ! 1047: indent_puts( "short yy_verify;" ); ! 1048: ! 1049: /* in cases where its sister yy_verify *is* a "yes, there is a ! 1050: * transition", yy_nxt is the offset (in records) to the next state. ! 1051: * In most cases where there is no transition, the value of yy_nxt ! 1052: * is irrelevant. If yy_nxt is the -1th record of a state, though, ! 1053: * then yy_nxt is the action number for that state ! 1054: */ ! 1055: ! 1056: indent_put2s( "%s yy_nxt;", trans_offset_type ); ! 1057: indent_puts( "};" ); ! 1058: indent_down(); ! 1059: ! 1060: indent_puts( "typedef const struct yy_trans_info *yy_state_type;" ); ! 1061: } ! 1062: ! 1063: else ! 1064: indent_puts( "typedef int yy_state_type;" ); ! 1065: ! 1066: if ( fullspd ) ! 1067: genctbl(); ! 1068: ! 1069: else if ( fulltbl ) ! 1070: genftbl(); ! 1071: ! 1072: else ! 1073: gentabs(); ! 1074: ! 1075: if ( num_backtracking > 0 ) ! 1076: { ! 1077: indent_puts( "static yy_state_type yy_last_accepting_state;" ); ! 1078: indent_puts( "static YY_CHAR *yy_last_accepting_cpos;\n" ); ! 1079: } ! 1080: ! 1081: if ( nultrans ) ! 1082: { ! 1083: printf( C_state_decl, "yy_NUL_trans", lastdfa + 1 ); ! 1084: ! 1085: for ( i = 1; i <= lastdfa; ++i ) ! 1086: { ! 1087: if ( fullspd ) ! 1088: { ! 1089: if ( nultrans ) ! 1090: printf( " &yy_transition[%d],\n", base[i] ); ! 1091: else ! 1092: printf( " 0,\n" ); ! 1093: } ! 1094: ! 1095: else ! 1096: mkdata( nultrans[i] ); ! 1097: } ! 1098: ! 1099: dataend(); ! 1100: } ! 1101: ! 1102: if ( ddebug ) ! 1103: { /* spit out table mapping rules to line numbers */ ! 1104: indent_puts( "extern int yy_flex_debug;" ); ! 1105: indent_puts( "int yy_flex_debug = 1;\n" ); ! 1106: ! 1107: printf( C_short_decl, "yy_rule_linenum", num_rules ); ! 1108: for ( i = 1; i < num_rules; ++i ) ! 1109: mkdata( rule_linenum[i] ); ! 1110: dataend(); ! 1111: } ! 1112: ! 1113: if ( reject ) ! 1114: { ! 1115: /* declare state buffer variables */ ! 1116: puts( ! 1117: "static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;" ); ! 1118: puts( "static YY_CHAR *yy_full_match;" ); ! 1119: puts( "static int yy_lp;" ); ! 1120: ! 1121: if ( variable_trailing_context_rules ) ! 1122: { ! 1123: puts( "static int yy_looking_for_trail_begin = 0;" ); ! 1124: puts( "static int yy_full_lp;" ); ! 1125: puts( "static int *yy_full_state;" ); ! 1126: printf( "#define YY_TRAILING_MASK 0x%x\n", YY_TRAILING_MASK ); ! 1127: printf( "#define YY_TRAILING_HEAD_MASK 0x%x\n", ! 1128: YY_TRAILING_HEAD_MASK ); ! 1129: } ! 1130: ! 1131: puts( "#define REJECT \\" ); ! 1132: puts( "{ \\" ); ! 1133: puts( ! 1134: "*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \\" ); ! 1135: puts( ! 1136: "yy_cp = yy_full_match; /* restore poss. backed-over text */ \\" ); ! 1137: ! 1138: if ( variable_trailing_context_rules ) ! 1139: { ! 1140: puts( "yy_lp = yy_full_lp; /* restore orig. accepting pos. */ \\" ); ! 1141: puts( ! 1142: "yy_state_ptr = yy_full_state; /* restore orig. state */ \\" ); ! 1143: puts( ! 1144: "yy_current_state = *yy_state_ptr; /* restore curr. state */ \\" ); ! 1145: } ! 1146: ! 1147: puts( "++yy_lp; \\" ); ! 1148: puts( "goto find_rule; \\" ); ! 1149: puts( "}" ); ! 1150: } ! 1151: ! 1152: else ! 1153: { ! 1154: puts( "/* the intent behind this definition is that it'll catch" ); ! 1155: puts( " * any uses of REJECT which flex missed" ); ! 1156: puts( " */" ); ! 1157: puts( "#define REJECT reject_used_but_not_detected" ); ! 1158: } ! 1159: ! 1160: if ( yymore_used ) ! 1161: { ! 1162: indent_puts( "static int yy_more_flag = 0;" ); ! 1163: indent_puts( "static int yy_doing_yy_more = 0;" ); ! 1164: indent_puts( "static int yy_more_len = 0;" ); ! 1165: indent_puts( ! 1166: "#define yymore() { yy_more_flag = 1; }" ); ! 1167: indent_puts( ! 1168: "#define YY_MORE_ADJ (yy_doing_yy_more ? yy_more_len : 0)" ); ! 1169: } ! 1170: ! 1171: else ! 1172: { ! 1173: indent_puts( "#define yymore() yymore_used_but_not_detected" ); ! 1174: indent_puts( "#define YY_MORE_ADJ 0" ); ! 1175: } ! 1176: ! 1177: skelout(); ! 1178: ! 1179: if ( ferror( temp_action_file ) ) ! 1180: flexfatal( "error occurred when writing temporary action file" ); ! 1181: ! 1182: else if ( fclose( temp_action_file ) ) ! 1183: flexfatal( "error occurred when closing temporary action file" ); ! 1184: ! 1185: temp_action_file = fopen( action_file_name, "r" ); ! 1186: ! 1187: if ( temp_action_file == NULL ) ! 1188: flexfatal( "could not re-open temporary action file" ); ! 1189: ! 1190: /* copy prolog from action_file to output file */ ! 1191: action_out(); ! 1192: ! 1193: skelout(); ! 1194: ! 1195: set_indent( 2 ); ! 1196: ! 1197: if ( yymore_used ) ! 1198: { ! 1199: indent_puts( "yy_doing_yy_more = yy_more_flag;" ); ! 1200: indent_puts( "if ( yy_doing_yy_more )" ); ! 1201: indent_up(); ! 1202: indent_puts( "{" ); ! 1203: indent_puts( "yy_more_len = yyleng;" ); ! 1204: indent_puts( "yy_more_flag = 0;" ); ! 1205: indent_puts( "}" ); ! 1206: indent_down(); ! 1207: } ! 1208: ! 1209: skelout(); ! 1210: ! 1211: gen_start_state(); ! 1212: ! 1213: /* note, don't use any indentation */ ! 1214: puts( "yy_match:" ); ! 1215: gen_next_match(); ! 1216: ! 1217: skelout(); ! 1218: set_indent( 2 ); ! 1219: gen_find_action(); ! 1220: ! 1221: skelout(); ! 1222: if ( ddebug ) ! 1223: { ! 1224: indent_puts( "if ( yy_flex_debug )" ); ! 1225: indent_up(); ! 1226: ! 1227: indent_puts( "{" ); ! 1228: indent_puts( "if ( yy_act == 0 )" ); ! 1229: indent_up(); ! 1230: indent_puts( "fprintf( stderr, \"--scanner backtracking\\n\" );" ); ! 1231: indent_down(); ! 1232: ! 1233: do_indent(); ! 1234: printf( "else if ( yy_act < %d )\n", num_rules ); ! 1235: indent_up(); ! 1236: indent_puts( ! 1237: "fprintf( stderr, \"--accepting rule at line %d (\\\"%s\\\")\\n\"," ); ! 1238: indent_puts( " yy_rule_linenum[yy_act], yytext );" ); ! 1239: indent_down(); ! 1240: ! 1241: do_indent(); ! 1242: printf( "else if ( yy_act == %d )\n", num_rules ); ! 1243: indent_up(); ! 1244: indent_puts( ! 1245: "fprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\"," ); ! 1246: indent_puts( " yytext );" ); ! 1247: indent_down(); ! 1248: ! 1249: do_indent(); ! 1250: printf( "else if ( yy_act == %d )\n", num_rules + 1 ); ! 1251: indent_up(); ! 1252: indent_puts( "fprintf( stderr, \"--(end of buffer or a NUL)\\n\" );" ); ! 1253: indent_down(); ! 1254: ! 1255: do_indent(); ! 1256: printf( "else\n" ); ! 1257: indent_up(); ! 1258: indent_puts( "fprintf( stderr, \"--EOF\\n\" );" ); ! 1259: indent_down(); ! 1260: ! 1261: indent_puts( "}" ); ! 1262: indent_down(); ! 1263: } ! 1264: ! 1265: /* copy actions from action_file to output file */ ! 1266: skelout(); ! 1267: indent_up(); ! 1268: gen_bt_action(); ! 1269: action_out(); ! 1270: ! 1271: /* generate cases for any missing EOF rules */ ! 1272: for ( i = 1; i <= lastsc; ++i ) ! 1273: if ( ! sceof[i] ) ! 1274: { ! 1275: do_indent(); ! 1276: printf( "case YY_STATE_EOF(%s):\n", scname[i] ); ! 1277: did_eof_rule = true; ! 1278: } ! 1279: ! 1280: if ( did_eof_rule ) ! 1281: { ! 1282: indent_up(); ! 1283: indent_puts( "yyterminate();" ); ! 1284: indent_down(); ! 1285: } ! 1286: ! 1287: ! 1288: /* generate code for handling NUL's, if needed */ ! 1289: ! 1290: /* first, deal with backtracking and setting up yy_cp if the scanner ! 1291: * finds that it should JAM on the NUL ! 1292: */ ! 1293: skelout(); ! 1294: set_indent( 7 ); ! 1295: ! 1296: if ( fullspd || fulltbl ) ! 1297: indent_puts( "yy_cp = yy_c_buf_p;" ); ! 1298: ! 1299: else ! 1300: { /* compressed table */ ! 1301: if ( ! reject && ! interactive ) ! 1302: { ! 1303: /* do the guaranteed-needed backtrack to figure out the match */ ! 1304: indent_puts( "yy_cp = yy_last_accepting_cpos;" ); ! 1305: indent_puts( "yy_current_state = yy_last_accepting_state;" ); ! 1306: } ! 1307: } ! 1308: ! 1309: ! 1310: /* generate code for yy_get_previous_state() */ ! 1311: set_indent( 1 ); ! 1312: skelout(); ! 1313: ! 1314: if ( bol_needed ) ! 1315: indent_puts( "register YY_CHAR *yy_bp = yytext;\n" ); ! 1316: ! 1317: gen_start_state(); ! 1318: ! 1319: set_indent( 2 ); ! 1320: skelout(); ! 1321: gen_next_state( true ); ! 1322: ! 1323: set_indent( 1 ); ! 1324: skelout(); ! 1325: gen_NUL_trans(); ! 1326: ! 1327: skelout(); ! 1328: ! 1329: /* copy remainder of input to output */ ! 1330: ! 1331: line_directive_out( stdout ); ! 1332: (void) flexscan(); /* copy remainder of input to output */ ! 1333: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.