home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / lex / gen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-12  |  31.6 KB  |  1,348 lines

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