26 |
user's parser. */ |
user's parser. */ |
27 |
|
|
28 |
#include "system.h" |
#include "system.h" |
29 |
#include "quotearg.h" |
|
30 |
#include "getargs.h" |
#include <bitset.h> |
31 |
|
#include <quotearg.h> |
32 |
|
|
33 |
|
#include "complain.h" |
34 |
#include "files.h" |
#include "files.h" |
35 |
#include "symtab.h" |
#include "getargs.h" |
36 |
#include "gram.h" |
#include "gram.h" |
|
#include "complain.h" |
|
|
#include "reduce.h" |
|
37 |
#include "reader.h" |
#include "reader.h" |
38 |
#include "getargs.h" |
#include "reduce.h" |
39 |
#include "bitset.h" |
#include "symtab.h" |
40 |
|
|
41 |
/* Set of all nonterminals which are not useless. */ |
/* Set of all nonterminals which are not useless. */ |
42 |
static bitset N; |
static bitset N; |
51 |
`useless', but no warning should be issued). */ |
`useless', but no warning should be issued). */ |
52 |
static bitset V1; |
static bitset V1; |
53 |
|
|
54 |
static rule_number_t nuseful_productions; |
static rule_number nuseful_productions; |
55 |
rule_number_t nuseless_productions; |
rule_number nuseless_productions; |
56 |
static int nuseful_nonterminals; |
static int nuseful_nonterminals; |
57 |
symbol_number_t nuseless_nonterminals; |
symbol_number nuseless_nonterminals; |
58 |
|
|
59 |
/*-------------------------------------------------------------------. |
/*-------------------------------------------------------------------. |
60 |
| Another way to do this would be with a set for each production and | |
| Another way to do this would be with a set for each production and | |
63 |
`-------------------------------------------------------------------*/ |
`-------------------------------------------------------------------*/ |
64 |
|
|
65 |
static bool |
static bool |
66 |
useful_production (rule_number_t r, bitset N0) |
useful_production (rule_number r, bitset N0) |
67 |
{ |
{ |
68 |
item_number_t *rhsp; |
item_number *rhsp; |
69 |
|
|
70 |
/* A production is useful if all of the nonterminals in its appear |
/* A production is useful if all of the nonterminals in its appear |
71 |
in the set of useful nonterminals. */ |
in the set of useful nonterminals. */ |
85 |
useless_nonterminals (void) |
useless_nonterminals (void) |
86 |
{ |
{ |
87 |
bitset Np, Ns; |
bitset Np, Ns; |
88 |
rule_number_t r; |
rule_number r; |
89 |
|
|
90 |
/* 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 |
91 |
set of all productions which have a RHS all in N. */ |
set of all productions which have a RHS all in N. */ |
168 |
|
|
169 |
while (1) |
while (1) |
170 |
{ |
{ |
171 |
rule_number_t r; |
rule_number r; |
172 |
bitset_copy (Vp, V); |
bitset_copy (Vp, V); |
173 |
for (r = 0; r < nrules; r++) |
for (r = 0; r < nrules; r++) |
174 |
{ |
{ |
176 |
&& bitset_test (P, r) |
&& bitset_test (P, r) |
177 |
&& bitset_test (V, rules[r].lhs->number)) |
&& bitset_test (V, rules[r].lhs->number)) |
178 |
{ |
{ |
179 |
item_number_t *rhsp; |
item_number *rhsp; |
180 |
for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++) |
for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++) |
181 |
if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens)) |
if (ISTOKEN (*rhsp) || bitset_test (N, *rhsp - ntokens)) |
182 |
bitset_set (Vp, *rhsp); |
bitset_set (Vp, *rhsp); |
207 |
|
|
208 |
nuseful_nonterminals = 0; |
nuseful_nonterminals = 0; |
209 |
{ |
{ |
210 |
symbol_number_t i; |
symbol_number i; |
211 |
for (i = ntokens; i < nsyms; i++) |
for (i = ntokens; i < nsyms; i++) |
212 |
if (bitset_test (V, i)) |
if (bitset_test (V, i)) |
213 |
nuseful_nonterminals++; |
nuseful_nonterminals++; |
216 |
|
|
217 |
/* A token that was used in %prec should not be warned about. */ |
/* A token that was used in %prec should not be warned about. */ |
218 |
{ |
{ |
219 |
rule_number_t r; |
rule_number r; |
220 |
for (r = 0; r < nrules; ++r) |
for (r = 0; r < nrules; ++r) |
221 |
if (rules[r].precsym != 0) |
if (rules[r].precsym != 0) |
222 |
bitset_set (V1, rules[r].precsym->number); |
bitset_set (V1, rules[r].precsym->number); |
234 |
{ |
{ |
235 |
/* Report and flag useless productions. */ |
/* Report and flag useless productions. */ |
236 |
{ |
{ |
237 |
rule_number_t r; |
rule_number r; |
238 |
for (r = 0; r < nrules; r++) |
for (r = 0; r < nrules; r++) |
239 |
rules[r].useful = bitset_test (P, r); |
rules[r].useful = bitset_test (P, r); |
240 |
grammar_rules_never_reduced_report (_("useless rule")); |
grammar_rules_never_reduced_report (_("useless rule")); |
245 |
{ |
{ |
246 |
int useful = 0; |
int useful = 0; |
247 |
int useless = nrules - nuseless_productions; |
int useless = nrules - nuseless_productions; |
248 |
rule_t *rules_sorted = XMALLOC (rule_t, nrules); |
rule *rules_sorted = XMALLOC (rule, nrules); |
249 |
rule_number_t r; |
rule_number r; |
250 |
for (r = 0; r < nrules; ++r) |
for (r = 0; r < nrules; ++r) |
251 |
rules_sorted[rules[r].useful ? useful++ : useless++] = rules[r]; |
rules_sorted[rules[r].useful ? useful++ : useless++] = rules[r]; |
252 |
free (rules); |
free (rules); |
255 |
/* Renumber the rules markers in RITEMS. */ |
/* Renumber the rules markers in RITEMS. */ |
256 |
for (r = 0; r < nrules; ++r) |
for (r = 0; r < nrules; ++r) |
257 |
{ |
{ |
258 |
item_number_t *rhsp = rules[r].rhs; |
item_number *rhsp = rules[r].rhs; |
259 |
for (/* Nothing. */; *rhsp >= 0; ++rhsp) |
for (/* Nothing. */; *rhsp >= 0; ++rhsp) |
260 |
/* Nothing. */; |
/* Nothing. */; |
261 |
*rhsp = rule_number_as_item_number (r); |
*rhsp = rule_number_as_item_number (r); |
284 |
static void |
static void |
285 |
nonterminals_reduce (void) |
nonterminals_reduce (void) |
286 |
{ |
{ |
287 |
symbol_number_t i, n; |
symbol_number i, n; |
288 |
|
|
289 |
/* Map the nonterminals to their new index: useful first, useless |
/* Map the nonterminals to their new index: useful first, useless |
290 |
afterwards. Kept for later report. */ |
afterwards. Kept for later report. */ |
291 |
|
|
292 |
symbol_number_t *nontermmap = XCALLOC (symbol_number_t, nvars) - ntokens; |
symbol_number *nontermmap = XCALLOC (symbol_number, nvars) - ntokens; |
293 |
n = ntokens; |
n = ntokens; |
294 |
for (i = ntokens; i < nsyms; i++) |
for (i = ntokens; i < nsyms; i++) |
295 |
if (bitset_test (V, i)) |
if (bitset_test (V, i)) |
305 |
|
|
306 |
/* Shuffle elements of tables indexed by symbol number. */ |
/* Shuffle elements of tables indexed by symbol number. */ |
307 |
{ |
{ |
308 |
symbol_t **symbols_sorted = XMALLOC (symbol_t *, nvars) - ntokens; |
symbol **symbols_sorted = XMALLOC (symbol *, nvars) - ntokens; |
309 |
|
|
310 |
for (i = ntokens; i < nsyms; i++) |
for (i = ntokens; i < nsyms; i++) |
311 |
symbols[i]->number = nontermmap[i]; |
symbols[i]->number = nontermmap[i]; |
317 |
} |
} |
318 |
|
|
319 |
{ |
{ |
320 |
rule_number_t r; |
rule_number r; |
321 |
for (r = 0; r < nrules; ++r) |
for (r = 0; r < nrules; ++r) |
322 |
{ |
{ |
323 |
item_number_t *rhsp; |
item_number *rhsp; |
324 |
for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp) |
for (rhsp = rules[r].rhs; *rhsp >= 0; ++rhsp) |
325 |
if (ISVAR (*rhsp)) |
if (ISVAR (*rhsp)) |
326 |
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp]); |
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp]); |