[PATCH 2/6] cex: use usual routines for diagnostics about R/R conflicts

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
This is more consistent, and brings benefits: users know that these
diagnostics are attached to -Wcounterexamples, and they can also click
on the hyperlink if permitted by their terminal.

We go from

    warning: 1 reduce/reduce conflict [-Wconflicts-rr]
    Reduce/reduce conflict on token $end:
      Example              A b .
      First derivation     a -> [ A b . ]
      Second derivation    a -> [ A b -> [ b . ] ]

to

    warning: 1 reduce/reduce conflict [-Wconflicts-rr]
    input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
      Example              A b .
      First derivation     a -> [ A b . ]
      Second derivation    a -> [ A b -> [ b . ] ]

with an hyperlink on -Wcounterexamples.

* src/counterexample.c (counterexample_report_reduce_reduce):
Use complain.
* tests/counterexample.at, tests/diagnostics.at, tests/report.at:
Adjust.
---
 src/counterexample.c    | 34 +++++++++++++++++++++++++---------
 tests/conflicts.at      |  6 +++---
 tests/counterexample.at | 40 ++++++++++++++++++++--------------------
 tests/diagnostics.at    |  2 +-
 tests/report.at         |  4 ++--
 5 files changed, 51 insertions(+), 35 deletions(-)

diff --git a/src/counterexample.c b/src/counterexample.c
index 1f690d3a..90a1739e 100644
--- a/src/counterexample.c
+++ b/src/counterexample.c
@@ -1265,27 +1265,43 @@ counterexample_report_reduce_reduce (state_item_number itm1, state_item_number i
                                      FILE *out, const char *prefix)
 {
   {
-    fputs (prefix, out);
-    fputs (ngettext ("Reduce/reduce conflict on token",
-                     "Reduce/reduce conflict on tokens",
-                     bitset_count (conflict_syms)), out);
+    struct obstack obstack;
+    obstack_init (&obstack);
     bitset_iterator biter;
     state_item_number sym;
-    const char *sep = " ";
+    const char *sep = "";
     BITSET_FOR_EACH (biter, conflict_syms, sym, 0)
       {
-        fprintf (out, "%s%s", sep, symbols[sym]->tag);
+        obstack_printf (&obstack, "%s%s", sep, symbols[sym]->tag);
         sep = ", ";
       }
-    fputs (_(":\n"), out);
+    char *tokens = obstack_finish0 (&obstack);
+    if (out == stderr)
+      complain (NULL, Wcounterexamples,
+                ngettext ("reduce/reduce conflict on token %s",
+                          "reduce/reduce conflict on tokens %s",
+                          bitset_count (conflict_syms)),
+                tokens);
+    else
+      {
+        fputs (prefix, out);
+        fprintf (out,
+                 ngettext ("reduce/reduce conflict on token %s",
+                           "reduce/reduce conflict on tokens %s",
+                           bitset_count (conflict_syms)),
+                 tokens);
+        fprintf (out, "%s\n", _(":"));
+      }
+    obstack_free (&obstack, NULL);
   }
   // In the report, print the items.
-  if (*prefix || trace_flag & trace_cex)
+  if (out != stderr || trace_flag & trace_cex)
     {
       print_state_item (&state_items[itm1], out, prefix);
       print_state_item (&state_items[itm2], out, prefix);
     }
-  counterexample_report (itm1, itm2, bitset_first (conflict_syms), false, out, prefix);
+  counterexample_report (itm1, itm2, bitset_first (conflict_syms),
+                         false, out, prefix);
 }
 
 static state_item_number
diff --git a/tests/conflicts.at b/tests/conflicts.at
index 794c7795..529f7406 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -1209,7 +1209,7 @@ State 1
     $end      [reduce using rule 4 (id)]
     $default  reduce using rule 3 (num)
 
-    Reduce/reduce conflict on token $end:
+    reduce/reduce conflict on token $end:
         3 num: '0' .
         4 id: '0' .
       Example                  '0' .
@@ -1803,7 +1803,7 @@ State 5
     'a'       [reduce using rule 9 (reported_conflicts)]
     $default  reduce using rule 8 (reported_conflicts)
 
-    Reduce/reduce conflict on token 'a':
+    reduce/reduce conflict on token 'a':
         8 reported_conflicts: 'a' .
         9 reported_conflicts: 'a' .
       Example                  'a' .
@@ -1993,7 +1993,7 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
     Conflict between rule 10 and token 'b' resolved as an error (%nonassoc 'b').
     Conflict between rule 11 and token 'c' resolved as an error (%nonassoc 'c').
 
-    Reduce/reduce conflict on token 'c':
+    reduce/reduce conflict on token 'c':
        12 empty_c2: . %empty
        13 empty_c3: . %empty
       Example                  . 'c'
diff --git a/tests/counterexample.at b/tests/counterexample.at
index 2b85d061..270e511e 100644
--- a/tests/counterexample.at
+++ b/tests/counterexample.at
@@ -389,7 +389,7 @@ b : A | b;
 
 AT_BISON_CHECK_CEX(
 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
-Reduce/reduce conflict on token $end:
+input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
   Example              A b .
   First derivation
     a
@@ -402,7 +402,7 @@ Reduce/reduce conflict on token $end:
 input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
-Reduce/reduce conflict on token $end:
+input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
   Example              A b .
   First derivation     a -> [ A b . ]
   Second derivation    a -> [ A b -> [ b . ] ]
@@ -428,7 +428,7 @@ b: D;
 
 AT_BISON_CHECK_CEX(
 [[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
-Reduce/reduce conflict on tokens A, C:
+input.y: warning: reduce/reduce conflict on tokens A, C [-Wcounterexamples]
   First example        D . A $end
   First derivation
     $accept
@@ -445,7 +445,7 @@ Reduce/reduce conflict on tokens A, C:
 input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
-Reduce/reduce conflict on tokens A, C:
+input.y: warning: reduce/reduce conflict on tokens A, C [-Wcounterexamples]
   First example        D . A $end
   First derivation     $accept -> [ s -> [ a -> [ D . ] A ] $end ]
   Second example       B D . A $end
@@ -589,7 +589,7 @@ C : A c A;
 
 AT_BISON_CHECK_CEX(
 [[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
-Reduce/reduce conflict on tokens b, c:
+input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
   Example              B . b c
   First derivation
     S
@@ -604,7 +604,7 @@ Reduce/reduce conflict on tokens b, c:
                   `-> A     b A
                       `-> .   `-> %empty
 
-Reduce/reduce conflict on tokens b, c:
+input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
   Example              C . c b
   First derivation
     S
@@ -621,12 +621,12 @@ Reduce/reduce conflict on tokens b, c:
 
 ]],
 [[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
-Reduce/reduce conflict on tokens b, c:
+input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
   Example              B . b c
   First derivation     S -> [ B -> [ A -> [ B . ] b A -> [ ] ] C -> [ A -> [ ] c A -> [ ] ] ]
   Second derivation    S -> [ B C -> [ A -> [ B -> [ A -> [ . ] b A -> [ ] ] ] c A -> [ ] ] ]
 
-Reduce/reduce conflict on tokens b, c:
+input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
   Example              C . c b
   First derivation     S -> [ C -> [ A -> [ C . ] c A -> [ ] ] B -> [ A -> [ ] b A -> [ ] ] ]
   Second derivation    S -> [ C B -> [ A -> [ C -> [ A -> [ . ] c A -> [ ] ] ] b A -> [ ] ] ]
@@ -653,7 +653,7 @@ d : a | c A | d;
 AT_BISON_CHECK_CEX(
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
-Reduce/reduce conflict on token A:
+input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
   First example        . c A A $end
   First derivation
     $accept
@@ -667,7 +667,7 @@ Reduce/reduce conflict on token A:
         `-> c     d
             `-> . `-> c A A
 
-Reduce/reduce conflict on token A:
+input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
 time limit exceeded: XXX
   First example        b . c A A $end
   First derivation
@@ -685,7 +685,7 @@ time limit exceeded: XXX
               `-> c     A
                   `-> .
 
-Reduce/reduce conflict on token A:
+input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
 time limit exceeded: XXX
   First example        c . c A A $end
   First derivation
@@ -721,7 +721,7 @@ time limit exceeded: XXX
                             `-> b     d
                                 `-> . `-> c A A
 
-Reduce/reduce conflict on token A:
+input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
   First example        b c . c A A $end
   First derivation
     $accept
@@ -758,7 +758,7 @@ Shift/reduce conflict on token A:
                         `-> c     A
                             `-> .
 
-Reduce/reduce conflict on token $end:
+input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
   Example              b d .
   First derivation
     a
@@ -768,7 +768,7 @@ Reduce/reduce conflict on token $end:
     `-> b d
           `-> d .
 
-Reduce/reduce conflict on token $end:
+input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
   Example              c d .
   First derivation
     a
@@ -783,20 +783,20 @@ input.y:6.15: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
-Reduce/reduce conflict on token A:
+input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
   First example        . c A A $end
   First derivation     $accept -> [ a -> [ b -> [ . ] d -> [ c A A ] ] $end ]
   Second example       . c A A $end
   Second derivation    $accept -> [ a -> [ c -> [ . ] d -> [ c A A ] ] $end ]
 
-Reduce/reduce conflict on token A:
+input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
 time limit exceeded: XXX
   First example        b . c A A $end
   First derivation     $accept -> [ a -> [ b d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] $end ]
   Second example       b . A $end
   Second derivation    $accept -> [ a -> [ b d -> [ c -> [ . ] A ] ] $end ]
 
-Reduce/reduce conflict on token A:
+input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
 time limit exceeded: XXX
   First example        c . c A A $end
   First derivation     $accept -> [ a -> [ c d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] $end ]
@@ -810,7 +810,7 @@ time limit exceeded: XXX
   Second example       b c . c A A $end
   Reduce derivation    $accept -> [ a -> [ b d -> [ a -> [ c d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] ] ] $end ]
 
-Reduce/reduce conflict on token A:
+input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
   First example        b c . c A A $end
   First derivation     $accept -> [ a -> [ b d -> [ a -> [ c d -> [ a -> [ b -> [ . ] d -> [ c A A ] ] ] ] ] ] $end ]
   Second example       b c . A $end
@@ -822,12 +822,12 @@ Shift/reduce conflict on token A:
   Second example       b c . A $end
   Reduce derivation    $accept -> [ a -> [ b d -> [ a -> [ c d -> [ c -> [ . ] A ] ] ] ] $end ]
 
-Reduce/reduce conflict on token $end:
+input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
   Example              b d .
   First derivation     a -> [ b d . ]
   Second derivation    a -> [ b d -> [ d . ] ]
 
-Reduce/reduce conflict on token $end:
+input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
   Example              c d .
   First derivation     a -> [ c d . ]
   Second derivation    a -> [ c d -> [ d . ] ]
diff --git a/tests/diagnostics.at b/tests/diagnostics.at
index 61803c44..47581049 100644
--- a/tests/diagnostics.at
+++ b/tests/diagnostics.at
@@ -621,7 +621,7 @@ input.y:31.4: <warning>warning:</warning> empty rule without %empty [<warning>-W
       |    <warning>^</warning>
       |    <fixit-insert>%empty</fixit-insert>
 input.y: <error>error:</error> reduce/reduce conflicts: 1 found, 0 expected
-Reduce/reduce conflict on token "X":
+input.y: <warning>warning:</warning> reduce/reduce conflict on token "X" [<warning>-Wcounterexamples</warning>]
   Example              <cex-0><cex-1><cex-2><cex-3><cex-leaf>"X"</cex-leaf> <cex-dot>•</cex-dot></cex-3></cex-2></cex-1><cex-4></cex-4><cex-5><cex-6><cex-7><cex-8><cex-9><cex-10> <cex-leaf>"X"</cex-leaf></cex-10></cex-9></cex-8><cex-11> <cex-leaf>"quuux"</cex-leaf></cex-11></cex-7></cex-6></cex-5><cex-12><cex-13><cex-14> <cex-leaf>"X"</cex-leaf></cex-14></cex-13></cex-12></cex-0>
   First derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
diff --git a/tests/report.at b/tests/report.at
index 9aa1c7be..ea00d0ad 100644
--- a/tests/report.at
+++ b/tests/report.at
@@ -1548,7 +1548,7 @@ Shift/reduce conflict on token "⊕":
     ↳ exp             "⊕" exp
       ↳ exp "+" exp •
 
-Reduce/reduce conflict on tokens $end, "+", "⊕":
+input.y: warning: reduce/reduce conflict on tokens $end, "+", "⊕" [-Wcounterexamples]
   Example              exp "+" exp •
   First derivation
     exp
@@ -1758,7 +1758,7 @@ State 7
         ↳ exp             "⊕" exp
           ↳ exp "+" exp •
 
-    Reduce/reduce conflict on tokens $end, "+", "⊕":
+    reduce/reduce conflict on tokens $end, "+", "⊕":
         2 exp: exp "+" exp •
         3 exp: exp "+" exp •
       Example                  exp "+" exp •
-- 
2.27.0
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.