cex: suggest -Wcounterexamples when there are unexpected conflicts

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
commit 761d5225eea36167742b171e0a422775a166e11c
Author: Akim Demaille <[email protected]>
Date:   Wed Jun 10 08:11:56 2020 +0200

    cex: suggest -Wcounterexamples when there are unexpected conflicts
    
    Suggesting -Wcounterexamples when there are conflicts is probably not
    what the user wants.  If she knows her conflicts and has set
    %expect/%expect-rr appropriately, we shouldn't warn.
    
    The commit also swaps the counterexamples and the report of conflicts,
    into, IMHO, a more natural order: from
    
        Shift/reduce conflict on token B:
        1:    3 a: A .
        1:    8 y: A . B
        Example              A • B C
        First derivation     s ::=[ a ::=[ A • ] x ::=[ B C ] ]
        Example              A • B C
        Second derivation    s ::=[ y ::=[ A • B ] c ::=[ C ] ]
    
        input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
        input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
    
    to
    
        input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
        Shift/reduce conflict on token B:
        1:    3 a: A .
        1:    8 y: A . B
        Example              A • B C
        First derivation     s ::=[ a ::=[ A • ] x ::=[ B C ] ]
        Example              A • B C
        Second derivation    s ::=[ y ::=[ A • B ] c ::=[ C ] ]
    
        input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
    
    * src/conflicts.c (rule_conflicts_print): Rename as...
    (report_rule_expectation_mismatches): this.
    Move the handling of report_counterexamples to...
    (conflicts_print): Here.
    Display this warning when applicable.

diff --git a/src/conflicts.c b/src/conflicts.c
index 7becadb2..87811f1f 100644
--- a/src/conflicts.c
+++ b/src/conflicts.c
@@ -694,12 +694,12 @@ report_counterexamples (void)
       report_state_counterexamples (states[sn]);
 }
 
-/*------------------------------.
-| Reporting per-rule conflicts. |
-`------------------------------*/
+/*------------------------------------------------.
+| Report per-rule %expect/%expect-rr mismatches.  |
+`------------------------------------------------*/
 
 static void
-rule_conflicts_print (void)
+report_rule_expectation_mismatches (void)
 {
   for (rule_number i = 0; i < nrules; i += 1)
     {
@@ -723,8 +723,6 @@ rule_conflicts_print (void)
                       r->code, rr, expected_rr);
         }
     }
-  if (warning_is_enabled (Wcounterexamples))
-    report_counterexamples ();
 }
 
 /*---------------------------------.
@@ -734,7 +732,7 @@ rule_conflicts_print (void)
 void
 conflicts_print (void)
 {
-  rule_conflicts_print ();
+  report_rule_expectation_mismatches ();
 
   if (! glr_parser && expected_rr_conflicts != -1)
     {
@@ -742,8 +740,9 @@ conflicts_print (void)
       expected_rr_conflicts = -1;
     }
 
-  /* Screams for factoring, but almost useless because of the
-     different strings to translate.  */
+  bool has_unexpected_conflicts = false;
+  /* The following two blocks scream for factoring, but i18n support
+     would make it ugly.  */
   {
     int total = count_sr_conflicts ();
     /* If %expect is not used, but %expect-rr is, then expect 0 sr.  */
@@ -754,16 +753,22 @@ conflicts_print (void)
     if (expected != -1)
       {
         if (expected != total)
-          complain (NULL, complaint,
-                    _("shift/reduce conflicts: %d found, %d expected"),
-                    total, expected);
+          {
+            complain (NULL, complaint,
+                      _("shift/reduce conflicts: %d found, %d expected"),
+                      total, expected);
+            has_unexpected_conflicts = true;
+          }
       }
     else if (total)
-      complain (NULL, Wconflicts_sr,
-                ngettext ("%d shift/reduce conflict",
-                          "%d shift/reduce conflicts",
-                          total),
-                total);
+      {
+        complain (NULL, Wconflicts_sr,
+                  ngettext ("%d shift/reduce conflict",
+                            "%d shift/reduce conflicts",
+                            total),
+                  total);
+        has_unexpected_conflicts = true;
+      }
   }
 
   {
@@ -776,17 +781,29 @@ conflicts_print (void)
     if (expected != -1)
       {
         if (expected != total)
-          complain (NULL, complaint,
-                    _("reduce/reduce conflicts: %d found, %d expected"),
-                    total, expected);
+          {
+            complain (NULL, complaint,
+                      _("reduce/reduce conflicts: %d found, %d expected"),
+                      total, expected);
+            has_unexpected_conflicts = true;
+          }
       }
     else if (total)
-      complain (NULL, Wconflicts_rr,
-                ngettext ("%d reduce/reduce conflict",
-                          "%d reduce/reduce conflicts",
-                          total),
-                total);
+      {
+        complain (NULL, Wconflicts_rr,
+                  ngettext ("%d reduce/reduce conflict",
+                            "%d reduce/reduce conflicts",
+                            total),
+                  total);
+        has_unexpected_conflicts = true;
+      }
   }
+
+  if (warning_is_enabled (Wcounterexamples))
+    report_counterexamples ();
+  else if (has_unexpected_conflicts)
+    complain (NULL, Wother,
+              _("rerun with option '-Wcounterexamples' to generate conflict counterexamples"));
 }
 
 void
diff --git a/tests/conflicts.at b/tests/conflicts.at
index b6d92c5a..807a07c2 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -726,6 +726,7 @@ AT_BISON_OPTION_POPDEFS
 AT_BISON_CHECK([[-Dlr.type=canonical-lr -o input.c input.y]],
                [[0]], [[]],
 [[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([[input]])
 AT_PARSER_CHECK([[input]], [[1]], [[]],
@@ -736,6 +737,7 @@ AT_PARSER_CHECK([[input]], [[1]], [[]],
 AT_BISON_CHECK([[-Dlr.type=canonical-lr -Dparse.lac=full \
                  -o input.c input.y]], [[0]], [[]],
 [[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([[input]])
 AT_PARSER_CHECK([[input]], [[1]], [[]],
@@ -746,6 +748,7 @@ AT_PARSER_CHECK([[input]], [[1]], [[]],
 AT_BISON_CHECK([[-Dlr.type=ielr -Dparse.lac=full -o input.c input.y]],
                [[0]], [[]],
 [[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([[input]])
 AT_PARSER_CHECK([[input]], [[1]], [[]],
@@ -770,6 +773,7 @@ exp: exp OP exp | NUM;
 
 AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 
 # Check the contents of the report.
@@ -1014,6 +1018,7 @@ cond:
 
 AT_BISON_CHECK([-o input.c input.y], 0, [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 input.y:12.3-18: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -1118,6 +1123,7 @@ id : '0';
 
 AT_BISON_CHECK([-o input.c --report=all input.y], 0, [],
 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 input.y:4.6-8: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -1238,6 +1244,7 @@ exp: exp OP exp | NUM;
 
 AT_BISON_CHECK([-o input.c input.y], 1, [],
 [[input.y: error: shift/reduce conflicts: 1 found, 0 expected
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_CLEANUP
 
@@ -1274,6 +1281,7 @@ exp: exp OP exp | NUM;
 
 AT_BISON_CHECK([-o input.c input.y], 1, [],
 [[input.y: error: shift/reduce conflicts: 1 found, 2 expected
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_CLEANUP
 
@@ -1293,6 +1301,7 @@ a: 'a';
 
 AT_BISON_CHECK([-o input.c input.y], 1, [],
 [[input.y: error: reduce/reduce conflicts: 1 found, 0 expected
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_CLEANUP
 
@@ -1493,6 +1502,7 @@ e:   e '+' e
 
 AT_BISON_CHECK([-Wall -o input.c input.y], 0, [],
 [[input.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 input.y:1.1-5: warning: useless precedence and associativity for '+' [-Wprecedence]
 input.y:2.1-5: warning: useless precedence and associativity for '*' [-Wprecedence]
 ]])
@@ -1598,6 +1608,7 @@ reported_conflicts:
 AT_BISON_CHECK([[--report=all input.y]], 0, [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 input.y:12.5-20: warning: rule useless in parser due to conflicts [-Wother]
 input.y:20.5-20: warning: rule useless in parser due to conflicts [-Wother]
 input.y:21.4: warning: rule useless in parser due to conflicts [-Wother]
@@ -1756,6 +1767,7 @@ AT_CHECK([[cat input.y >> input-keep.y]])
 AT_BISON_CHECK([[input-keep.y]], 0, [],
 [[input-keep.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
 input-keep.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
+input-keep.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 input-keep.y:22.4: warning: rule useless in parser due to conflicts [-Wother]
 input-keep.y:26.16: warning: rule useless in parser due to conflicts [-Wother]
 input-keep.y:32.5-7: warning: rule useless in parser due to conflicts [-Wother]
@@ -1939,6 +1951,7 @@ exp: 'a' | 'a';
 AT_BISON_CHECK([[2.y]], [[0]], [],
 [[2.y: warning: %expect-rr applies only to GLR parsers [-Wother]
 2.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+2.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 2.y:3.12-14: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -1975,12 +1988,15 @@ B: ;
 AT_BISON_CHECK([[sr-rr.y]], [[0]], [[]],
 [[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+sr-rr.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_BISON_CHECK([[-Wno-conflicts-sr sr-rr.y]], [[0]], [[]],
 [[sr-rr.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+sr-rr.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_BISON_CHECK([[-Wno-conflicts-rr sr-rr.y]], [[0]], [[]],
 [[sr-rr.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+sr-rr.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 
 [
@@ -2049,6 +2065,7 @@ for gram in sr-rr sr rr; do
           fi
         } | sed -e "s/^/$file: /" > experr
         ]AT_BISON_CHECK([[-Wnone $file]], [[1]], [[]], [[experr]])[
+        echo "$file: error: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Werror=other]" >> experr
         ]AT_BISON_CHECK([[-Werror $file]], [[1]], [[]], [[experr]])[
       fi
     done
diff --git a/tests/counterexample.at b/tests/counterexample.at
index 8647e464..7d677cb8 100644
--- a/tests/counterexample.at
+++ b/tests/counterexample.at
@@ -44,7 +44,8 @@ y: A | A B;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token B:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+Shift/reduce conflict on token B:
 1:    3 a: A .
 1:    8 y: A . B
 Example              A • B C
@@ -52,7 +53,6 @@ First derivation     s ::=[ a ::=[ A • ] x ::=[ B C ] ]
 Example              A • B C
 Second derivation    s ::=[ y ::=[ A • B ] c ::=[ C ] ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -76,7 +76,8 @@ bc: B bc C | B C;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token B:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+Shift/reduce conflict on token B:
 1:    7 a: A .
 1:    5 b: . B
 Example              A • B C
@@ -84,7 +85,6 @@ First derivation     s ::=[ a ::=[ A • ] bc ::=[ B C ] ]
 Example              A • B C
 Second derivation    s ::=[ ac ::=[ A ac ::=[ b ::=[ • B ] ] C ] ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -109,7 +109,8 @@ xby: B | X xby Y;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token B:
+[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
+Shift/reduce conflict on token B:
 1:    4 x: . %empty
 1:    9 xby: . B
 Example              A • B y
@@ -125,7 +126,6 @@ First derivation     $accept ::=[ s ::=[ ax ::=[ A x ::=[ X x ::=[ • ] ] ] by
 Second example       A X • B Y $end
 Second derivation    $accept ::=[ s ::=[ A xby ::=[ X xby ::=[ • B ] Y ] ] $end ]
 
-input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
 input.y:5.4-9: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -150,7 +150,8 @@ bc: B C;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token C:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+Shift/reduce conflict on token C:
 2:    7 b: B .
 2:    9 bc: B . C
 First example        B • C D $end
@@ -158,7 +159,6 @@ First derivation     $accept ::=[ g ::=[ x ::=[ b ::=[ B • ] cd ::=[ C D ] ] ]
 Second example       B • C $end
 Second derivation    $accept ::=[ g ::=[ x ::=[ bc ::=[ B • C ] ] ] $end ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -181,7 +181,8 @@ y: A A B;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token A:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+Shift/reduce conflict on token A:
 1:    5 x: A .
 1:    6 y: A . A B
 First example        A • A $end
@@ -189,7 +190,6 @@ First derivation     $accept ::=[ s ::=[ s ::=[ t ::=[ x ::=[ A • ] ] ] t ::=[
 Second example       A • A B $end
 Second derivation    $accept ::=[ s ::=[ t ::=[ y ::=[ A • A B ] ] ] $end ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 ]])
 
 AT_CLEANUP
@@ -216,7 +216,8 @@ y: Y;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token A:
+[[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
+Shift/reduce conflict on token A:
 4:    3 r: b .
 4:    7 s: b . A xx y
 Example              b • A X X Y
@@ -232,7 +233,6 @@ First derivation     a ::=[ x ::=[ X • ] t ::=[ X xy ] ]
 Second example       A X • X
 Second derivation    a ::=[ t ::=[ A xx ::=[ X • X ] ] ]
 
-input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
 input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
 input.y:8.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
@@ -254,7 +254,8 @@ b : A | b;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Reduce/reduce conflict on token $end:
+[[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+Reduce/reduce conflict on token $end:
 4:    1 a: A b .
 4:    3 b: b .
 Example              A b •
@@ -262,7 +263,6 @@ First derivation     a ::=[ A b • ]
 Example              A b •
 Second derivation    a ::=[ A b ::=[ b • ] ]
 
-input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -284,7 +284,8 @@ b: D;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Reduce/reduce conflict on tokens A, C:
+[[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
+Reduce/reduce conflict on tokens A, C:
 2:    5 a: D .
 2:    6 b: D .
 First example        D • A $end
@@ -292,7 +293,6 @@ First derivation     $accept ::=[ s ::=[ a ::=[ D • ] A ] $end ]
 Second example       B D • A $end
 Second derivation    $accept ::=[ s ::=[ B b ::=[ D • ] A ] $end ]
 
-input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
 input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -314,7 +314,8 @@ i: X | i J K;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token J:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+Shift/reduce conflict on token J:
 5:    2 a: H i .
 5:    4 i: i . J K
 time limit exceeded: XXX
@@ -323,7 +324,6 @@ First derivation     $accept ::=[ s ::=[ a ::=[ H i • ] J ] $end ]
 Second example       H i • J K $end
 Second derivation    $accept ::=[ a ::=[ H i ::=[ i • J K ] ] $end ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y:4.4-6: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -349,7 +349,8 @@ b: A B C | A B D;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token B:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+Shift/reduce conflict on token B:
 4:    7 a: A .
 4:    8 b: A . B C
 Example              N A • B C
@@ -357,7 +358,6 @@ First derivation     s ::=[ n ::=[ N a ::=[ A • ] B ] C ]
 Example              N A • B C
 Second derivation    s ::=[ n ::=[ N b ::=[ A • B C ] ] ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -384,7 +384,8 @@ C : A c A;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Reduce/reduce conflict on tokens b, c:
+[[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
+Reduce/reduce conflict on tokens b, c:
 3:    3 A: B .
 3:    5 A: . %empty
 Example              B • b A A c A
@@ -400,7 +401,6 @@ First derivation     S ::=[ C ::=[ A ::=[ C • ] c A ] B ::=[ A b A ] ]
 Example              C • c A b A
 Second derivation    S ::=[ C B ::=[ A ::=[ C ::=[ A ::=[ • ] c A ] ] b A ] ]
 
-input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
 ]])
 
 AT_CLEANUP
@@ -422,7 +422,9 @@ d : a | c A | d;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Reduce/reduce conflict on token A:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
+Reduce/reduce conflict on token A:
 0:    3 b: . %empty
 0:    4 c: . %empty
 First example        • c A A $end
@@ -489,8 +491,6 @@ First derivation     a ::=[ c d • ]
 Example              c d •
 Second derivation    a ::=[ c d ::=[ d • ] ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
-input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
 input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
 input.y:6.15: warning: rule useless in parser due to conflicts [-Wother]
 ]])
@@ -516,7 +516,8 @@ i: %empty | i J;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token J:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+Shift/reduce conflict on token J:
 7:    5 i: i J .
 7:    3 a: H i J . J
 Example              H i J • J J
@@ -524,7 +525,6 @@ First derivation     s ::=[ a ::=[ H i ::=[ i J • ] J J ] ]
 Example              H i J • J J
 Second derivation    s ::=[ a ::=[ H i J • J ] J ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y:5.13-15: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -551,7 +551,8 @@ d: D;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token D:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+Shift/reduce conflict on token D:
 3:    5 c: . %empty
 3:    6 d: . D
 Example              A a • D
@@ -559,7 +560,6 @@ First derivation     s ::=[ A a a ::=[ b ::=[ c ::=[ • ] ] ] d ::=[ D ] ]
 Example              A a • D
 Second derivation    s ::=[ A a d ::=[ • D ] ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 ]])
 
 AT_CLEANUP
@@ -584,7 +584,8 @@ d: D;
 ]])
 
 AT_BISON_CHECK_CEX([input.y], [], [],
-[[Shift/reduce conflict on token D:
+[[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+Shift/reduce conflict on token D:
 3:    5 c: . %empty
 3:    6 d: . D
 First example        A a • D E $end
@@ -592,7 +593,6 @@ First derivation     $accept ::=[ s ::=[ A a a ::=[ b ::=[ c ::=[ • ] ] ] d ::
 Second example       A a • D $end
 Second derivation    $accept ::=[ s ::=[ A a d ::=[ • D ] ] $end ]
 
-input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 ]])
 
 AT_CLEANUP
diff --git a/tests/existing.at b/tests/existing.at
index da6287d5..d0f6cb95 100644
--- a/tests/existing.at
+++ b/tests/existing.at
@@ -434,6 +434,7 @@ input.y:323.10: warning: empty rule without %empty [-Wempty-rule]
 ]AT_COND_CASE([[canonical LR]],
 [[input.y: warning: 265 shift/reduce conflicts [-Wconflicts-sr]]],
 [[input.y: warning: 65 shift/reduce conflicts [-Wconflicts-sr]]])[
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 input.y:39.1-5: warning: useless associativity for FUNC_CALL, use %precedence [-Wprecedence]
 input.y:44.1-5: warning: useless associativity for YNUMBER, use %precedence [-Wprecedence]
 input.y:44.1-5: warning: useless associativity for YSTRING, use %precedence [-Wprecedence]
@@ -1418,6 +1419,7 @@ input.y:591.18: warning: empty rule without %empty [-Wempty-rule]
 input.y: warning: 144 reduce/reduce conflicts [-Wconflicts-rr]]],
 [[input.y: warning: 78 shift/reduce conflicts [-Wconflicts-sr]
 input.y: warning: 10 reduce/reduce conflicts [-Wconflicts-rr]]])[
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 input.y:72.1-5: warning: useless associativity for HQUA, use %precedence [-Wprecedence]
 input.y:53.1-6: warning: useless associativity for HASSIGN, use %precedence [-Wprecedence]
 input.y:54.1-5: warning: useless associativity for HORELSE, use %precedence [-Wprecedence]
diff --git a/tests/glr-regression.at b/tests/glr-regression.at
index 8257088b..fede248d 100644
--- a/tests/glr-regression.at
+++ b/tests/glr-regression.at
@@ -89,6 +89,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr1.c -rall glr-regr1.y]], 0, [],
 [[glr-regr1.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
+glr-regr1.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr1])
 AT_PARSER_CHECK([[glr-regr1 BPBPB]], 0,
@@ -213,6 +214,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr2a.c -rall glr-regr2a.y]], 0, [],
 [[glr-regr2a.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
+glr-regr2a.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr2a])
 
@@ -348,6 +350,7 @@ AT_BISON_OPTION_POPDEFS
 AT_BISON_CHECK([[-o glr-regr3.c -rall glr-regr3.y]], 0, [],
 [[glr-regr3.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 glr-regr3.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
+glr-regr3.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr3])
 
@@ -444,6 +447,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr4.c -rall glr-regr4.y]], 0, [],
 [[glr-regr4.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
+glr-regr4.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr4])
 
@@ -501,6 +505,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr5.c -rall glr-regr5.y]], 0, [],
 [[glr-regr5.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+glr-regr5.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr5])
 
@@ -550,6 +555,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr6.c -rall glr-regr6.y]], 0, [],
 [[glr-regr6.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+glr-regr6.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr6])
 
@@ -640,6 +646,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr7.c -rall glr-regr7.y]], 0, [],
 [[glr-regr7.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
+glr-regr7.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr7])
 
@@ -730,6 +737,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr8.c -rall glr-regr8.y]], 0, [],
 [[glr-regr8.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+glr-regr8.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr8])
 
@@ -811,6 +819,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr9.c -rall glr-regr9.y]], 0, [],
 [[glr-regr9.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
+glr-regr9.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr9])
 
@@ -868,6 +877,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr10.c -rall glr-regr10.y]], 0, [],
 [[glr-regr10.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+glr-regr10.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr10])
 
@@ -927,6 +937,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr11.c -rall glr-regr11.y]], 0, [],
 [[glr-regr11.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+glr-regr11.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr11])
 
@@ -1049,6 +1060,7 @@ AT_BISON_OPTION_POPDEFS
 AT_BISON_CHECK([[-o glr-regr12.c -rall glr-regr12.y]], 0, [],
 [[glr-regr12.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 glr-regr12.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+glr-regr12.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr12])
 
@@ -1380,6 +1392,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr14.c -rall glr-regr14.y]], 0, [],
 [[glr-regr14.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
+glr-regr14.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr14])
 
@@ -1474,6 +1487,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr15.c -rall glr-regr15.y]], 0, [],
 [[glr-regr15.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
+glr-regr15.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr15])
 
@@ -1535,6 +1549,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr16.c -rall glr-regr16.y]], 0, [],
 [[glr-regr16.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+glr-regr16.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr16])
 
@@ -1610,6 +1625,7 @@ AT_BISON_OPTION_POPDEFS
 
 AT_BISON_CHECK([[-o glr-regr17.c -rall glr-regr17.y]], 0, [],
 [[glr-regr17.y: warning: 3 reduce/reduce conflicts [-Wconflicts-rr]
+glr-regr17.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([glr-regr17])
 
@@ -1703,6 +1719,7 @@ d: /* nada.  */;
 
 AT_BISON_CHECK([[-o input.c input.y]], 0, [],
 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]])
 AT_COMPILE([input])
 
diff --git a/tests/reduce.at b/tests/reduce.at
index 90dad835..e064cebc 100644
--- a/tests/reduce.at
+++ b/tests/reduce.at
@@ -1300,6 +1300,7 @@ dnl INPUT
 dnl BISON-STDERR
 [AT_COND_CASE([[LALR]],
 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 ]], [])],
 
 dnl TABLES
diff --git a/tests/sets.at b/tests/sets.at
index 76680f78..c8820d30 100644
--- a/tests/sets.at
+++ b/tests/sets.at
@@ -285,6 +285,7 @@ term: 'n'
 
 AT_BISON_CHECK([[-fcaret input.y]], [], [],
 [[input.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr]
+input.y: warning: rerun with option '-Wcounterexamples' to generate conflict counterexamples [-Wother]
 input.y:2.14-17: warning: rule useless in parser due to conflicts [-Wother]
     2 | expr: term | term | term | term | term | term
       |              ^~~~
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.