home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / gnu / flexs237.lzh / FLEXS237 / GEN.C < prev    next >
C/C++ Source or Header  |  1993-07-29  |  32KB  |  1,337 lines

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