/[bison]/bison/src/output.c
ViewVC logotype

Diff of /bison/src/output.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.193 by akim, Wed Jul 31 19:52:13 2002 UTC revision 1.194 by akim, Wed Jul 31 21:52:00 2002 UTC
# Line 86  Line 86 
86     negative short int.  Used to flag ??  */     negative short int.  Used to flag ??  */
87    
88  #include "system.h"  #include "system.h"
 #include "bitsetv.h"  
89  #include "quotearg.h"  #include "quotearg.h"
90  #include "error.h"  #include "error.h"
91  #include "getargs.h"  #include "getargs.h"
92  #include "files.h"  #include "files.h"
93  #include "gram.h"  #include "gram.h"
 #include "LR0.h"  
94  #include "complain.h"  #include "complain.h"
95  #include "output.h"  #include "output.h"
 #include "lalr.h"  
96  #include "reader.h"  #include "reader.h"
97  #include "symtab.h"  #include "symtab.h"
98  #include "conflicts.h"  #include "tables.h"
99  #include "muscle_tab.h"  #include "muscle_tab.h"
100    
101  /* From src/scan-skel.l. */  /* From src/scan-skel.l. */
102  void m4_invoke PARAMS ((const char *definitions));  void m4_invoke PARAMS ((const char *definitions));
103    
104    
 /* Several tables will be indexed both by state and nonterminal  
    numbers.  We call `vector' such a thing (= either a state or a  
    symbol number.  
   
    Of course vector_number_t ought to be wide enough to contain  
    state_number_t and symbol_number_t.  */  
 typedef short vector_number_t;  
 #define VECTOR_NUMBER_MAX ((vector_number_t) SHRT_MAX)  
 #define VECTOR_NUMBER_MIN ((vector_number_t) SHRT_MIN)  
 #define state_number_to_vector_number(State) \  
    ((vector_number_t) State)  
 #define symbol_number_to_vector_number(Symbol) \  
    ((vector_number_t) (state_number_as_int (nstates) + Symbol - ntokens))  
   
 static int nvectors;  
   
   
 /* FROMS and TOS are indexed by vector_number_t.  
   
    If VECTOR is a nonterminal, (FROMS[VECTOR], TOS[VECTOR]) form an  
    array of state numbers of the non defaulted GOTO on VECTOR.  
   
    If VECTOR is a state, TOS[VECTOR] is the array of actions to do on  
    the (array of) symbols FROMS[VECTOR].  
   
    In both cases, TALLY[VECTOR] is the size of the arrays  
    FROMS[VECTOR], TOS[VECTOR]; and WIDTH[VECTOR] =  
    (FROMS[VECTOR][SIZE] - FROMS[VECTOR][0] + 1) where SIZE =  
    TALLY[VECTOR].  
   
    FROMS therefore contains symbol_number_t and action_number_t,  
    TOS state_number_t and action_number_t,  
    TALLY sizes,  
    WIDTH differences of FROMS.  
   
    Let base_t be the type of FROMS, TOS, and WIDTH.  */  
 typedef int base_t;  
 #define BASE_MAX ((base_t) INT_MAX)  
 #define BASE_MIN ((base_t) INT_MIN)  
   
 static base_t **froms = NULL;  
 static base_t **tos = NULL;  
 static unsigned int **conflict_tos = NULL;  
 static short *tally = NULL;  
 static base_t *width = NULL;  
   
   
 /* For a given state, N = ACTROW[SYMBOL]:  
   
    If N = 0, stands for `run the default action'.  
    If N = MIN, stands for `raise a parse error'.  
    If N > 0, stands for `shift SYMBOL and go to n'.  
    If N < 0, stands for `reduce -N'.  */  
 typedef short action_t;  
 #define ACTION_MAX ((action_t) SHRT_MAX)  
 #define ACTION_MIN ((action_t) SHRT_MIN)  
   
 static action_t *actrow = NULL;  
   
 /* FROMS and TOS are reordered to be compressed.  ORDER[VECTOR] is the  
    new vector number of VECTOR.  We skip `empty' vectors (i.e.,  
    TALLY[VECTOR] = 0), and call these `entries'.  */  
 static vector_number_t *order = NULL;  
 static int nentries;  
   
 static base_t *base = NULL;  
 /* A distinguished value of BASE, negative infinite.  During the  
    computation equals to BASE_MIN, later mapped to BASE_NINF to  
    keep parser tables small.  */  
 base_t base_ninf = 0;  
 static base_t *pos = NULL;  
   
 static unsigned int *conflrow = NULL;  
 static unsigned int *conflict_table = NULL;  
 static unsigned int *conflict_list = NULL;  
 static int conflict_list_cnt;  
 static int conflict_list_free;  
   
 /* TABLE_SIZE is the allocated size of both TABLE and CHECK.  We start  
    with more or less the original hard-coded value (which was  
    SHRT_MAX).  */  
 static size_t table_size = 32768;  
 static base_t *table = NULL;  
 static base_t *check = NULL;  
 /* The value used in TABLE to denote explicit parse errors  
    (%nonassoc), a negative infinite.  First defaults to ACTION_MIN,  
    but in order to keep small tables, renumbered as TABLE_ERROR, which  
    is the smallest (non error) value minus 1.  */  
 base_t table_ninf = 0;  
 static int lowzero;  
 static int high;  
   
105  static struct obstack format_obstack;  static struct obstack format_obstack;
106    
107  int error_verbose = 0;  int error_verbose = 0;
108    
109    
 /*----------------------------------------------------------------.  
 | If TABLE (and CHECK) appear to be small to be addressed at      |  
 | DESIRED, grow them.  Note that TABLE[DESIRED] is to be used, so |  
 | the desired size is at least DESIRED + 1.                       |  
 `----------------------------------------------------------------*/  
   
 static void  
 table_grow (size_t desired)  
 {  
   size_t old_size = table_size;  
   
   while (table_size <= desired)  
     table_size *= 2;  
   
   if (trace_flag & trace_resource)  
     fprintf (stderr, "growing table and check from: %d to %d\n",  
              old_size, table_size);  
   
   table = XREALLOC (table, base_t, table_size);  
   check = XREALLOC (check, base_t, table_size);  
   if (glr_parser)  
     conflict_table = XREALLOC (conflict_table, unsigned int, table_size);  
   
   for (/* Nothing. */; old_size < table_size; ++old_size)  
     {  
       table[old_size] = 0;  
       check[old_size] = -1;  
     }  
 }  
   
110    
111  /*-------------------------------------------------------------------.  /*-------------------------------------------------------------------.
112  | Create a function NAME which associates to the muscle NAME the     |  | Create a function NAME which associates to the muscle NAME the     |
# Line 430  prepare_states (void) Line 305  prepare_states (void)
305  }  }
306    
307    
 /*-------------------------------------------------------------------.  
 | For GLR parsers, for each conflicted token in STATE, as indicated  |  
 | by non-zero entries in CONFLROW, create a list of possible         |  
 | reductions that are alternatives to the shift or reduction         |  
 | currently recorded for that token in STATE.  Store the alternative |  
 | reductions followed by a 0 in CONFLICT_LIST, updating              |  
 | CONFLICT_LIST_CNT, and storing an index to the start of the list   |  
 | back into CONFLROW.                                                |  
 `-------------------------------------------------------------------*/  
   
 static void  
 conflict_row (state_t *state)  
 {  
   int i, j;  
   
   if (! glr_parser)  
     return;  
   
   for (j = 0; j < ntokens; j += 1)  
     if (conflrow[j])  
       {  
         conflrow[j] = conflict_list_cnt;  
   
         /* Find all reductions for token J, and record all that do not  
            match ACTROW[J].  */  
         for (i = 0; i < state->nlookaheads; i += 1)  
           if (bitset_test (state->lookaheads[i], j)  
               && (actrow[j]  
                   != rule_number_as_item_number (state->lookaheads_rule[i]->number)))  
             {  
               assert (conflict_list_free > 0);  
               conflict_list[conflict_list_cnt]  
                 = state->lookaheads_rule[i]->number + 1;  
               conflict_list_cnt += 1;  
               conflict_list_free -= 1;  
             }  
   
         /* Leave a 0 at the end.  */  
         assert (conflict_list_free > 0);  
         conflict_list_cnt += 1;  
         conflict_list_free -= 1;  
       }  
 }  
   
   
 /*------------------------------------------------------------------.  
 | Decide what to do for each type of token if seen as the lookahead |  
 | token in specified state.  The value returned is used as the      |  
 | default action (yydefact) for the state.  In addition, ACTROW is  |  
 | filled with what to do for each kind of token, index by symbol    |  
 | number, with zero meaning do the default action.  The value       |  
 | ACTION_MIN, a very negative number, means this situation is an    |  
 | error.  The parser recognizes this value specially.               |  
 |                                                                   |  
 | This is where conflicts are resolved.  The loop over lookahead    |  
 | rules considered lower-numbered rules last, and the last rule     |  
 | considered that likes a token gets to handle it.                  |  
 |                                                                   |  
 | For GLR parsers, also sets CONFLROW[SYM] to an index into         |  
 | CONFLICT_LIST iff there is an unresolved conflict (s/r or r/r)    |  
 | with symbol SYM. The default reduction is not used for a symbol   |  
 | that has any such conflicts.                                      |  
 `------------------------------------------------------------------*/  
   
 static rule_t *  
 action_row (state_t *state)  
 {  
   int i;  
   rule_t *default_rule = NULL;  
   reductions_t *redp = state->reductions;  
   transitions_t *transitions = state->transitions;  
   errs_t *errp = state->errs;  
   /* Set to nonzero to inhibit having any default reduction.  */  
   int nodefault = 0;  
   int conflicted = 0;  
   
   for (i = 0; i < ntokens; i++)  
     actrow[i] = conflrow[i] = 0;  
   
   if (redp->num >= 1)  
     {  
       int j;  
       bitset_iterator biter;  
       /* loop over all the rules available here which require  
          lookahead */  
       for (i = state->nlookaheads - 1; i >= 0; --i)  
         /* and find each token which the rule finds acceptable  
            to come next */  
         BITSET_FOR_EACH (biter, state->lookaheads[i], j, 0)  
         {  
           /* and record this rule as the rule to use if that  
              token follows.  */  
           if (actrow[j] != 0)  
             conflicted = conflrow[j] = 1;  
           actrow[j] = rule_number_as_item_number (state->lookaheads_rule[i]->number);  
         }  
     }  
   
   /* Now see which tokens are allowed for shifts in this state.  For  
      them, record the shift as the thing to do.  So shift is preferred  
      to reduce.  */  
   FOR_EACH_SHIFT (transitions, i)  
     {  
       symbol_number_t symbol = TRANSITION_SYMBOL (transitions, i);  
       state_t *shift_state = transitions->states[i];  
   
       if (actrow[symbol] != 0)  
         conflicted = conflrow[symbol] = 1;  
       actrow[symbol] = state_number_as_int (shift_state->number);  
   
       /* Do not use any default reduction if there is a shift for  
          error */  
       if (symbol == errtoken->number)  
         nodefault = 1;  
     }  
   
   /* See which tokens are an explicit error in this state (due to  
      %nonassoc).  For them, record ACTION_MIN as the action.  */  
   for (i = 0; i < errp->num; i++)  
     {  
       symbol_t *symbol = errp->symbols[i];  
       actrow[symbol->number] = ACTION_MIN;  
     }  
   
   /* Now find the most common reduction and make it the default action  
      for this state.  */  
   
   if (redp->num >= 1 && !nodefault)  
     {  
       if (state->consistent)  
         default_rule = redp->rules[0];  
       else  
         {  
           int max = 0;  
           for (i = 0; i < state->nlookaheads; i++)  
             {  
               int count = 0;  
               rule_t *rule = state->lookaheads_rule[i];  
               symbol_number_t j;  
   
               for (j = 0; j < ntokens; j++)  
                 if (actrow[j] == rule_number_as_item_number (rule->number))  
                   count++;  
   
               if (count > max)  
                 {  
                   max = count;  
                   default_rule = rule;  
                 }  
             }  
   
           /* GLR parsers need space for conflict lists, so we can't  
              default conflicted entries.  For non-conflicted entries  
              or as long as we are not building a GLR parser,  
              actions that match the default are replaced with zero,  
              which means "use the default". */  
   
           if (max > 0)  
             {  
               int j;  
               for (j = 0; j < ntokens; j++)  
                 if (actrow[j] == rule_number_as_item_number (default_rule->number)  
                     && ! (glr_parser && conflrow[j]))  
                   actrow[j] = 0;  
             }  
         }  
     }  
   
   /* Find the rules which are reduced.  */  
   if (!glr_parser)  
     {  
       for (i = 0; i < ntokens; i++)  
         if (actrow[i] < 0 && actrow[i] != ACTION_MIN)  
           rules[item_number_as_rule_number (actrow[i])].useful = TRUE;  
       if (default_rule)  
         default_rule->useful = TRUE;  
     }  
   
   /* If have no default rule, the default is an error.  
      So replace any action which says "error" with "use default".  */  
   
   if (!default_rule)  
     for (i = 0; i < ntokens; i++)  
       if (actrow[i] == ACTION_MIN)  
         actrow[i] = 0;  
   
   if (conflicted)  
     conflict_row (state);  
   
   return default_rule;  
 }  
   
   
 /*--------------------------------------------.  
 | Set FROMS, TOS, TALLY and WIDTH for STATE.  |  
 `--------------------------------------------*/  
   
 static void  
 save_row (state_number_t state)  
 {  
   symbol_number_t i;  
   int count;  
   base_t *sp = NULL;  
   base_t *sp1 = NULL;  
   base_t *sp2 = NULL;  
   unsigned int *sp3 = NULL;  
   
   /* Number of non default actions in STATE.  */  
   count = 0;  
   for (i = 0; i < ntokens; i++)  
     if (actrow[i] != 0)  
       count++;  
   
   if (count == 0)  
     return;  
   
   /* Allocate non defaulted actions.  */  
   froms[state] = sp1 = sp = XCALLOC (base_t, count);  
   tos[state] = sp2 = XCALLOC (base_t, count);  
   if (glr_parser)  
     conflict_tos[state] = sp3 = XCALLOC (unsigned int, count);  
   else  
     conflict_tos[state] = NULL;  
   
   /* Store non defaulted actions.  */  
   for (i = 0; i < ntokens; i++)  
     if (actrow[i] != 0)  
       {  
         *sp1++ = i;  
         *sp2++ = actrow[i];  
         if (glr_parser)  
           *sp3++ = conflrow[i];  
       }  
   
   tally[state] = count;  
   width[state] = sp1[-1] - sp[0] + 1;  
 }  
   
308    
309  /*------------------------------------------------------------------.  /*----------------------------------.
310  | Figure out the actions for the specified state, indexed by        |  | Output the user actions to OOUT.  |
311  | lookahead token type.                                             |  `----------------------------------*/
 |                                                                   |  
 | The YYDEFACT table is output now.  The detailed info is saved for |  
 | putting into YYTABLE later.                                       |  
 `------------------------------------------------------------------*/  
312    
313  static void  static void
314  token_actions (void)  user_actions_output (FILE *out)
 {  
   state_number_t i;  
   rule_number_t r;  
   int nconflict = conflicts_total_count ();  
   
   rule_number_t *yydefact = XCALLOC (rule_number_t, nstates);  
   
   actrow = XCALLOC (action_t, ntokens);  
   conflrow = XCALLOC (unsigned int, ntokens);  
   
   /* Now that the parser was computed, we can find which rules are  
      really reduced, and which are not because of SR or RR conflicts.  
      */  
   if (!glr_parser)  
     for (r = 0; r < nrules; ++r)  
       rules[r].useful = FALSE;  
   
   if (glr_parser)  
     {  
       conflict_list = XCALLOC (unsigned int, 1 + 2 * nconflict);  
       conflict_list_free = 2 * nconflict;  
       conflict_list_cnt = 1;  
     }  
   else  
     conflict_list_free = conflict_list_cnt = 0;  
   
   for (i = 0; i < nstates; ++i)  
     {  
       rule_t *default_rule = action_row (states[i]);  
       yydefact[i] = default_rule ? default_rule->number + 1 : 0;  
       save_row (i);  
     }  
   
   muscle_insert_rule_number_table ("defact", yydefact,  
                                    yydefact[0], 1, nstates);  
   
   if (!glr_parser)  
     for (r = 0; r < nrules ; ++r)  
       if (!rules[r].useful)  
         {  
           LOCATION_PRINT (stderr, rules[r].location);  
           fprintf (stderr, ": %s: %s: ",  
                    _("warning"), _("rule never reduced because of conflicts"));  
           rule_print (&rules[r], stderr);  
         }  
   
   XFREE (actrow);  
   XFREE (conflrow);  
   XFREE (yydefact);  
 }  
   
   
 /*-----------------------------.  
 | Output the actions to OOUT.  |  
 `-----------------------------*/  
   
 void  
 actions_output (FILE *out)  
315  {  {
316    rule_number_t r;    rule_number_t r;
317    
# Line 784  merger_output (FILE *out) Line 359  merger_output (FILE *out)
359  | Output the tokens definition to OOUT.  |  | Output the tokens definition to OOUT.  |
360  `---------------------------------------*/  `---------------------------------------*/
361    
362  void  static void
363  token_definitions_output (FILE *out)  token_definitions_output (FILE *out)
364  {  {
365    int i;    int i;
# Line 896  symbol_printers_output (FILE *out) Line 471  symbol_printers_output (FILE *out)
471  }  }
472    
473    
 /*------------------------------------------------------------------.  
 | Compute FROMS[VECTOR], TOS[VECTOR], TALLY[VECTOR], WIDTH[VECTOR], |  
 | i.e., the information related to non defaulted GOTO on the nterm  |  
 | SYMBOL.                                                           |  
 |                                                                   |  
 | DEFAULT_STATE is the principal destination on SYMBOL, i.e., the   |  
 | default GOTO destination on SYMBOL.                               |  
 `------------------------------------------------------------------*/  
   
 static void  
 save_column (symbol_number_t symbol, state_number_t default_state)  
 {  
   int i;  
   base_t *sp;  
   base_t *sp1;  
   base_t *sp2;  
   int count;  
   vector_number_t symno = symbol_number_to_vector_number (symbol);  
   
   goto_number_t begin = goto_map[symbol];  
   goto_number_t end = goto_map[symbol + 1];  
   
   /* Number of non default GOTO.  */  
   count = 0;  
   for (i = begin; i < end; i++)  
     if (to_state[i] != default_state)  
       count++;  
   
   if (count == 0)  
     return;  
   
   /* Allocate room for non defaulted gotos.  */  
   froms[symno] = sp1 = sp = XCALLOC (base_t, count);  
   tos[symno] = sp2 = XCALLOC (base_t, count);  
   
   /* Store the state numbers of the non defaulted gotos.  */  
   for (i = begin; i < end; i++)  
     if (to_state[i] != default_state)  
       {  
         *sp1++ = from_state[i];  
         *sp2++ = to_state[i];  
       }  
   
   tally[symno] = count;  
   width[symno] = sp1[-1] - sp[0] + 1;  
 }  
   
   
 /*----------------------------------------------------------------.  
 | Return `the' most common destination GOTO on SYMBOL (a nterm).  |  
 `----------------------------------------------------------------*/  
   
 static state_number_t  
 default_goto (symbol_number_t symbol, short state_count[])  
 {  
   state_number_t s;  
   int i;  
   goto_number_t m = goto_map[symbol];  
   goto_number_t n = goto_map[symbol + 1];  
   state_number_t default_state = (state_number_t) -1;  
   int max = 0;  
   
   if (m == n)  
     return (state_number_t) -1;  
   
   for (s = 0; s < nstates; s++)  
     state_count[s] = 0;  
   
   for (i = m; i < n; i++)  
     state_count[to_state[i]]++;  
   
   for (s = 0; s < nstates; s++)  
     if (state_count[s] > max)  
       {  
         max = state_count[s];  
         default_state = s;  
       }  
   
   return default_state;  
 }  
   
   
 /*-------------------------------------------------------------------.  
 | Figure out what to do after reducing with each rule, depending on  |  
 | the saved state from before the beginning of parsing the data that |  
 | matched this rule.                                                 |  
 |                                                                    |  
 | The YYDEFGOTO table is output now.  The detailed info is saved for |  
 | putting into YYTABLE later.                                        |  
 `-------------------------------------------------------------------*/  
   
474  static void  static void
475  goto_actions (void)  prepare_actions (void)
476  {  {
477    symbol_number_t i;    /* Figure out the actions for the specified state, indexed by
478    state_number_t *yydefgoto = XMALLOC (state_number_t, nvars);       lookahead token type.  */
479    
480    /* For a given nterm I, STATE_COUNT[S] is the number of times there    muscle_insert_rule_number_table ("defact", yydefact,
481       is a GOTO to S on I.  */                                     yydefact[0], 1, nstates);
   short *state_count = XCALLOC (short, nstates);  
   for (i = ntokens; i < nsyms; ++i)  
     {  
       state_number_t default_state = default_goto (i, state_count);  
       save_column (i, default_state);  
       yydefgoto[i - ntokens] = default_state;  
     }  
482    
483      /* Figure out what to do after reducing with each rule, depending on
484         the saved state from before the beginning of parsing the data
485         that matched this rule.  */
486    muscle_insert_state_number_table ("defgoto", yydefgoto,    muscle_insert_state_number_table ("defgoto", yydefgoto,
487                                      yydefgoto[0], 1, nsyms - ntokens);                                      yydefgoto[0], 1, nsyms - ntokens);
   XFREE (state_count);  
   XFREE (yydefgoto);  
 }  
   
   
 /*------------------------------------------------------------------.  
 | Compute ORDER, a reordering of vectors, in order to decide how to |  
 | pack the actions and gotos information into yytable.              |  
 `------------------------------------------------------------------*/  
   
 static void  
 sort_actions (void)  
 {  
   int i;  
   
   nentries = 0;  
   
   for (i = 0; i < nvectors; i++)  
     if (tally[i] > 0)  
       {  
         int k;  
         int t = tally[i];  
         int w = width[i];  
         int j = nentries - 1;  
   
         while (j >= 0 && (width[order[j]] < w))  
           j--;  
   
         while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))  
           j--;  
   
         for (k = nentries - 1; k > j; k--)  
           order[k + 1] = order[k];  
   
         order[j + 1] = i;  
         nentries++;  
       }  
 }  
   
   
 /* If VECTOR is a state which actions (reflected by FROMS, TOS, TALLY  
    and WIDTH of VECTOR) are common to a previous state, return this  
    state number.  
   
    In any other case, return -1.  */  
   
 static state_number_t  
 matching_state (vector_number_t vector)  
 {  
   vector_number_t i = order[vector];  
   int t;  
   int w;  
   int prev;  
   
   /* If VECTOR is a nterm, return -1.  */  
   if (i >= (int) nstates)  
     return -1;  
   
   t = tally[i];  
   w = width[i];  
   
   for (prev = vector - 1; prev >= 0; prev--)  
     {  
       vector_number_t j = order[prev];  
       int k;  
       int match = 1;  
   
       /* Given how ORDER was computed, if the WIDTH or TALLY is  
          different, there cannot be a matching state.  */  
       if (width[j] != w || tally[j] != t)  
         return -1;  
   
       for (k = 0; match && k < t; k++)  
         if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])  
           match = 0;  
   
       if (match)  
         return j;  
     }  
   
   return -1;  
 }  
   
   
 static base_t  
 pack_vector (vector_number_t vector)  
 {  
   vector_number_t i = order[vector];  
   int j;  
   int t = tally[i];  
   int loc = 0;  
   base_t *from = froms[i];  
   base_t *to = tos[i];  
   unsigned int *conflict_to = conflict_tos[i];  
   
   assert (t);  
   
   for (j = lowzero - from[0]; j < (int) table_size; j++)  
     {  
       int k;  
       int ok = 1;  
   
       for (k = 0; ok && k < t; k++)  
         {  
           loc = j + state_number_as_int (from[k]);  
           if (loc > (int) table_size)  
             table_grow (loc);  
   
           if (table[loc] != 0)  
             ok = 0;  
         }  
   
       for (k = 0; ok && k < vector; k++)  
         if (pos[k] == j)  
           ok = 0;  
   
       if (ok)  
         {  
           for (k = 0; k < t; k++)  
             {  
               loc = j + from[k];  
               table[loc] = to[k];  
               if (glr_parser && conflict_to != NULL)  
                 conflict_table[loc] = conflict_to[k];  
               check[loc] = from[k];  
             }  
   
           while (table[lowzero] != 0)  
             lowzero++;  
   
           if (loc > high)  
             high = loc;  
   
           if (j < BASE_MIN || BASE_MAX < j)  
             fatal ("base_t too small to hold %d\n", j);  
           return j;  
         }  
     }  
 #define pack_vector_succeeded 0  
   assert (pack_vector_succeeded);  
   return 0;  
 }  
   
   
 /*-------------------------------------------------------------.  
 | Remap the negative infinite in TAB from NINF to the greatest |  
 | possible smallest value.  Return it.                         |  
 |                                                              |  
 | In most case this allows us to use shorts instead of ints in |  
 | parsers.                                                     |  
 `-------------------------------------------------------------*/  
   
 static base_t  
 table_ninf_remap (base_t tab[], size_t size, base_t ninf)  
 {  
   base_t res = 0;  
   size_t i;  
   
   for (i = 0; i < size; i++)  
     if (tab[i] < res && tab[i] != ninf)  
       res = base[i];  
   
   --res;  
488    
   for (i = 0; i < size; i++)  
     if (tab[i] == ninf)  
       tab[i] = res;  
489    
   return res;  
 }  
   
 static void  
 pack_table (void)  
 {  
   int i;  
   
   base = XCALLOC (base_t, nvectors);  
   pos = XCALLOC (base_t, nentries);  
   table = XCALLOC (base_t, table_size);  
   if (glr_parser)  
     conflict_table = XCALLOC (unsigned int, table_size);  
   check = XCALLOC (base_t, table_size);  
   
   lowzero = 0;  
   high = 0;  
   
   for (i = 0; i < nvectors; i++)  
     base[i] = BASE_MIN;  
   
   for (i = 0; i < (int) table_size; i++)  
     check[i] = -1;  
   
   for (i = 0; i < nentries; i++)  
     {  
       state_number_t state = matching_state (i);  
       base_t place;  
   
       if (state < 0)  
         /* A new set of state actions, or a nonterminal.  */  
         place = pack_vector (i);  
       else  
         /* Action of I were already coded for STATE.  */  
         place = base[state];  
   
       pos[i] = place;  
       base[order[i]] = place;  
     }  
   
   /* Use the greatest possible negative infinites.  */  
   base_ninf = table_ninf_remap (base, nvectors, BASE_MIN);  
   table_ninf = table_ninf_remap (table, high + 1, ACTION_MIN);  
   
   for (i = 0; i < nvectors; i++)  
     {  
       XFREE (froms[i]);  
       XFREE (tos[i]);  
       XFREE (conflict_tos[i]);  
     }  
   
   free (froms);  
   free (tos);  
   free (conflict_tos);  
   free (pos);  
 }  
   
   
 /* the following functions output yytable, yycheck, yyconflp, yyconfl,  
    and the vectors whose elements index the portion starts.  */  
   
 static void  
 output_base (void)  
 {  
490    /* Output PACT. */    /* Output PACT. */
491    muscle_insert_base_table ("pact", base,    muscle_insert_base_table ("pact", base,
492                               base[0], 1, nstates);                               base[0], 1, nstates);
# Line 1245  output_base (void) Line 495  output_base (void)
495    /* Output PGOTO. */    /* Output PGOTO. */
496    muscle_insert_base_table ("pgoto", base,    muscle_insert_base_table ("pgoto", base,
497                               base[nstates], nstates + 1, nvectors);                               base[nstates], nstates + 1, nvectors);
   XFREE (base);  
 }  
498    
   
 static void  
 output_table (void)  
 {  
499    muscle_insert_base_table ("table", table,    muscle_insert_base_table ("table", table,
500                              table[0], 1, high + 1);                              table[0], 1, high + 1);
501    MUSCLE_INSERT_INT ("table_ninf", table_ninf);    MUSCLE_INSERT_INT ("table_ninf", table_ninf);
   XFREE (table);  
 }  
   
   
 static void  
 output_conflicts (void)  
 {  
   /* GLR parsing slightly modifies yytable and yycheck  
      (and thus yypact) so that in states with unresolved conflicts,  
      the default reduction is not used in the conflicted entries, so  
      that there is a place to put a conflict pointer.  This means that  
      yyconflp and yyconfl are nonsense for a non-GLR parser, so we  
      avoid accidents by not writing them out in that case. */  
   if (! glr_parser)  
     return;  
   
   muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,  
                                     conflict_table[0], 1, high+1);  
   muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,  
                              conflict_list[0], 1, conflict_list_cnt);  
   
   XFREE (conflict_table);  
   XFREE (conflict_list);  
 }  
502    
   
 static void  
 output_check (void)  
 {  
503    muscle_insert_base_table ("check", check,    muscle_insert_base_table ("check", check,
504                              check[0], 1, high + 1);                              check[0], 1, high + 1);
   XFREE (check);  
 }  
   
505    
506  /*-----------------------------------------------------------------.    if (glr_parser)
507  | Compute and output yydefact, yydefgoto, yypact, yypgoto, yytable |      {
508  | and yycheck.                                                     |        /* GLR parsing slightly modifies yytable and yycheck
509  `-----------------------------------------------------------------*/           (and thus yypact) so that in states with unresolved conflicts,
510             the default reduction is not used in the conflicted entries, so
511  static void           that there is a place to put a conflict pointer.  This means that
512  prepare_actions (void)           yyconflp and yyconfl are nonsense for a non-GLR parser, so we
513  {           avoid accidents by not writing them out in that case. */
514    /* That's a poor way to make sure the sizes are properly corelated,        muscle_insert_unsigned_int_table ("conflict_list_heads", conflict_table,
515       in particular the signedness is not taking into account, but it's                                          conflict_table[0], 1, high+1);
516       not useless.  */        muscle_insert_unsigned_int_table ("conflicting_rules", conflict_list,
517    assert (sizeof (nvectors) >= sizeof (nstates));                               conflict_list[0], 1, conflict_list_cnt);
518    assert (sizeof (nvectors) >= sizeof (nvars));      }
   
   nvectors = state_number_as_int (nstates) + nvars;  
   
   froms = XCALLOC (base_t *, nvectors);  
   tos = XCALLOC (base_t *, nvectors);  
   conflict_tos = XCALLOC (unsigned int *, nvectors);  
   tally = XCALLOC (short, nvectors);  
   width = XCALLOC (base_t, nvectors);  
   
   token_actions ();  
   bitsetv_free (LA);  
   free (LArule);  
   
   goto_actions ();  
   XFREE (goto_map + ntokens);  
   XFREE (from_state);  
   XFREE (to_state);  
   
   order = XCALLOC (vector_number_t, nvectors);  
   sort_actions ();  
   pack_table ();  
   free (order);  
   
   free (tally);  
   free (width);  
   
   output_base ();  
   output_table ();  
   output_conflicts ();  
   
   output_check ();  
519  }  }
520    
521    
# Line 1367  output_skeleton (void) Line 549  output_skeleton (void)
549    fputs ("m4_changecom()\n", out);    fputs ("m4_changecom()\n", out);
550    fputs ("m4_init()\n", out);    fputs ("m4_init()\n", out);
551    
552    actions_output (out);    user_actions_output (out);
553    merger_output (out);    merger_output (out);
554    token_definitions_output (out);    token_definitions_output (out);
555    symbol_destructors_output (out);    symbol_destructors_output (out);
# Line 1454  output (void) Line 636  output (void)
636    prepare_tokens ();    prepare_tokens ();
637    prepare_rules ();    prepare_rules ();
638    prepare_states ();    prepare_states ();
   timevar_push (TV_ACTIONS);  
639    prepare_actions ();    prepare_actions ();
   timevar_pop (TV_ACTIONS);  
640    
641    prepare ();    prepare ();
642    

Legend:
Removed from v.1.193  
changed lines
  Added in v.1.194

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26