/* Grammar reduction for Bison.
- Copyright (C) 1988, 1989, 2000 Free Software Foundation, Inc.
+ Copyright 1988, 1989, 2000, 2001 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
#include "getargs.h"
#include "files.h"
#include "gram.h"
-#include "alloc.h"
#include "complain.h"
#include "reduce.h"
-
-extern char **tags; /* reader.c */
-static int statisticsflag; /* XXXXXXX */
-extern int fixed_outfiles;
+#include "reader.h"
+#include "getargs.h"
typedef unsigned *BSet;
typedef short *rule;
/* A production is useful if all of the nonterminals in its appear
in the set of useful nonterminals. */
- for (r = &ritem[rrhs[i]]; *r > 0; r++)
+ for (r = &ritem[rule_table[i].rhs]; *r > 0; r++)
if (ISVAR (n = *r))
if (!BITISSET (N0, n - ntokens))
return FALSE;
useless_nonterminals (void)
{
BSet Np, Ns;
- int i, n;
+ int i;
/* N is set as built. Np is set being built this iteration. P is
set of all productions which have a RHS all in N. */
- Np = NEW2 (WORDSIZE (nvars), unsigned);
+ Np = XCALLOC (unsigned, WORDSIZE (nvars));
/* The set being computed is a set of nonterminals which can derive
the empty string or strings consisting of all terminals. At each
saved to be used when finding useful productions: only
productions in this set will appear in the final grammar. */
- n = 0;
while (1)
{
for (i = WORDSIZE (nvars) - 1; i >= 0; i--)
{
if (useful_production (i, N))
{
- SETBIT (Np, rlhs[i] - ntokens);
+ SETBIT (Np, rule_table[i].lhs - ntokens);
SETBIT (P, i);
}
}
Np = N;
N = Ns;
}
- FREE (N);
+ XFREE (N);
N = Np;
}
inaccessable_symbols (void)
{
BSet Vp, Vs, Pp;
- int i, n;
+ int i;
short t;
rule r;
terminals are printed (if running in verbose mode) so that the
user can know. */
- Vp = NEW2 (WORDSIZE (nsyms), unsigned);
- Pp = NEW2 (WORDSIZE (nrules + 1), unsigned);
+ Vp = XCALLOC (unsigned, WORDSIZE (nsyms));
+ Pp = XCALLOC (unsigned, WORDSIZE (nrules + 1));
/* If the start symbol isn't useful, then nothing will be useful. */
if (!BITISSET (N, start_symbol - ntokens))
SETBIT (V, start_symbol);
- n = 0;
while (1)
{
for (i = WORDSIZE (nsyms) - 1; i >= 0; i--)
Vp[i] = V[i];
for (i = 1; i <= nrules; i++)
{
- if (!BITISSET (Pp, i) && BITISSET (P, i) && BITISSET (V, rlhs[i]))
+ if (!BITISSET (Pp, i) && BITISSET (P, i) && BITISSET (V, rule_table[i].lhs))
{
- for (r = &ritem[rrhs[i]]; *r >= 0; r++)
+ for (r = &ritem[rule_table[i].rhs]; *r >= 0; r++)
{
if (ISTOKEN (t = *r) || BITISSET (N, t - ntokens))
{
}
end_iteration:
- FREE (V);
+ XFREE (V);
V = Vp;
/* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */
SETBIT (V, 1); /* error token */
SETBIT (V, 2); /* some undefined token */
- FREE (P);
+ XFREE (P);
P = Pp;
nuseful_productions = bits_size (P, WORDSIZE (nrules + 1));
/* A token that was used in %prec should not be warned about. */
for (i = 1; i < nrules; i++)
- if (rprecsym[i] != 0)
- SETBIT (V1, rprecsym[i]);
+ if (rule_table[i].precsym != 0)
+ SETBIT (V1, rule_table[i].precsym);
}
static void
np++;
if (pn != np)
{
- rlhs[np] = rlhs[pn];
+ rule_table[np].lhs = rule_table[pn].lhs;
rline[np] = rline[pn];
- rprec[np] = rprec[pn];
- rassoc[np] = rassoc[pn];
- rrhs[np] = rrhs[pn];
- if (rrhs[np] != ni)
+ rule_table[np].prec = rule_table[pn].prec;
+ rule_table[np].assoc = rule_table[pn].assoc;
+ rule_table[np].rhs = rule_table[pn].rhs;
+ if (rule_table[np].rhs != ni)
{
- pi = rrhs[np];
- rrhs[np] = ni;
+ pi = rule_table[np].rhs;
+ rule_table[np].rhs = ni;
while (ritem[pi] >= 0)
ritem[ni++] = ritem[pi++];
ritem[ni++] = -np;
{
if (!BITISSET (P, pn))
{
- rlhs[pn] = -1;
+ rule_table[pn].lhs = -1;
}
}
}
number. -1 in the map means it was useless and is being
eliminated. */
- nontermmap = NEW2 (nvars, short) - ntokens;
+ nontermmap = XCALLOC (short, nvars) - ntokens;
for (i = ntokens; i < nsyms; i++)
nontermmap[i] = -1;
for (i = 1; i <= nrules; i++)
{
/* Ignore the rules disabled above. */
- if (rlhs[i] >= 0)
- rlhs[i] = nontermmap[rlhs[i]];
- if (ISVAR (rprecsym[i]))
+ if (rule_table[i].lhs >= 0)
+ rule_table[i].lhs = nontermmap[rule_table[i].lhs];
+ if (ISVAR (rule_table[i].precsym))
/* Can this happen? */
- rprecsym[i] = nontermmap[rprecsym[i]];
+ rule_table[i].precsym = nontermmap[rule_table[i].precsym];
}
for (r = ritem; *r; r++)
}
}
-static void
-print_results (void)
+
+/*-----------------------------------------------------------------.
+| Ouput the detailed results of the reductions. For FILE.output. |
+`-----------------------------------------------------------------*/
+
+void
+reduce_output (FILE *out)
{
int i;
-/* short j; JF unused */
rule r;
bool b;
if (nuseless_nonterminals > 0)
{
- fprintf (foutput, _("Useless nonterminals:\n\n"));
+ fprintf (out, _("Useless nonterminals:"));
+ fprintf (out, "\n\n");
for (i = ntokens; i < nsyms; i++)
if (!BITISSET (V, i))
- fprintf (foutput, " %s\n", tags[i]);
+ fprintf (out, " %s\n", tags[i]);
}
b = FALSE;
for (i = 0; i < ntokens; i++)
{
if (!b)
{
- fprintf (foutput, _("\n\nTerminals which are not used:\n\n"));
+ fprintf (out, "\n\n");
+ fprintf (out, _("Terminals which are not used:"));
+ fprintf (out, "\n\n");
b = TRUE;
}
- fprintf (foutput, " %s\n", tags[i]);
+ fprintf (out, " %s\n", tags[i]);
}
}
if (nuseless_productions > 0)
{
- fprintf (foutput, _("\n\nUseless rules:\n\n"));
+ fprintf (out, "\n\n");
+ fprintf (out, _("Useless rules:"));
+ fprintf (out, "\n\n");
for (i = 1; i <= nrules; i++)
{
if (!BITISSET (P, i))
{
- fprintf (foutput, "#%-4d ", i);
- fprintf (foutput, "%s :\t", tags[rlhs[i]]);
- for (r = &ritem[rrhs[i]]; *r >= 0; r++)
- {
- fprintf (foutput, " %s", tags[*r]);
- }
- fprintf (foutput, ";\n");
+ fprintf (out, "#%-4d ", i);
+ fprintf (out, "%s :\t", tags[rule_table[i].lhs]);
+ for (r = &ritem[rule_table[i].rhs]; *r >= 0; r++)
+ fprintf (out, " %s", tags[*r]);
+ fprintf (out, ";\n");
}
}
}
if (nuseless_nonterminals > 0 || nuseless_productions > 0 || b)
- fprintf (foutput, "\n\n");
+ fprintf (out, "\n\n");
}
\f
#if 0 /* XXX currently unused. */
static void
-dump_grammar (void)
+dump_grammar (FILE *out)
{
int i;
rule r;
- fprintf (foutput,
- "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nitems = %d\n\n",
- ntokens, nvars, nsyms, nrules, nitems);
- fprintf (foutput, _("Variables\n---------\n\n"));
- fprintf (foutput, _("Value Sprec Sassoc Tag\n"));
+ fprintf (out,
+ "ntokens = %d, nvars = %d, nsyms = %d, nrules = %d, nitems = %d\n\n",
+ ntokens, nvars, nsyms, nrules, nitems);
+ fprintf (out, _("Variables\n---------\n\n"));
+ fprintf (out, _("Value Sprec Sassoc Tag\n"));
for (i = ntokens; i < nsyms; i++)
- fprintf (foutput, "%5d %5d %5d %s\n", i, sprec[i], sassoc[i], tags[i]);
- fprintf (foutput, "\n\n");
- fprintf (foutput, _("Rules\n-----\n\n"));
+ fprintf (out, "%5d %5d %5d %s\n", i, sprec[i], sassoc[i], tags[i]);
+ fprintf (out, "\n\n");
+ fprintf (out, _("Rules\n-----\n\n"));
for (i = 1; i <= nrules; i++)
{
- fprintf (foutput, "%-5d(%5d%5d)%5d : (@%-5d)",
- i, rprec[i], rassoc[i], rlhs[i], rrhs[i]);
- for (r = &ritem[rrhs[i]]; *r > 0; r++)
- fprintf (foutput, "%5d", *r);
- fprintf (foutput, " [%d]\n", -(*r));
+ fprintf (out, "%-5d(%5d%5d)%5d : (@%-5d)",
+ i,
+ rule_table[i].prec,
+ rule_table[i].assoc,
+ rule_table[i].lhs,
+ rule_table[i].rhs);
+ for (r = &ritem[rule_table[i].rhs]; *r > 0; r++)
+ fprintf (out, "%5d", *r);
+ fprintf (out, " [%d]\n", -(*r));
}
- fprintf (foutput, "\n\n");
- fprintf (foutput, _("Rules interpreted\n-----------------\n\n"));
+ fprintf (out, "\n\n");
+ fprintf (out, _("Rules interpreted\n-----------------\n\n"));
for (i = 1; i <= nrules; i++)
{
- fprintf (foutput, "%-5d %s :", i, tags[rlhs[i]]);
- for (r = &ritem[rrhs[i]]; *r > 0; r++)
- fprintf (foutput, " %s", tags[*r]);
- fprintf (foutput, "\n");
+ fprintf (out, "%-5d %s :", i, tags[rule_table[i].lhs]);
+ for (r = &ritem[rule_table[i].rhs]; *r > 0; r++)
+ fprintf (out, " %s", tags[*r]);
+ fputc ('\n', out);
}
- fprintf (foutput, "\n\n");
+ fprintf (out, "\n\n");
}
-
#endif
+
+/*-------------------------------.
+| Report the results to STDERR. |
+`-------------------------------*/
+
static void
-print_notices (void)
+reduce_print (void)
{
- if (fixed_outfiles && nuseless_productions)
+ if (yacc_flag && nuseless_productions)
fprintf (stderr, _("%d rules never reduced\n"), nuseless_productions);
fprintf (stderr, _("%s contains "), infile);
/* Allocate the global sets used to compute the reduced grammar */
- N = NEW2 (WORDSIZE (nvars), unsigned);
- P = NEW2 (WORDSIZE (nrules + 1), unsigned);
- V = NEW2 (WORDSIZE (nsyms), unsigned);
- V1 = NEW2 (WORDSIZE (nsyms), unsigned);
+ N = XCALLOC (unsigned, WORDSIZE (nvars));
+ P = XCALLOC (unsigned, WORDSIZE (nrules + 1));
+ V = XCALLOC (unsigned, WORDSIZE (nsyms));
+ V1 = XCALLOC (unsigned, WORDSIZE (nsyms));
useless_nonterminals ();
inaccessable_symbols ();
reduced = (bool) (nuseless_nonterminals + nuseless_productions > 0);
- if (verboseflag)
- print_results ();
+ if (!reduced)
+ return;
- if (reduced == FALSE)
- goto done_reducing;
-
- print_notices ();
+ reduce_print ();
if (!BITISSET (N, start_symbol - ntokens))
fatal (_("Start symbol %s does not derive any sentence"),
reduce_grammar_tables ();
#if 0
- if (verboseflag)
+ if (verbose_flag)
{
- fprintf (foutput, "REDUCED GRAMMAR\n\n");
+ fprintf (out, "REDUCED GRAMMAR\n\n");
dump_grammar ();
}
#endif
- statisticsflag = FALSE; /* someday getopts should handle this */
- if (statisticsflag == TRUE)
+
+ if (statistics_flag)
fprintf (stderr, _("reduced %s defines %d terminal%s, %d nonterminal%s\
, and %d production%s.\n"),
infile,
(nvars == 1 ? "" : "s"),
nrules,
(nrules == 1 ? "" : "s"));
+}
+
-done_reducing:
- /* Free the global sets used to compute the reduced grammar */
+/*-----------------------------------------------------------.
+| Free the global sets used to compute the reduced grammar. |
+`-----------------------------------------------------------*/
- FREE (N);
- FREE (V);
- FREE (P);
+void
+reduce_free (void)
+{
+ XFREE (N);
+ XFREE (V);
+ XFREE (V1);
+ XFREE (P);
}