In the XML output, list useless and unused symbols and rules with the

useful ones and add a "usefulness" attribute.  Discussed starting at
<http://lists.gnu.org/archive/html/bison-patches/2007-09/msg00017.html>.
* src/gram.c (grammar_rules_partial_print_xml): Remove.
(grammar_rules_print_xml): Print all rules instead of just those
useful in the grammar, and add a "usefulness" attribute.
* src/gram.h (grammar_rules_partial_print_xml): Remove prototype.
* src/print-xml.c (print_rules_useless_in_parser): Remove.
(print_grammar): Print all nonterminals instead of just useful ones,
and add a "usefulness" attribute to nonterminals and terminals.
(print_xml): Don't print a separate "reductions" or
"rules-useless-in-parser" element.
* src/reduce.c (reduce_output): Use reduce_token_unused_in_grammar.
(reduce_xml): Remove.
(reduce_token_unused_in_grammar): New.
(reduce_nonterminal_useless_in_grammar): New.
* src/reduce.h (reduce_xml): Remove prototype.
(reduce_token_unused_in_grammar): Add prototype.
(reduce_nonterminal_useless_in_grammar): Add prototype.
* data/xslt/xml2text.xsl: Update for XML changes.
* data/xslt/xml2xhtml.xsl: Update for XML changes.
* tests/reduce.at (Useless Terminals): Update output.
(Useless Rules): Update output.
(Reduced Automaton): Update output.

Say "Terminals unused in grammar" instead of "Unused terminals".
* NEWS (2.3a+): Update.
* doc/bison.texinfo (Understanding): Update example output.
* src/reduce.c (reduce_output): Implement.
* data/xslt/xml2text.xsl: Implement.
* data/xslt/xml2xhtml.xsl: Implement.
This commit is contained in:
Joel E. Denny
2007-11-24 19:41:25 +00:00
parent 1bb2bd75f0
commit d80fb37a26
11 changed files with 267 additions and 269 deletions

View File

@@ -196,36 +196,6 @@ grammar_rules_partial_print (FILE *out, const char *title,
fputs ("\n\n", out);
}
void
grammar_rules_partial_print_xml (FILE *out, int level, bool rtag,
rule_filter filter)
{
rule_number r;
bool first = true;
for (r = 0; r < nrules + nuseless_productions; r++)
{
if (filter && !filter (&rules[r]))
continue;
if (rtag && first)
xml_puts (out, level + 1, "<rules>");
first = false;
xml_printf (out, level + 2, "<rule number=\"%d\">",
rules[r].number);
rule_lhs_print_xml (&rules[r], out, level + 3);
rule_rhs_print_xml (&rules[r], out, level + 3);
xml_puts (out, level + 2, "</rule>");
}
if (rtag)
{
if (!first)
xml_puts (out, level + 1, "</rules>");
else
xml_puts (out, level + 1, "<rules/>");
}
}
void
grammar_rules_print (FILE *out)
{
@@ -235,7 +205,33 @@ grammar_rules_print (FILE *out)
void
grammar_rules_print_xml (FILE *out, int level)
{
grammar_rules_partial_print_xml (out, level, true, rule_useful_in_grammar_p);
rule_number r;
bool first = true;
for (r = 0; r < nrules + nuseless_productions; r++)
{
if (first)
xml_puts (out, level + 1, "<rules>");
first = false;
{
char const *usefulness;
if (rule_useless_in_grammar_p (&rules[r]))
usefulness = "useless-in-grammar";
else if (rule_useless_in_parser_p (&rules[r]))
usefulness = "useless-in-parser";
else
usefulness = "useful";
xml_printf (out, level + 2, "<rule number=\"%d\" usefulness=\"%s\">",
rules[r].number, usefulness);
}
rule_lhs_print_xml (&rules[r], out, level + 3);
rule_rhs_print_xml (&rules[r], out, level + 3);
xml_puts (out, level + 2, "</rule>");
}
if (!first)
xml_puts (out, level + 1, "</rules>");
else
xml_puts (out, level + 1, "<rules/>");
}
void

View File

@@ -254,11 +254,10 @@ size_t ritem_longest_rhs (void);
/* Print the grammar's rules that match FILTER on OUT under TITLE. */
void grammar_rules_partial_print (FILE *out, const char *title,
rule_filter filter);
void grammar_rules_partial_print_xml (FILE *out, int level, bool rtag,
rule_filter filter);
/* Print the grammar's useful rules on OUT. */
void grammar_rules_print (FILE *out);
/* Print all of the grammar's rules with a "usefulness" attribute. */
void grammar_rules_print_xml (FILE *out, int level);
/* Dump the grammar. */

View File

@@ -51,35 +51,6 @@ struct escape_buf
static struct escape_buf escape_bufs[2];
/*--------------------------------.
| Print rules useless in parser. |
`--------------------------------*/
static void
print_rules_useless_in_parser (FILE *out, int level)
{
rule_number r;
bool count = false;
for (r = 0; r < nrules + nuseless_productions; r++)
{
if (rule_useless_in_parser_p (&rules[r]))
{
count = true;
break;
}
}
if (count) {
xml_puts (out, level, "<rules-useless-in-parser>");
grammar_rules_partial_print_xml (out, level - 1,
false, rule_useless_in_parser_p);
xml_puts (out, level, "</rules-useless-in-parser>");
}
else
xml_puts (out, level, "<rules-useless-in-parser/>");
}
/*--------------------------------.
| Report information on a state. |
`--------------------------------*/
@@ -430,8 +401,10 @@ print_grammar (FILE *out, int level)
xml_printf (out, level + 2,
"<terminal symbol-number=\"%d\" token-number=\"%d\""
" name=\"%s\">",
token_translations[i], i, xml_escape (tag));
" name=\"%s\" usefulness=\"%s\">",
token_translations[i], i, xml_escape (tag),
reduce_token_unused_in_grammar (token_translations[i])
? "unused-in-grammar" : "useful");
for (r = 0; r < nrules; r++)
for (rhsp = rules[r].rhs; *rhsp >= 0; rhsp++)
@@ -446,7 +419,7 @@ print_grammar (FILE *out, int level)
/* Nonterminals */
xml_puts (out, level + 1, "<nonterminals>");
for (i = ntokens; i < nsyms; i++)
for (i = ntokens; i < nsyms + nuseless_nonterminals; i++)
{
int left_count = 0, right_count = 0;
rule_number r;
@@ -466,8 +439,11 @@ print_grammar (FILE *out, int level)
}
xml_printf (out, level + 2,
"<nonterminal symbol-number=\"%d\" name=\"%s\">",
i, xml_escape (tag));
"<nonterminal symbol-number=\"%d\" name=\"%s\""
" usefulness=\"%s\">",
i, xml_escape (tag),
reduce_nonterminal_useless_in_grammar (i)
? "useless-in-grammar" : "useful");
if (left_count > 0)
{
@@ -584,12 +560,6 @@ print_xml (void)
xml_printf (out, level + 1, "<filename>%s</filename>",
xml_escape (grammar_file));
/* print reductions */
reduce_xml (out, level + 1);
/* print rules useless in parser */
print_rules_useless_in_parser (out, level + 1);
/* print grammar */
print_grammar (out, level + 1);

View File

@@ -358,10 +358,10 @@ reduce_output (FILE *out)
bool b = false;
int i;
for (i = 0; i < ntokens; i++)
if (!bitset_test (V, i) && !bitset_test (V1, i))
if (reduce_token_unused_in_grammar (i))
{
if (!b)
fprintf (out, "%s\n\n", _("Terminals which are not used"));
fprintf (out, "%s\n\n", _("Terminals unused in grammar"));
b = true;
fprintf (out, " %s\n", symbols[i]->tag);
}
@@ -375,64 +375,6 @@ reduce_output (FILE *out)
}
/*--------------------------------------------------------------.
| Output the detailed results of the reductions. For FILE.xml. |
`---------------------------------------------------------------*/
void
reduce_xml (FILE *out, int level)
{
fputc ('\n', out);
xml_puts (out, level, "<reductions>");
xml_puts (out, level + 1, "<useless-in-grammar>");
if (nuseless_nonterminals > 0)
{
int i;
xml_puts (out, level + 2, "<nonterminals>");
for (i = 0; i < nuseless_nonterminals; ++i)
xml_printf (out, level + 3,
"<nonterminal>%s</nonterminal>",
symbols[nsyms + i]->tag);
xml_puts (out, level + 2, "</nonterminals>");
}
else
xml_puts (out, level + 2, "<nonterminals/>");
if (nuseless_productions > 0)
grammar_rules_partial_print_xml (out, level + 1, true,
rule_useless_in_grammar_p);
else
xml_puts (out, level + 2, "<rules/>");
xml_puts (out, level + 1, "</useless-in-grammar>");
xml_puts (out, level + 1, "<unused>");
{
bool b = false;
int i;
for (i = 0; i < ntokens; i++)
if (!bitset_test (V, i) && !bitset_test (V1, i))
{
if (!b)
xml_puts (out, level + 2, "<terminals>");
b = true;
xml_printf (out, level + 3,
"<terminal>%s</terminal>",
xml_escape (symbols[i]->tag));
}
if (b)
xml_puts (out, level + 2, "</terminals>");
else
xml_puts (out, level + 2, "<terminals/>");
}
xml_puts (out, level + 1, "</unused>");
xml_puts (out, level, "</reductions>");
fputc ('\n', out);
}
/*-------------------------------.
| Report the results to STDERR. |
`-------------------------------*/
@@ -506,6 +448,19 @@ reduce_grammar (void)
}
}
bool
reduce_token_unused_in_grammar (symbol_number i)
{
aver (i < ntokens);
return !bitset_test (V, i) && !bitset_test (V1, i);
}
bool
reduce_nonterminal_useless_in_grammar (symbol_number i)
{
aver (ntokens <= i && i < nsyms + nuseless_nonterminals);
return nsyms <= i;
}
/*-----------------------------------------------------------.
| Free the global sets used to compute the reduced grammar. |

View File

@@ -22,7 +22,8 @@
void reduce_grammar (void);
void reduce_output (FILE *out);
void reduce_xml (FILE *out, int level);
bool reduce_token_unused_in_grammar (symbol_number i);
bool reduce_nonterminal_useless_in_grammar (symbol_number i);
void reduce_free (void);
extern symbol_number nuseless_nonterminals;