%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.
This commit is contained in:
Akim Demaille
2001-11-12 09:33:38 +00:00
parent ba9dda1a2e
commit 7da99edea7
6 changed files with 113 additions and 35 deletions

View File

@@ -1,3 +1,15 @@
2001-11-12 Akim Demaille <akim@epita.fr>
%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 <akim@epita.fr> 2001-11-12 Akim Demaille <akim@epita.fr>
* tests/regression.at (Conflicts): Rename as... * tests/regression.at (Conflicts): Rename as...

View File

@@ -95,7 +95,7 @@ jm_PREREQ_ERROR
AM_WITH_DMALLOC AM_WITH_DMALLOC
ALL_LINGUAS="de es et fr ja nl tr ru" 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 # This is necessary so that .o files in LIBOBJS are also built via
# the ANSI2KNR-filtering rules. # the ANSI2KNR-filtering rules.

View File

@@ -3071,11 +3071,11 @@ terminal symbol. All kinds of token declarations allow
@findex %expect @findex %expect
Bison normally warns if there are any conflicts in the grammar 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 (@pxref{Shift/Reduce, ,Shift/Reduce Conflicts}), but most real grammars
conflicts which are resolved in a predictable way and would be difficult to have harmless shift/reduce conflicts which are resolved in a predictable
eliminate. It is desirable to suppress the warning about these conflicts way and would be difficult to eliminate. It is desirable to suppress
unless the number of conflicts changes. You can do this with the the warning about these conflicts unless the number of conflicts
@code{%expect} declaration. changes. You can do this with the @code{%expect} declaration.
The declaration looks like this: The declaration looks like this:
@@ -3083,10 +3083,11 @@ The declaration looks like this:
%expect @var{n} %expect @var{n}
@end example @end example
Here @var{n} is a decimal integer. The declaration says there should be no Here @var{n} is a decimal integer. The declaration says there should be
warning if there are @var{n} shift/reduce conflicts and no reduce/reduce no warning if there are @var{n} shift/reduce conflicts and no
conflicts. The usual warning is given if there are either more or fewer reduce/reduce conflicts. An error, instead of the usual warning, is
conflicts, or if there are any reduce/reduce conflicts. 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: In general, using @code{%expect} involves these steps:

View File

@@ -19,6 +19,7 @@
02111-1307, USA. */ 02111-1307, USA. */
#include "system.h" #include "system.h"
#include "complain.h"
#include "getargs.h" #include "getargs.h"
#include "files.h" #include "files.h"
#include "gram.h" #include "gram.h"
@@ -29,7 +30,8 @@
#include "LR0.h" #include "LR0.h"
errs **err_table = NULL; errs **err_table = NULL;
int expected_conflicts; /* -1 stands for not specified. */
int expected_conflicts = -1;
static char *conflicts = NULL; static char *conflicts = NULL;
static unsigned *shiftset = NULL; static unsigned *shiftset = NULL;
@@ -404,31 +406,23 @@ conflict_report (int src_num, int rrc_num)
static char res[4096]; static char res[4096];
char *cp = res; char *cp = res;
if (src_num == 1) if (src_num >= 1)
{ {
sprintf (cp, _(" 1 shift/reduce conflict")); sprintf (cp, ngettext ("%d shift/reduce conflict",
cp += strlen (cp); "%d shift/reduce conflicts", src_num), src_num);
}
else if (src_num > 1)
{
sprintf (cp, _(" %d shift/reduce conflicts"), src_num);
cp += strlen (cp); cp += strlen (cp);
} }
if (src_num > 0 && rrc_num > 0) if (src_num > 0 && rrc_num > 0)
{ {
sprintf (cp, _(" and")); sprintf (cp, " %s ", _("and"));
cp += strlen (cp); cp += strlen (cp);
} }
if (rrc_num == 1) if (rrc_num >= 1)
{ {
sprintf (cp, _(" 1 reduce/reduce conflict")); sprintf (cp, ngettext ("%d reduce/reduce conflict",
cp += strlen (cp); "%d reduce/reduce conflicts", rrc_num), rrc_num);
}
else if (rrc_num > 1)
{
sprintf (cp, _(" %d reduce/reduce conflicts"), rrc_num);
cp += strlen (cp); cp += strlen (cp);
} }
@@ -451,7 +445,7 @@ conflicts_output (FILE *out)
for (i = 0; i < nstates; i++) for (i = 0; i < nstates; i++)
if (conflicts[i]) if (conflicts[i])
{ {
fprintf (out, _("State %d contains"), i); fprintf (out, _("State %d contains "), i);
fputs (conflict_report (count_sr_conflicts (i), fputs (conflict_report (count_sr_conflicts (i),
count_rr_conflicts (i)), out); count_rr_conflicts (i)), out);
} }
@@ -495,9 +489,19 @@ conflicts_print (void)
} }
else else
{ {
fprintf (stderr, _("%s contains"), infile); fprintf (stderr, _("%s contains "), infile);
fputs (conflict_report (src_total, rrc_total), stderr); 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);
}
} }

View File

@@ -64,15 +64,16 @@ main (int argc, char *argv[])
if (complain_message_count) if (complain_message_count)
exit (1); exit (1);
/* find useless nonterminals and productions and reduce the grammar. In /* Find useless nonterminals and productions and reduce the grammar.
file reduce.c */ In file reduce.c. */
reduce_grammar (); 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_derives ();
set_nullable (); 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. */ See state.h for more info. */
generate_states (); generate_states ();
@@ -103,14 +104,14 @@ main (int argc, char *argv[])
/* Output the tables and the parser to ftable. In file output. */ /* Output the tables and the parser to ftable. In file output. */
output (); output ();
/* Close the input files. */
close_files ();
/* Free the symbol table data structure. */ /* Free the symbol table data structure. */
free_symtab (); free_symtab ();
lex_free (); lex_free ();
/* Close the input files. */
close_files ();
reduce_free (); reduce_free ();
free_conflicts (); free_conflicts ();
free_nullable (); free_nullable ();

View File

@@ -239,6 +239,66 @@ state 6
AT_CLEANUP(input.c input.output) 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. ## ## Mixing %token styles. ##
## ---------------------- ## ## ---------------------- ##