home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / gnu / flex-2.4.6-src.lha / src / amiga / flex-2.4.6 / gen.c < prev    next >
C/C++ Source or Header  |  1994-01-04  |  33KB  |  1,454 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. /* $Header: gen.c,v 1.2 94/01/04 14:33:12 vern Exp $ */
  30.  
  31. #include "flexdef.h"
  32.  
  33.  
  34. /* declare functions that have forward references */
  35.  
  36. void gen_next_state PROTO((int));
  37. void genecs PROTO((void));
  38. void indent_put2s PROTO((char [], char []));
  39. void indent_puts PROTO((char []));
  40.  
  41.  
  42. static int indent_level = 0; /* each level is 8 spaces */
  43.  
  44. #define indent_up() (++indent_level)
  45. #define indent_down() (--indent_level)
  46. #define set_indent(indent_val) indent_level = indent_val
  47.  
  48. /* Almost everything is done in terms of arrays starting at 1, so provide
  49.  * a null entry for the zero element of all C arrays.  (The exception
  50.  * to this is that the fast table representation generally uses the
  51.  * 0 elements of its arrays, too.)
  52.  */
  53. static char C_int_decl[] = "static const int %s[%d] =\n    {   0,\n";
  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.     register int i = indent_level * 8;
  65.  
  66.     while ( i >= 8 )
  67.         {
  68.         putchar( '\t' );
  69.         i -= 8;
  70.         }
  71.  
  72.     while ( i > 0 )
  73.         {
  74.         putchar( ' ' );
  75.         --i;
  76.         }
  77.     }
  78.  
  79.  
  80. /* Generate the code to keep backing-up information. */
  81.  
  82. void gen_backing_up()
  83.     {
  84.     if ( reject || num_backing_up == 0 )
  85.         return;
  86.  
  87.     if ( fullspd )
  88.         indent_puts( "if ( yy_current_state[-1].yy_nxt )" );
  89.     else
  90.         indent_puts( "if ( yy_accept[yy_current_state] )" );
  91.  
  92.     indent_up();
  93.     indent_puts( "{" );
  94.     indent_puts( "yy_last_accepting_state = yy_current_state;" );
  95.     indent_puts( "yy_last_accepting_cpos = yy_cp;" );
  96.     indent_puts( "}" );
  97.     indent_down();
  98.     }
  99.  
  100.  
  101. /* Generate the code to perform the backing up. */
  102.  
  103. void gen_bu_action()
  104.     {
  105.     if ( reject || num_backing_up == 0 )
  106.         return;
  107.  
  108.     set_indent( 3 );
  109.  
  110.     indent_puts( "case 0: /* must back up */" );
  111.     indent_puts( "/* undo the effects of YY_DO_BEFORE_ACTION */" );
  112.     indent_puts( "*yy_cp = yy_hold_char;" );
  113.  
  114.     if ( fullspd || fulltbl )
  115.         indent_puts( "yy_cp = yy_last_accepting_cpos + 1;" );
  116.     else
  117.         /* Backing-up info for compressed tables is taken \after/
  118.          * yy_cp has been incremented for the next state.
  119.          */
  120.         indent_puts( "yy_cp = yy_last_accepting_cpos;" );
  121.  
  122.     indent_puts( "yy_current_state = yy_last_accepting_state;" );
  123.     indent_puts( "goto yy_find_action;" );
  124.     putchar( '\n' );
  125.  
  126.     set_indent( 0 );
  127.     }
  128.  
  129.  
  130. /* genctbl - generates full speed compressed transition table */
  131.  
  132. void genctbl()
  133.     {
  134.     register int i;
  135.     int end_of_buffer_action = num_rules + 1;
  136.  
  137.     /* Table of verify for transition and offset to next state. */
  138.     printf( "static const struct yy_trans_info yy_transition[%d] =\n",
  139.         tblend + numecs + 1 );
  140.     printf( "    {\n" );
  141.  
  142.     /* We want the transition to be represented as the offset to the
  143.      * next state, not the actual state number, which is what it currently
  144.      * is.  The offset is base[nxt[i]] - (base of current state)].  That's
  145.      * just the difference between the starting points of the two involved
  146.      * states (to - from).
  147.      *
  148.      * First, though, we need to find some way to put in our end-of-buffer
  149.      * flags and states.  We do this by making a state with absolutely no
  150.      * transitions.  We put it at the end of the table.
  151.      */
  152.  
  153.     /* We need to have room in nxt/chk for two more slots: One for the
  154.      * action and one for the end-of-buffer transition.  We now *assume*
  155.      * that we're guaranteed the only character we'll try to index this
  156.      * nxt/chk pair with is EOB, i.e., 0, so we don't have to make sure
  157.      * there's room for jam entries for other characters.
  158.      */
  159.  
  160.     while ( tblend + 2 >= current_max_xpairs )
  161.         expand_nxt_chk();
  162.  
  163.     while ( lastdfa + 1 >= current_max_dfas )
  164.         increase_max_dfas();
  165.  
  166.     base[lastdfa + 1] = tblend + 2;
  167.     nxt[tblend + 1] = end_of_buffer_action;
  168.     chk[tblend + 1] = numecs + 1;
  169.     chk[tblend + 2] = 1; /* anything but EOB */
  170.  
  171.     /* So that "make test" won't show arb. differences. */
  172.     nxt[tblend + 2] = 0;
  173.  
  174.     /* Make sure every state has an end-of-buffer transition and an
  175.      * action #.
  176.      */
  177.     for ( i = 0; i <= lastdfa; ++i )
  178.         {
  179.         int anum = dfaacc[i].dfaacc_state;
  180.         int offset = base[i];
  181.  
  182.         chk[offset] = EOB_POSITION;
  183.         chk[offset - 1] = ACTION_POSITION;
  184.         nxt[offset - 1] = anum;    /* action number */
  185.         }
  186.  
  187.     for ( i = 0; i <= tblend; ++i )
  188.         {
  189.         if ( chk[i] == EOB_POSITION )
  190.             transition_struct_out( 0, base[lastdfa + 1] - i );
  191.  
  192.         else if ( chk[i] == ACTION_POSITION )
  193.             transition_struct_out( 0, nxt[i] );
  194.  
  195.         else if ( chk[i] > numecs || chk[i] == 0 )
  196.             transition_struct_out( 0, 0 );    /* unused slot */
  197.  
  198.         else    /* verify, transition */
  199.             transition_struct_out( chk[i],
  200.                         base[nxt[i]] - (i - chk[i]) );
  201.         }
  202.  
  203.  
  204.     /* Here's the final, end-of-buffer state. */
  205.     transition_struct_out( chk[tblend + 1], nxt[tblend + 1] );
  206.     transition_struct_out( chk[tblend + 2], nxt[tblend + 2] );
  207.  
  208.     printf( "    };\n" );
  209.     printf( "\n" );
  210.  
  211.     /* Table of pointers to start states. */
  212.     printf(
  213.     "static const struct yy_trans_info *yy_start_state_list[%d] =\n",
  214.         lastsc * 2 + 1 );
  215.     printf( "    {\n" );    /* } so vi doesn't get confused */
  216.  
  217.     for ( i = 0; i <= lastsc * 2; ++i )
  218.         printf( "    &yy_transition[%d],\n", base[i] );
  219.  
  220.     dataend();
  221.  
  222.     if ( useecs )
  223.         genecs();
  224.     }
  225.  
  226.  
  227. /* Generate equivalence-class tables. */
  228.  
  229. void genecs()
  230.     {
  231.     Char clower();
  232.     register int i, j;
  233.     int numrows;
  234.  
  235.     printf( C_int_decl, "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.         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",
  259.                     readable_form( i ), ecgroup[i] );
  260.  
  261.                 putc( ' ', stderr );
  262.                 }
  263.  
  264.             putc( '\n', stderr );
  265.             }
  266.         }
  267.     }
  268.  
  269.  
  270. /* Generate the code to find the action number. */
  271.  
  272. void gen_find_action()
  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(
  286.         "find_rule: /* we branch to this label when backing up */" );
  287.  
  288.         indent_puts(
  289.         "for ( ; ; ) /* until we find what rule we matched */" );
  290.  
  291.         indent_up();
  292.  
  293.         indent_puts( "{" );
  294.  
  295.         indent_puts(
  296.         "if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )" );
  297.         indent_up();
  298.         indent_puts( "{" );
  299.         indent_puts( "yy_act = yy_acclist[yy_lp];" );
  300.  
  301.         if ( variable_trailing_context_rules )
  302.             {
  303.             indent_puts( "if ( yy_act & YY_TRAILING_HEAD_MASK ||" );
  304.             indent_puts( "     yy_looking_for_trail_begin )" );
  305.             indent_up();
  306.             indent_puts( "{" );
  307.  
  308.             indent_puts(
  309.                 "if ( yy_act == yy_looking_for_trail_begin )" );
  310.             in