220 |
bitset_set (V1, rules[i].precsym); |
bitset_set (V1, rules[i].precsym); |
221 |
} |
} |
222 |
|
|
223 |
|
|
224 |
|
/*-------------------------------------------------------------------. |
225 |
|
| Put the useless productions at the end of RULES, and adjust NRULES | |
226 |
|
| accordingly. | |
227 |
|
`-------------------------------------------------------------------*/ |
228 |
|
|
229 |
static void |
static void |
230 |
reduce_grammar_tables (void) |
reduce_grammar_tables (void) |
231 |
{ |
{ |
232 |
/* This is turned off because we would need to change the numbers in |
/* Flag useless productions. */ |
233 |
the case statements in the actions file. |
{ |
234 |
|
int pn; |
235 |
We don't disable it via CPP so that it is still checked with the |
for (pn = 1; pn < nrules + 1; pn++) |
236 |
rest of the code, to avoid its becoming completely obsolete. |
rules[pn].useful = bitset_test (P, pn); |
237 |
|
} |
|
FIXME: I think the comment above demonstrates this code must be |
|
|
turned off for *semantic* parser, not in the general case. Try |
|
|
to understand this better --akim. */ |
|
|
|
|
|
if (0) |
|
|
/* remove useless productions */ |
|
|
if (nuseless_productions > 0) |
|
|
{ |
|
|
short np, pn, ni, pi; |
|
|
|
|
|
np = 0; |
|
|
ni = 0; |
|
|
for (pn = 1; pn < nrules + 1; pn++) |
|
|
if (bitset_test (P, pn)) |
|
|
{ |
|
|
np++; |
|
|
if (pn != np) |
|
|
{ |
|
|
rules[np].lhs = rules[pn].lhs; |
|
|
rules[np].line = rules[pn].line; |
|
|
rules[np].prec = rules[pn].prec; |
|
|
rules[np].assoc = rules[pn].assoc; |
|
|
rules[np].rhs = rules[pn].rhs; |
|
|
if (rules[np].rhs - ritem != ni) |
|
|
{ |
|
|
pi = rules[np].rhs - ritem; |
|
|
rules[np].rhs = ritem + ni; |
|
|
while (ritem[pi] >= 0) |
|
|
ritem[ni++] = ritem[pi++]; |
|
|
ritem[ni++] = -np; |
|
|
} |
|
|
} |
|
|
else |
|
|
{ |
|
|
while (ritem[ni++] >= 0) |
|
|
/* Nothing. */; |
|
|
} |
|
|
} |
|
|
|
|
|
ritem[ni] = 0; |
|
|
nrules -= nuseless_productions; |
|
|
nitems = ni; |
|
|
nritems = ni; |
|
238 |
|
|
239 |
/* Is it worth it to reduce the amount of memory for the |
/* Map the nonterminals to their new index: useful first, useless |
240 |
grammar? Probably not. */ |
afterwards. Kept for later report. */ |
241 |
} |
{ |
242 |
|
int useful = 1; |
243 |
|
int useless = nrules + 1 - nuseless_productions; |
244 |
|
rule_t *rules_sorted = XMALLOC (rule_t, nrules + 1) - 1; |
245 |
|
int i; |
246 |
|
for (i = 1; i < nrules + 1; ++i) |
247 |
|
rules_sorted[rules[i].useful ? useful++ : useless++] = rules[i]; |
248 |
|
free (rules + 1); |
249 |
|
rules = rules_sorted; |
250 |
|
|
251 |
/* Disable useless productions. */ |
/* Also reorder ritems. */ |
|
if (nuseless_productions > 0) |
|
252 |
{ |
{ |
253 |
int pn; |
short *ritems_sorted = XCALLOC (short, nitems + 1); |
254 |
for (pn = 1; pn < nrules + 1; pn++) |
short *ritemsp = ritems_sorted; |
255 |
rules[pn].useful = bitset_test (P, pn); |
for (i = 1; i < nrules + 1; ++i) |
256 |
|
{ |
257 |
|
short *rhsp = rules[i].rhs; |
258 |
|
rules[i].rhs = ritemsp; |
259 |
|
for (/* Nothing. */; *rhsp >= 0; ++rhsp) |
260 |
|
*ritemsp++ = *rhsp; |
261 |
|
*ritemsp++ = -i; |
262 |
|
} |
263 |
|
*ritemsp++ = 0; |
264 |
|
free (ritem); |
265 |
|
ritem = ritems_sorted; |
266 |
} |
} |
267 |
|
nrules -= nuseless_productions; |
268 |
|
} |
269 |
|
|
270 |
|
/* Adjust NRITEMS and NITEMS. */ |
271 |
|
{ |
272 |
|
int r; |
273 |
|
int length; |
274 |
|
for (r = nrules + 1; r < nrules + 1 + nuseless_productions; ++r) |
275 |
|
{ |
276 |
|
length = rule_rhs_length (&rules[r]); |
277 |
|
nritems -= length + 1; |
278 |
|
nitems -= length + 1; |
279 |
|
} |
280 |
|
} |
281 |
} |
} |
282 |
|
|
283 |
|
|
372 |
{ |
{ |
373 |
int i; |
int i; |
374 |
fprintf (out, "%s\n\n", _("Useless rules:")); |
fprintf (out, "%s\n\n", _("Useless rules:")); |
375 |
for (i = 1; i < nrules + 1; i++) |
for (i = nrules + 1; i < nuseless_productions + nrules + 1; i++) |
376 |
if (!rules[i].useful) |
{ |
377 |
{ |
rule r; |
378 |
rule r; |
fprintf (out, "#%-4d ", rules[i].number - 1); |
379 |
fprintf (out, "#%-4d ", i - 1); |
fprintf (out, "%s:", symbols[rules[i].lhs]->tag); |
380 |
fprintf (out, "%s:", symbols[rules[i].lhs]->tag); |
for (r = rules[i].rhs; *r >= 0; r++) |
381 |
for (r = rules[i].rhs; *r >= 0; r++) |
fprintf (out, " %s", symbols[*r]->tag); |
382 |
fprintf (out, " %s", symbols[*r]->tag); |
fputs (";\n", out); |
383 |
fputs (";\n", out); |
} |
|
} |
|
384 |
fputs ("\n\n", out); |
fputs ("\n\n", out); |
385 |
} |
} |
386 |
} |
} |
404 |
fprintf (out, "\n\n"); |
fprintf (out, "\n\n"); |
405 |
fprintf (out, "Rules\n-----\n\n"); |
fprintf (out, "Rules\n-----\n\n"); |
406 |
fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n"); |
fprintf (out, "Num (Prec, Assoc, Useful, Ritem Range) Lhs -> Rhs (Ritem range) [Num]\n"); |
407 |
for (i = 1; i < nrules + 1; i++) |
for (i = 1; i < nrules + nuseless_productions + 1; i++) |
408 |
{ |
{ |
409 |
int rhs_count = 0; |
int rhs_count = 0; |
410 |
/* Find the last RHS index in ritems. */ |
/* Find the last RHS index in ritems. */ |
422 |
} |
} |
423 |
fprintf (out, "\n\n"); |
fprintf (out, "\n\n"); |
424 |
fprintf (out, "Rules interpreted\n-----------------\n\n"); |
fprintf (out, "Rules interpreted\n-----------------\n\n"); |
425 |
for (i = 1; i < nrules + 1; i++) |
for (i = 1; i < nrules + nuseless_productions + 1; i++) |
426 |
{ |
{ |
427 |
fprintf (out, "%-5d %s :", i, symbols[rules[i].lhs]->tag); |
fprintf (out, "%-5d %s :", i, symbols[rules[i].lhs]->tag); |
428 |
for (r = rules[i].rhs; *r >= 0; r++) |
for (r = rules[i].rhs; *r >= 0; r++) |
492 |
fatal (_("Start symbol %s does not derive any sentence"), |
fatal (_("Start symbol %s does not derive any sentence"), |
493 |
symbols[start_symbol]->tag); |
symbols[start_symbol]->tag); |
494 |
|
|
495 |
reduce_grammar_tables (); |
if (nuseless_productions > 0) |
496 |
|
reduce_grammar_tables (); |
497 |
if (nuseless_nonterminals > 0) |
if (nuseless_nonterminals > 0) |
498 |
nonterminals_reduce (); |
nonterminals_reduce (); |
499 |
|
|