]> git.saurik.com Git - bison.git/blobdiff - src/conflicts.c
* src/conflicts.c (conflicts_print): Correct format string typo:
[bison.git] / src / conflicts.c
index fcfa735d18ea0a24150d6a5770ff3c022b69334d..2edd1e8b3b981dfdec7936820cb88bbee52a1115 100644 (file)
@@ -1,6 +1,6 @@
 /* Find and resolve or report look-ahead conflicts for bison,
 
 /* 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.
    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. */
 #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;
 
 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))
     {
 
   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))
   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.  */
 
   /* 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
 +`----------------------------------------------------------------*/
 
 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;
 {
   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
 
 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])
        {
       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;
        }
     }
          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.  */
   /* 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;
 
   int src_total = 0;
   int rrc_total = 0;
@@ -521,24 +482,40 @@ 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;
+    }
 
 
-  /* If there are no RR conflicts, and as many SR conflicts as
+  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 as many RR conflicts and SR conflicts as
      expected, then there is nothing to report.  */
      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.  */
     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 && !src_ok)
-    complain (ngettext ("expected %d shift/reduce conflict",
+  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)
+       warn (ngettext ("expected %d shift/reduce conflict",
                        "expected %d shift/reduce conflicts",
                        "expected %d shift/reduce conflicts",
-                       expected_conflicts),
-             expected_conflicts);
+                       sr), sr);
+      if (! rrc_ok)
+       warn (ngettext ("expected %d reduce/reduce conflict",
+                       "expected %d reduce/reduce conflicts",
+                       rr), rr);
+    }
 }
 
 
 }