From 7da99edea76d6148c776214a71bc09dacfc0cb7b Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 12 Nov 2001 09:33:38 +0000 Subject: [PATCH] %expext was not functioning at all. * src/conflicts.c (expected_conflicts): Set to -1. (conflict_report): Use ngettext. (conflicts_print): Check %expect and make its violation an error. * doc/bison.texinfo (Expect Decl): Adjust. * configure.in (AM_GNU_GETTEXT): Ask for ngettext. * tests/regression.at (%expect not enough, %expect right) (%expect too much): New. --- ChangeLog | 12 +++++++++ configure.in | 2 +- doc/bison.texinfo | 19 +++++++------- src/conflicts.c | 40 ++++++++++++++++-------------- src/main.c | 15 ++++++------ tests/regression.at | 60 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index bda485af..2ecb707e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2001-11-12 Akim Demaille + + %expext was not functioning at all. + + * src/conflicts.c (expected_conflicts): Set to -1. + (conflict_report): Use ngettext. + (conflicts_print): Check %expect and make its violation an error. + * doc/bison.texinfo (Expect Decl): Adjust. + * configure.in (AM_GNU_GETTEXT): Ask for ngettext. + * tests/regression.at (%expect not enough, %expect right) + (%expect too much): New. + 2001-11-12 Akim Demaille * tests/regression.at (Conflicts): Rename as... diff --git a/configure.in b/configure.in index 3e5f284d..19070af9 100644 --- a/configure.in +++ b/configure.in @@ -95,7 +95,7 @@ jm_PREREQ_ERROR AM_WITH_DMALLOC ALL_LINGUAS="de es et fr ja nl tr ru" -AM_GNU_GETTEXT +AM_GNU_GETTEXT(, need-ngettext) # This is necessary so that .o files in LIBOBJS are also built via # the ANSI2KNR-filtering rules. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index c4f19339..9f769460 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -3071,11 +3071,11 @@ terminal symbol. All kinds of token declarations allow @findex %expect Bison normally warns if there are any conflicts in the grammar -(@pxref{Shift/Reduce, ,Shift/Reduce Conflicts}), but most real grammars have harmless shift/reduce -conflicts which are resolved in a predictable way and would be difficult to -eliminate. It is desirable to suppress the warning about these conflicts -unless the number of conflicts changes. You can do this with the -@code{%expect} declaration. +(@pxref{Shift/Reduce, ,Shift/Reduce Conflicts}), but most real grammars +have harmless shift/reduce conflicts which are resolved in a predictable +way and would be difficult to eliminate. It is desirable to suppress +the warning about these conflicts unless the number of conflicts +changes. You can do this with the @code{%expect} declaration. The declaration looks like this: @@ -3083,10 +3083,11 @@ The declaration looks like this: %expect @var{n} @end example -Here @var{n} is a decimal integer. The declaration says there should be no -warning if there are @var{n} shift/reduce conflicts and no reduce/reduce -conflicts. The usual warning is given if there are either more or fewer -conflicts, or if there are any reduce/reduce conflicts. +Here @var{n} is a decimal integer. The declaration says there should be +no warning if there are @var{n} shift/reduce conflicts and no +reduce/reduce conflicts. An error, instead of the usual warning, is +given if there are either more or fewer conflicts, or if there are any +reduce/reduce conflicts. In general, using @code{%expect} involves these steps: diff --git a/src/conflicts.c b/src/conflicts.c index 1e5f29cf..91345366 100644 --- a/src/conflicts.c +++ b/src/conflicts.c @@ -19,6 +19,7 @@ 02111-1307, USA. */ #include "system.h" +#include "complain.h" #include "getargs.h" #include "files.h" #include "gram.h" @@ -29,7 +30,8 @@ #include "LR0.h" errs **err_table = NULL; -int expected_conflicts; +/* -1 stands for not specified. */ +int expected_conflicts = -1; static char *conflicts = NULL; static unsigned *shiftset = NULL; @@ -404,31 +406,23 @@ conflict_report (int src_num, int rrc_num) static char res[4096]; char *cp = res; - if (src_num == 1) + if (src_num >= 1) { - sprintf (cp, _(" 1 shift/reduce conflict")); - cp += strlen (cp); - } - else if (src_num > 1) - { - sprintf (cp, _(" %d shift/reduce conflicts"), src_num); + sprintf (cp, ngettext ("%d shift/reduce conflict", + "%d shift/reduce conflicts", src_num), src_num); cp += strlen (cp); } if (src_num > 0 && rrc_num > 0) { - sprintf (cp, _(" and")); + sprintf (cp, " %s ", _("and")); cp += strlen (cp); } - if (rrc_num == 1) + if (rrc_num >= 1) { - sprintf (cp, _(" 1 reduce/reduce conflict")); - cp += strlen (cp); - } - else if (rrc_num > 1) - { - sprintf (cp, _(" %d reduce/reduce conflicts"), rrc_num); + sprintf (cp, ngettext ("%d reduce/reduce conflict", + "%d reduce/reduce conflicts", rrc_num), rrc_num); cp += strlen (cp); } @@ -451,7 +445,7 @@ conflicts_output (FILE *out) for (i = 0; i < nstates; i++) if (conflicts[i]) { - fprintf (out, _("State %d contains"), i); + fprintf (out, _("State %d contains "), i); fputs (conflict_report (count_sr_conflicts (i), count_rr_conflicts (i)), out); } @@ -495,9 +489,19 @@ conflicts_print (void) } else { - fprintf (stderr, _("%s contains"), infile); + fprintf (stderr, _("%s contains "), infile); fputs (conflict_report (src_total, rrc_total), stderr); } + + if (expected_conflicts != -1 + && src_total != expected_conflicts) + { + complain_message_count++; + fprintf (stderr, ngettext ("expected %d shift/reduce conflict", + "expected %d shift/reduce conflicts", + expected_conflicts), + expected_conflicts); + } } diff --git a/src/main.c b/src/main.c index df66d7c6..674c56d5 100644 --- a/src/main.c +++ b/src/main.c @@ -64,15 +64,16 @@ main (int argc, char *argv[]) if (complain_message_count) exit (1); - /* find useless nonterminals and productions and reduce the grammar. In - file reduce.c */ + /* Find useless nonterminals and productions and reduce the grammar. + In file reduce.c. */ reduce_grammar (); - /* record other info about the grammar. In files derives and nullable. */ + /* Record other info about the grammar. In files derives and + nullable. */ set_derives (); set_nullable (); - /* convert to nondeterministic finite state machine. In file LR0. + /* Convert to nondeterministic finite state machine. In file LR0. See state.h for more info. */ generate_states (); @@ -103,14 +104,14 @@ main (int argc, char *argv[]) /* Output the tables and the parser to ftable. In file output. */ output (); + /* Close the input files. */ + close_files (); + /* Free the symbol table data structure. */ free_symtab (); lex_free (); - /* Close the input files. */ - close_files (); - reduce_free (); free_conflicts (); free_nullable (); diff --git a/tests/regression.at b/tests/regression.at index 14ce95ac..da2ab065 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -239,6 +239,66 @@ state 6 AT_CLEANUP(input.c input.output) + +## -------------------- ## +## %expect not enough. ## +## -------------------- ## + +AT_SETUP([%expect not enough]) + +AT_DATA([input.y], +[[%token NUM OP +%expect 0 +%% +exp: exp OP exp | NUM; +]]) + +AT_CHECK([bison input.y -o input.c], 1, [], +[input.y contains 1 shift/reduce conflict. +expected 0 shift/reduce conflicts +]) +AT_CLEANUP(input.c) + + +## --------------- ## +## %expect right. ## +## --------------- ## + +AT_SETUP([%expect right]) + +AT_DATA([input.y], +[[%token NUM OP +%expect 1 +%% +exp: exp OP exp | NUM; +]]) + +AT_CHECK([bison input.y -o input.c], 0, [], +[input.y contains 1 shift/reduce conflict. +]) +AT_CLEANUP(input.c) + + +## ------------------ ## +## %expect too much. ## +## ------------------ ## + +AT_SETUP([%expect too much]) + +AT_DATA([input.y], +[[%token NUM OP +%expect 2 +%% +exp: exp OP exp | NUM; +]]) + +AT_CHECK([bison input.y -o input.c], 1, [], +[input.y contains 1 shift/reduce conflict. +expected 2 shift/reduce conflicts +]) +AT_CLEANUP(input.c) + + ## ---------------------- ## ## Mixing %token styles. ## ## ---------------------- ## -- 2.45.2