X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/76be9271f2bd46510de83d9957d4cfc68d757996..4f16766c00b107bf12328bc6a613535bd7af8275:/src/conflicts.c diff --git a/src/conflicts.c b/src/conflicts.c index 0c2fb03c..2edd1e8b 100644 --- a/src/conflicts.c +++ b/src/conflicts.c @@ -1,6 +1,6 @@ /* Find and resolve or report look-ahead conflicts for bison, - Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002 + Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -36,7 +36,8 @@ #include "symtab.h" /* -1 stands for not specified. */ -int expected_conflicts = -1; +int expected_sr_conflicts = -1; +int expected_rr_conflicts = -1; static char *conflicts = NULL; struct obstack solved_conflicts_obstack; @@ -237,9 +238,12 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors) } } - /* Some tokens have been explicitly made errors. Allocate a - permanent errs structure for this state, to record them. */ - state_errs_set (s, nerrs, errors); + if (nerrs) + { + /* Some tokens have been explicitly made errors. Allocate a + permanent errs structure for this state, to record them. */ + state_errs_set (s, nerrs, errors); + } if (obstack_object_size (&solved_conflicts_obstack)) { @@ -277,10 +281,7 @@ set_conflicts (state *s, symbol **errors) for (i = 0; i < reds->num; ++i) if (reds->rules[i]->prec && reds->rules[i]->prec->prec && !bitset_disjoint_p (reds->lookaheads[i], lookaheadset)) - { - resolve_sr_conflict (s, i, errors); - break; - } + resolve_sr_conflict (s, i, errors); /* Loop over all rules which require lookahead in this state. Check for conflicts not resolved above. */ @@ -365,7 +366,7 @@ count_sr_conflicts (state *s) +`----------------------------------------------------------------*/ static int -count_rr_conflicts (state *s, int one_per_token) +count_rr_conflicts (state *s, bool one_per_token) { int i; reductions *reds = s->reductions; @@ -387,60 +388,20 @@ count_rr_conflicts (state *s, int one_per_token) } -/*--------------------------------------------------------------. -| Return a human readable string which reports shift/reduce and | -| reduce/reduce conflict numbers (SRC_NUM, RRC_NUM). | -`--------------------------------------------------------------*/ - -static const char * -conflict_report (int src_num, int rrc_num) -{ - static char res[4096]; - char *cp = res; - - if (src_num >= 1) - { - 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, " %s ", _("and")); - cp += strlen (cp); - } - - if (rrc_num >= 1) - { - sprintf (cp, ngettext ("%d reduce/reduce conflict", - "%d reduce/reduce conflicts", rrc_num), rrc_num); - cp += strlen (cp); - } - - *cp++ = '\0'; - - return res; -} - - -/*----------------------------------------------------------------. -| Same as above, but report the number of conflicts a` la POSIX. | -`----------------------------------------------------------------*/ +/*--------------------------------------------------------. +| Report the number of conflicts, using the Yacc format. | +`--------------------------------------------------------*/ static void -conflict_report_yacc (int src_num, int rrc_num) +conflict_report (FILE *out, int src_num, int rrc_num) { - /* If invoked with `--yacc', use the output format specified by - POSIX. */ - fprintf (stderr, _("conflicts: ")); - if (src_num > 0) - fprintf (stderr, _(" %d shift/reduce"), src_num); - if (src_num > 0 && rrc_num > 0) - fprintf (stderr, ","); - if (rrc_num > 0) - fprintf (stderr, _(" %d reduce/reduce"), rrc_num); - putc ('\n', stderr); + if (src_num && rrc_num) + fprintf (out, _("conflicts: %d shift/reduce, %d reduce/reduce\n"), + src_num, rrc_num); + else if (src_num) + fprintf (out, _("conflicts: %d shift/reduce\n"), src_num); + else if (rrc_num) + fprintf (out, _("conflicts: %d reduce/reduce\n"), rrc_num); } @@ -458,10 +419,9 @@ conflicts_output (FILE *out) state *s = states[i]; if (conflicts[i]) { - fprintf (out, _("State %d contains "), i); - fprintf (out, "%s.\n", - conflict_report (count_sr_conflicts (s), - count_rr_conflicts (s, true))); + fprintf (out, _("State %d "), i); + conflict_report (out, count_sr_conflicts (s), + count_rr_conflicts (s, true)); printed_sth = true; } } @@ -504,7 +464,8 @@ conflicts_print (void) /* Is the number of SR conflicts OK? Either EXPECTED_CONFLICTS is not set, and then we want 0 SR, or else it is specified, in which case we want equality. */ - int src_ok = 0; + bool src_ok = false; + bool rrc_ok = false; int src_total = 0; int rrc_total = 0; @@ -521,28 +482,39 @@ conflicts_print (void) } } - src_ok = src_total == (expected_conflicts == -1 ? 0 : expected_conflicts); + if (! glr_parser && rrc_total > 0 && expected_rr_conflicts != -1) + { + warn (_("%%expect-rr applies only to GLR parsers")); + expected_rr_conflicts = -1; + } + + src_ok = + src_total == (expected_sr_conflicts == -1 ? 0 : expected_sr_conflicts); + rrc_ok = + rrc_total == (expected_rr_conflicts == -1 ? 0 : expected_rr_conflicts); - /* If there are no RR conflicts, and as many SR conflicts as + /* If there are as many RR conflicts and SR conflicts as expected, then there is nothing to report. */ - if (!rrc_total && src_ok) + if (rrc_ok && src_ok) return; /* Report the total number of conflicts on STDERR. */ - if (yacc_flag) - conflict_report_yacc (src_total, rrc_total); - else - warn ("%s", conflict_report (src_total, rrc_total)); + if (! yacc_flag) + fprintf (stderr, "%s: ", current_file); + conflict_report (stderr, src_total, rrc_total); - if (expected_conflicts != -1) + if (expected_sr_conflicts != -1 || expected_rr_conflicts != -1) { + int sr = expected_sr_conflicts == -1 ? 0 : expected_sr_conflicts; + int rr = expected_rr_conflicts == -1 ? 0 : expected_rr_conflicts; if (! src_ok) - complain (ngettext ("expected %d shift/reduce conflict", - "expected %d shift/reduce conflicts", - expected_conflicts), - expected_conflicts); - if (rrc_total) - complain (_("expected 0 reduce/reduce conflicts")); + warn (ngettext ("expected %d shift/reduce conflict", + "expected %d shift/reduce conflicts", + sr), sr); + if (! rrc_ok) + warn (ngettext ("expected %d reduce/reduce conflict", + "expected %d reduce/reduce conflicts", + rr), rr); } }