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

Diff of /bison/src/reduce.c

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

revision 1.41 by akim, Sat Dec 29 14:21:06 2001 UTC revision 1.42 by akim, Mon Mar 4 12:01:44 2002 UTC
# Line 34  Line 34 
34  #include "reduce.h"  #include "reduce.h"
35  #include "reader.h"  #include "reader.h"
36  #include "getargs.h"  #include "getargs.h"
37    #include "bitset.h"
38    
 typedef unsigned *BSet;  
39  typedef short *rule;  typedef short *rule;
40    
41    
42  /* Set of all nonterminals which are not useless.  */  /* Set of all nonterminals which are not useless.  */
43  static BSet N;  static bitset N;
44    
45  /* Set of all rules which have no useless nonterminals in their RHS.  */  /* Set of all rules which have no useless nonterminals in their RHS.  */
46  static BSet P;  static bitset P;
47    
48  /* Set of all accessible symbols.  */  /* Set of all accessible symbols.  */
49  static BSet V;  static bitset V;
50    
51  /* Set of symbols used to define rule precedence (so they are  /* Set of symbols used to define rule precedence (so they are
52     `useless', but no warning should be issued).  */     `useless', but no warning should be issued).  */
53  static BSet V1;  static bitset V1;
54    
55  static int nuseful_productions;  static int nuseful_productions;
56  static int nuseless_productions;  static int nuseless_productions;
57  static int nuseful_nonterminals;  static int nuseful_nonterminals;
58  int nuseless_nonterminals;  int nuseless_nonterminals;
59    
 static bool  
 bits_equal (BSet L, BSet R, int n)  
 {  
   int i;  
   
   for (i = n - 1; i >= 0; i--)  
     if (L[i] != R[i])  
       return FALSE;  
   return TRUE;  
 }  
   
   
 static int  
 nbits (unsigned i)  
 {  
   int count = 0;  
   
   while (i != 0)  
     {  
       i ^= (i & ((unsigned) (-(int) i)));  
       ++count;  
     }  
   return count;  
 }  
   
   
60  static int  static int
61  bits_size (BSet S, int n)  bits_size (bitset S)
62  {  {
63    int i, count = 0;    int i, count = 0;
64    
65    for (i = n - 1; i >= 0; i--)    BITSET_EXECUTE (S, 0, i, { ++count; });
     count += nbits (S[i]);  
66    return count;    return count;
67  }  }
68    
# Line 100  bits_size (BSet S, int n) Line 73  bits_size (BSet S, int n)
73  `-------------------------------------------------------------------*/  `-------------------------------------------------------------------*/
74    
75  static bool  static bool
76  useful_production (int i, BSet N0)  useful_production (int i, bitset N0)
77  {  {
78    rule r;    rule r;
79    short n;    short n;
# Line 110  useful_production (int i, BSet N0) Line 83  useful_production (int i, BSet N0)
83    
84    for (r = &ritem[rules[i].rhs]; *r >= 0; r++)    for (r = &ritem[rules[i].rhs]; *r >= 0; r++)
85      if (ISVAR (n = *r))      if (ISVAR (n = *r))
86        if (!BITISSET (N0, n - ntokens))        if (!bitset_test (N0, n - ntokens))
87          return FALSE;          return FALSE;
88    return TRUE;    return TRUE;
89  }  }
# Line 123  useful_production (int i, BSet N0) Line 96  useful_production (int i, BSet N0)
96  static void  static void
97  useless_nonterminals (void)  useless_nonterminals (void)
98  {  {
99    BSet Np, Ns;    bitset Np, Ns;
100    int i;    int i;
101    
102    /* N is set as built.  Np is set being built this iteration. P is    /* N is set as built.  Np is set being built this iteration. P is
103       set of all productions which have a RHS all in N.  */       set of all productions which have a RHS all in N.  */
104    
105    Np = XCALLOC (unsigned, WORDSIZE (nvars));    Np = bitset_create (nvars, BITSET_FIXED);
106      bitset_zero (Np);
107    
108    
109    /* The set being computed is a set of nonterminals which can derive    /* The set being computed is a set of nonterminals which can derive
110       the empty string or strings consisting of all terminals. At each       the empty string or strings consisting of all terminals. At each
# Line 149  useless_nonterminals (void) Line 124  useless_nonterminals (void)
124    
125    while (1)    while (1)
126      {      {
127        for (i = WORDSIZE (nvars) - 1; i >= 0; i--)        bitset_copy (Np, N);
         Np[i] = N[i];  
128        for (i = 1; i <= nrules; i++)        for (i = 1; i <= nrules; i++)
129          {          {
130            if (!BITISSET (P, i))            if (!bitset_test (P, i))
131              {              {
132                if (useful_production (i, N))                if (useful_production (i, N))
133                  {                  {
134                    SETBIT (Np, rules[i].lhs - ntokens);                    bitset_set (Np, rules[i].lhs - ntokens);
135                    SETBIT (P, i);                    bitset_set (P, i);
136                  }                  }
137              }              }
138          }          }
139        if (bits_equal (N, Np, WORDSIZE (nvars)))        if (bitset_equal_p (N, Np))
140          break;          break;
141        Ns = Np;        Ns = Np;
142        Np = N;        Np = N;
143        N = Ns;        N = Ns;
144      }      }
145    XFREE (N);    bitset_free (N);
146    N = Np;    N = Np;
147  }  }
148    
# Line 176  useless_nonterminals (void) Line 150  useless_nonterminals (void)
150  static void  static void
151  inaccessable_symbols (void)  inaccessable_symbols (void)
152  {  {
153    BSet Vp, Vs, Pp;    bitset Vp, Vs, Pp;
154    int i;    int i;
155    short t;    short t;
156    rule r;    rule r;
# Line 204  inaccessable_symbols (void) Line 178  inaccessable_symbols (void)
178       terminals are printed (if running in verbose mode) so that the       terminals are printed (if running in verbose mode) so that the
179       user can know.  */       user can know.  */
180    
181    Vp = XCALLOC (unsigned, WORDSIZE (nsyms));    Vp = bitset_create (nsyms, BITSET_FIXED);
182    Pp = XCALLOC (unsigned, WORDSIZE (nrules + 1));    bitset_zero (Vp);
183      Pp = bitset_create (nrules + 1, BITSET_FIXED);
184      bitset_zero (Pp);
185    
186    /* If the start symbol isn't useful, then nothing will be useful. */    /* If the start symbol isn't useful, then nothing will be useful. */
187    if (BITISSET (N, start_symbol - ntokens))    if (bitset_test (N, start_symbol - ntokens))
188      {      {
189        SETBIT (V, start_symbol);        bitset_set (V, start_symbol);
190    
191        while (1)        while (1)
192          {          {
193            for (i = WORDSIZE (nsyms) - 1; i >= 0; i--)            bitset_copy (Vp, V);
             Vp[i] = V[i];  
194            for (i = 1; i <= nrules; i++)            for (i = 1; i <= nrules; i++)
195              {              {
196                if (!BITISSET (Pp, i)                if (!bitset_test (Pp, i)
197                    && BITISSET (P, i)                    && bitset_test (P, i)
198                    && BITISSET (V, rules[i].lhs))                    && bitset_test (V, rules[i].lhs))
199                  {                  {
200                    for (r = &ritem[rules[i].rhs]; *r >= 0; r++)                    for (r = &ritem[rules[i].rhs]; *r >= 0; r++)
201                      if (ISTOKEN (t = *r) || BITISSET (N, t - ntokens))                      if (ISTOKEN (t = *r) || bitset_test (N, t - ntokens))
202                        SETBIT (Vp, t);                        bitset_set (Vp, t);
203                    SETBIT (Pp, i);                    bitset_set (Pp, i);
204                  }                  }
205              }              }
206            if (bits_equal (V, Vp, WORDSIZE (nsyms)))            if (bitset_equal_p (V, Vp))
207              break;              break;
208            Vs = Vp;            Vs = Vp;
209            Vp = V;            Vp = V;
# Line 236  inaccessable_symbols (void) Line 211  inaccessable_symbols (void)
211          }          }
212      }      }
213    
214    XFREE (V);    bitset_free (V);
215    V = Vp;    V = Vp;
216    
217    /* Tokens 0, 1, and 2 are internal to Bison.  Consider them useful. */    /* Tokens 0, 1, and 2 are internal to Bison.  Consider them useful. */
218    SETBIT (V, 0);                /* end-of-input token */    bitset_set (V, 0);            /* end-of-input token */
219    SETBIT (V, 1);                /* error token */    bitset_set (V, 1);            /* error token */
220    SETBIT (V, 2);                /* some undefined token */    bitset_set (V, 2);            /* some undefined token */
221    
222    XFREE (P);    bitset_free (P);
223    P = Pp;    P = Pp;
224    
225    nuseful_productions = bits_size (P, WORDSIZE (nrules + 1));    nuseful_productions = bits_size (P);
226    nuseless_productions = nrules - nuseful_productions;    nuseless_productions = nrules - nuseful_productions;
227    
228    nuseful_nonterminals = 0;    nuseful_nonterminals = 0;
229    for (i = ntokens; i < nsyms; i++)    for (i = ntokens; i < nsyms; i++)
230      if (BITISSET (V, i))      if (bitset_test (V, i))
231        nuseful_nonterminals++;        nuseful_nonterminals++;
232    nuseless_nonterminals = nvars - nuseful_nonterminals;    nuseless_nonterminals = nvars - nuseful_nonterminals;
233    
234    /* A token that was used in %prec should not be warned about.  */    /* A token that was used in %prec should not be warned about.  */
235    for (i = 1; i < nrules; i++)    for (i = 1; i < nrules; i++)
236      if (rules[i].precsym != 0)      if (rules[i].precsym != 0)
237        SETBIT (V1, rules[i].precsym);        bitset_set (V1, rules[i].precsym);
238  }  }
239    
240  static void  static void
# Line 284  reduce_grammar_tables (void) Line 259  reduce_grammar_tables (void)
259          np = 0;          np = 0;
260          ni = 0;          ni = 0;
261          for (pn = 1; pn <= nrules; pn++)          for (pn = 1; pn <= nrules; pn++)
262            if (BITISSET (P, pn))            if (bitset_test (P, pn))
263              {              {
264                np++;                np++;
265                if (pn != np)                if (pn != np)
# Line 324  reduce_grammar_tables (void) Line 299  reduce_grammar_tables (void)
299      {      {
300        int pn;        int pn;
301        for (pn = 1; pn <= nrules; pn++)        for (pn = 1; pn <= nrules; pn++)
302          rules[pn].useful = BITISSET (P, pn);          rules[pn].useful = bitset_test (P, pn);
303      }      }
304  }  }
305    
# Line 344  nonterminals_reduce (void) Line 319  nonterminals_reduce (void)
319    short *nontermmap = XCALLOC (short, nvars) - ntokens;    short *nontermmap = XCALLOC (short, nvars) - ntokens;
320    n = ntokens;    n = ntokens;
321    for (i = ntokens; i < nsyms; i++)    for (i = ntokens; i < nsyms; i++)
322      if (BITISSET (V, i))      if (bitset_test (V, i))
323        nontermmap[i] = n++;        nontermmap[i] = n++;
324    for (i = ntokens; i < nsyms; i++)    for (i = ntokens; i < nsyms; i++)
325      if (!BITISSET (V, i))      if (!bitset_test (V, i))
326        nontermmap[i] = n++;        nontermmap[i] = n++;
327    
328    
# Line 405  reduce_output (FILE *out) Line 380  reduce_output (FILE *out)
380      bool b = FALSE;      bool b = FALSE;
381      int i;      int i;
382      for (i = 0; i < ntokens; i++)      for (i = 0; i < ntokens; i++)
383        if (!BITISSET (V, i) && !BITISSET (V1, i))        if (!bitset_test (V, i) && !bitset_test (V1, i))
384          {          {
385            if (!b)            if (!b)
386              fprintf (out, "%s\n\n", _("Terminals which are not used:"));              fprintf (out, "%s\n\n", _("Terminals which are not used:"));
# Line 523  reduce_grammar (void) Line 498  reduce_grammar (void)
498    
499    /* Allocate the global sets used to compute the reduced grammar */    /* Allocate the global sets used to compute the reduced grammar */
500    
501    N = XCALLOC (unsigned, WORDSIZE (nvars));    N = bitset_create (nvars, BITSET_FIXED);
502    P = XCALLOC (unsigned, WORDSIZE (nrules + 1));    bitset_zero (N);
503    V = XCALLOC (unsigned, WORDSIZE (nsyms));    P =  bitset_create (nrules + 1, BITSET_FIXED);
504    V1 = XCALLOC (unsigned, WORDSIZE (nsyms));    bitset_zero (P);
505      V = bitset_create (nsyms, BITSET_FIXED);
506      bitset_zero (V);
507      V1 = bitset_create (nsyms, BITSET_FIXED);
508      bitset_zero (V1);
509    
510    useless_nonterminals ();    useless_nonterminals ();
511    inaccessable_symbols ();    inaccessable_symbols ();
# Line 538  reduce_grammar (void) Line 517  reduce_grammar (void)
517    
518    reduce_print ();    reduce_print ();
519    
520    if (!BITISSET (N, start_symbol - ntokens))    if (!bitset_test (N, start_symbol - ntokens))
521      fatal (_("Start symbol %s does not derive any sentence"),      fatal (_("Start symbol %s does not derive any sentence"),
522             symbols[start_symbol]->tag);             symbols[start_symbol]->tag);
523    
# Line 564  reduce_grammar (void) Line 543  reduce_grammar (void)
543  void  void
544  reduce_free (void)  reduce_free (void)
545  {  {
546    XFREE (N);    bitset_free (N);
547    XFREE (V);    bitset_free (V);
548    XFREE (V1);    bitset_free (V1);
549    XFREE (P);    bitset_free (P);
550  }  }

Legend:
Removed from v.1.41  
changed lines
  Added in v.1.42

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