cex: color the counterexamples

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
Hi all,

This is only a proposal.  I'll install it unless there is resistance in the near future, but I'm open with changing things afterwards.

This is what I get on the dangling else example:

https://www.lrde.epita.fr/~akim/private/bison/bison-cex-color-2.png

Instead of alternating the examples and derivations (keep in mind this is colored, see the URL above):

> Example              "if" exp "then" exp "else" exp • "+" exp
> First derivation     exp ::=[ exp ::=[ "if" exp "then" exp "else" exp • ] "+" exp ]
> Example              "if" exp "then" exp "else" exp • "+" exp
> Second derivation    exp ::=[ "if" exp "then" exp "else" exp ::=[ exp • "+" exp ] ]

maybe we should put both examples one after the other, two make it easier to catch the differences, 

> First derivation     exp ::=[ exp ::=[ "if" exp "then" exp "else" exp • ] "+" exp ]
> Example              "if" exp "then" exp "else" exp • "+" exp
> Example              "if" exp "then" exp "else" exp • "+" exp
> Second derivation    exp ::=[ "if" exp "then" exp "else" exp ::=[ exp • "+" exp ] ]

or both derivations, 

> Example              "if" exp "then" exp "else" exp • "+" expFirst derivation     exp ::=[ exp ::=[ "if" exp "then" exp "else" exp • ] "+" exp ]
> Second derivation    exp ::=[ "if" exp "then" exp "else" exp ::=[ exp • "+" exp ] ]
> Example              "if" exp "then" exp "else" exp • "+" exp


or both bothes:

> Example              "if" exp "then" exp "else" exp • "+" exp
> Example              "if" exp "then" exp "else" exp • "+" exp

> First derivation     exp ::=[ exp ::=[ "if" exp "then" exp "else" exp • ] "+" exp ]
> Second derivation    exp ::=[ "if" exp "then" exp "else" exp ::=[ exp • "+" exp ] ]

commit d5f2063d51b30e2c5571301e771dea63f10889cc
Author: Akim Demaille <[email protected]>
Date:   Sat May 23 19:13:01 2020 +0200

    cex: color the counterexamples
    
    Use colors to show the counterexamples and the derivations in color,
    to highlight their structure.  Align the outputs, and add i18n
    support. Reduce width by using a one-space separator instead of
    two-space.
    
    From
    
        Example  A  •  B  C
        First  derivation  s ::=[ a ::=[ A  • ]  x ::=[ B  C ] ]
        Second derivation  s ::=[ y ::=[ A  •  B ]  c ::=[ C ] ]
    
    to
    
        Example              A • B C
        First derivation     s ::=[ a ::=[ A • ] x ::=[ B C ] ]
        Example              A • B C
        Second derivation    s ::=[ y ::=[ A • B ] c ::=[ C ] ]
    
    with colors.
    
    * data/bison-default.css (cex-dot, cex-0, cex-1, cex-2, cex-3, cex-4)
    (cex-5, cex-6, cex-7, cex-step, cex-leaf): New.
    * src/derivation.c (derivation_print_styled_impl): New.
    (derivation_print, derivation_print_leaves): Use it.
    * src/counterexample.c: Reformat the output.
    * tests/counterexample.at: Adjust.

diff --git a/data/bison-default.css b/data/bison-default.css
index 17b9b657..2652e03f 100644
--- a/data/bison-default.css
+++ b/data/bison-default.css
@@ -30,5 +30,28 @@
 /* "Sections" in traces (--trace).  */
 .trace0    { color: green; }
 
+/* Syntax error messages.  */
 .expected   { color: green; }
 .unexpected { color: red; }
+
+
+/* Counterexamples.  */
+
+/* Cex: point in rule.  */
+.cex-dot { color: red; }
+
+/* Cex: coloring various rules.  */
+.cex-0   { color: yellow; }
+.cex-1   { color: green; }
+.cex-2   { color: blue; }
+.cex-3   { color: cobalt; }
+.cex-4   { color: violet; }
+.cex-5   { color: orange; }
+.cex-6   { color: brown; }
+.cex-7   { color: mauve; }
+
+/* Cex: derivation rewriting steps.  */
+.cex-step { font-style: italic; }
+
+/* Cex: leaves of a derivation.  */
+.cex-leaf { font-weight: 600; }
diff --git a/src/counterexample.c b/src/counterexample.c
index ebef6d5d..5b6c1d36 100644
--- a/src/counterexample.c
+++ b/src/counterexample.c
@@ -103,21 +103,18 @@ static void
 print_counterexample (counterexample *cex)
 {
   FILE *out = stderr;
-  if (cex->unifying)
-    fprintf (out, "Example  ");
-  else
-    fprintf (out, "First  Example ");
+
+  fprintf (out, "%-20s ", cex->unifying ? _("Example") : _("First example"));
   derivation_print_leaves (cex->d1, out);
-  fprintf (out, "\nFirst  derivation ");
+  fprintf (out, "%-20s ", _("First derivation"));
   derivation_print (cex->d1, out);
-  if (!cex->unifying)
-    {
-      fprintf (out, "\nSecond Example ");
-      derivation_print_leaves (cex->d2, out);
-    }
-  fprintf (out, "\nSecond derivation ");
+
+  fprintf (out, "%-20s ", cex->unifying ? _("Example") : _("Second example"));
+  derivation_print_leaves (cex->d2, out);
+  fprintf (out, "%-20s ", _("Second derivation"));
   derivation_print (cex->d2, out);
-  fputs ("\n\n", out);
+
+  fputc ('\n', out);
 }
 
 /*
diff --git a/src/derivation.c b/src/derivation.c
index 2f6a81e5..cc5145e5 100644
--- a/src/derivation.c
+++ b/src/derivation.c
@@ -18,11 +18,13 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
+
+#include "derivation.h"
+
 #include <gl_linked_list.h>
 
 #include "system.h"
-
-#include "derivation.h"
+#include "complain.h"
 
 struct derivation
 {
@@ -124,57 +126,72 @@ derivation_size (const derivation *deriv)
   return size;
 }
 
-// these are used rarely enough that I don't think they should be interned.
-void
-derivation_print (const derivation *deriv, FILE *f)
+/* Print DERIV, colored according to COUNTER.  */
+static void
+derivation_print_impl (const derivation *deriv, FILE *f,
+                       bool leaves_only,
+                       int *counter)
 {
-  if (deriv == &d_dot)
+  if (deriv->children)
     {
-      fputs (" •", f);
-      return;
+      const symbol *sym = symbols[deriv->sym];
+      char style[20];
+      snprintf (style, 20, "cex-%d", *counter);
+      ++*counter;
+      begin_use_class (style, f);
+
+      if (!leaves_only)
+        {
+          begin_use_class ("cex-step", f);
+          fprintf (f, "%s ::=[ ", sym->tag);
+          end_use_class ("cex-step", f);
+        }
+      const char *sep = "";
+      derivation *child;
+      for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
+           derivation_list_next (&it, &child);
+           )
+        {
+          fputs (sep, f);
+          sep = " ";
+          derivation_print_impl (child, f, leaves_only, counter);
+        }
+      if (!leaves_only)
+        {
+          begin_use_class ("cex-step", f);
+          fputs (" ]", f);
+          end_use_class ("cex-step", f);
+        }
+      end_use_class (style, f);
     }
-  symbol *sym = symbols[deriv->sym];
-  if (!deriv->children)
+  else if (deriv == &d_dot)
     {
-      fprintf (f, " %s", sym->tag);
-      return;
+      begin_use_class ("cex-dot", f);
+      fputs ("•", f);
+      end_use_class ("cex-dot", f);
     }
-
-  fprintf (f, " %s ::=[", sym->tag);
-  derivation *child;
-  for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
-       derivation_list_next (&it, &child);
-       )
+  else // leaf.
     {
-      derivation_print (child, f);
-      fputs (" ", f);
+      const symbol *sym = symbols[deriv->sym];
+      begin_use_class ("cex-leaf", f);
+      fprintf (f, "%s", sym->tag);
+      end_use_class ("cex-leaf", f);
     }
-  fputs ("]", f);
 }
 
 void
-derivation_print_leaves (const derivation *deriv, FILE *f)
+derivation_print (const derivation *deriv, FILE *f)
 {
-  if (deriv == &d_dot)
-    {
-      fputs ("•", f);
-      return;
-    }
-  if (!deriv->children)
-    {
-      symbol *sym = symbols[deriv->sym];
-      fprintf (f, "%s", sym->tag);
-      return;
-    }
+  int counter = 0;
+  derivation_print_impl (deriv, f, false, &counter);
+  fputc ('\n', f);
+}
 
-  const char *sep = "";
-  derivation *child;
-  for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
-       derivation_list_next (&it, &child);
-       )
-    {
-      fputs (sep, f);
-      sep = "  ";
-      derivation_print_leaves (child, f);
-    }
+
+void
+derivation_print_leaves (const derivation *deriv, FILE *f)
+{
+  int counter = 0;
+  derivation_print_impl (deriv, f, true, &counter);
+  fputc ('\n', f);
 }
diff --git a/src/derivation.h b/src/derivation.h
index 397a5be6..78714047 100644
--- a/src/derivation.h
+++ b/src/derivation.h
@@ -20,6 +20,7 @@
 #ifndef DERIVATION_H
 # define DERIVATION_H
 
+# include <gl_linked_list.h>
 # include <gl_xlist.h>
 
 # include "gram.h"
diff --git a/tests/counterexample.at b/tests/counterexample.at
index 6d9d5a8e..7c176636 100644
--- a/tests/counterexample.at
+++ b/tests/counterexample.at
@@ -47,9 +47,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[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 ] ]
-Second derivation  s ::=[ y ::=[ A  •  B ]  c ::=[ C ] ]
+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]
@@ -78,9 +79,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Shift/reduce conflict on token B:
 1:    7 a: A .
 1:    5 b: . B
-Example  A  •  B  C
-First  derivation  s ::=[ a ::=[ A  • ]  bc ::=[ B  C ] ]
-Second derivation  s ::=[ ac ::=[ A  ac ::=[ b ::=[ •  B ] ]  C ] ]
+Example              A • B C
+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]
@@ -110,17 +112,18 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Shift/reduce conflict on token B:
 1:    4 x: . %empty
 1:    9 xby: . B
-Example  A  •  B  y
-First  derivation  s ::=[ ax ::=[ A  x ::=[ • ] ]  by ::=[ B  y ] ]
-Second derivation  s ::=[ A  xby ::=[ •  B ] ]
+Example              A • B y
+First derivation     s ::=[ ax ::=[ A x ::=[ • ] ] by ::=[ B y ] ]
+Example              A • B
+Second derivation    s ::=[ A xby ::=[ • B ] ]
 
 Shift/reduce conflict on token B:
 5:    4 x: . %empty
 5:    9 xby: . B
-First  Example A  X  •  B  y  $end
-First  derivation  $accept ::=[ s ::=[ ax ::=[ A  x ::=[ X  x ::=[ • ] ] ]  by ::=[ B  y ] ]  $end ]
-Second Example A  X  •  B  Y  $end
-Second derivation  $accept ::=[ s ::=[ A  xby ::=[ X  xby ::=[ •  B ]  Y ] ]  $end ]
+First example        A X • B y $end
+First derivation     $accept ::=[ s ::=[ ax ::=[ A x ::=[ X x ::=[ • ] ] ] by ::=[ B y ] ] $end ]
+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,10 +153,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Shift/reduce conflict on token C:
 2:    7 b: B .
 2:    9 bc: B . C
-First  Example B  •  C  D  $end
-First  derivation  $accept ::=[ g ::=[ x ::=[ b ::=[ B  • ]  cd ::=[ C  D ] ] ]  $end ]
-Second Example B  •  C  $end
-Second derivation  $accept ::=[ g ::=[ x ::=[ bc ::=[ B  •  C ] ] ]  $end ]
+First example        B • C D $end
+First derivation     $accept ::=[ g ::=[ x ::=[ b ::=[ B • ] cd ::=[ C D ] ] ] $end ]
+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,10 +184,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Shift/reduce conflict on token A:
 1:    5 x: A .
 1:    6 y: A . A B
-First  Example A  •  A  $end
-First  derivation  $accept ::=[ s ::=[ s ::=[ t ::=[ x ::=[ A  • ] ] ]  t ::=[ x ::=[ A ] ] ]  $end ]
-Second Example A  •  A  B  $end
-Second derivation  $accept ::=[ s ::=[ t ::=[ y ::=[ A  •  A  B ] ] ]  $end ]
+First example        A • A $end
+First derivation     $accept ::=[ s ::=[ s ::=[ t ::=[ x ::=[ A • ] ] ] t ::=[ x ::=[ A ] ] ] $end ]
+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]
 ]])
@@ -216,17 +219,18 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Shift/reduce conflict on token A:
 4:    3 r: b .
 4:    7 s: b . A xx y
-Example  b  •  A  X  X  Y
-First  derivation  a ::=[ r ::=[ b  • ]  t ::=[ A  x ::=[ X ]  xy ::=[ X  Y ] ] ]
-Second derivation  a ::=[ s ::=[ b  •  xx ::=[ A  X  X ]  y ::=[ Y ] ] ]
+Example              b • A X X Y
+First derivation     a ::=[ r ::=[ b • ] t ::=[ A x ::=[ X ] xy ::=[ X Y ] ] ]
+Example              b • A X X Y
+Second derivation    a ::=[ s ::=[ b • xx ::=[ A X X ] y ::=[ Y ] ] ]
 
 Shift/reduce conflict on token X:
 10:    8 x: X .
 10:    9 xx: X . X
-First  Example X  •  X  xy
-First  derivation  a ::=[ x ::=[ X  • ]  t ::=[ X  xy ] ]
-Second Example A  X  •  X
-Second derivation  a ::=[ t ::=[ A  xx ::=[ X  •  X ] ] ]
+First example        X • X xy
+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]
@@ -253,9 +257,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Reduce/reduce conflict on token $end:
 4:    1 a: A b .
 4:    3 b: b .
-Example  A  b  •
-First  derivation  a ::=[ A  b  • ]
-Second derivation  a ::=[ A  b ::=[ b  • ] ]
+Example              A b •
+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]
@@ -282,10 +287,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Reduce/reduce conflict on tokens A, C:
 2:    5 a: D .
 2:    6 b: D .
-First  Example D  •  A  $end
-First  derivation  $accept ::=[ s ::=[ a ::=[ D  • ]  A ]  $end ]
-Second Example B  D  •  A  $end
-Second derivation  $accept ::=[ s ::=[ B  b ::=[ D  • ]  A ]  $end ]
+First example        D • A $end
+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]
@@ -313,10 +318,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 5:    2 a: H i .
 5:    4 i: i . J K
 time limit exceeded: XXX
-First  Example H  i  •  J  $end
-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 ]
+First example        H i • J $end
+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]
@@ -347,9 +352,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Shift/reduce conflict on token B:
 4:    7 a: A .
 4:    8 b: A . B C
-Example  N  A  •  B  C
-First  derivation  s ::=[ n ::=[ N  a ::=[ A  • ]  B ]  C ]
-Second derivation  s ::=[ n ::=[ N  b ::=[ A  •  B  C ] ] ]
+Example              N A • B C
+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]
@@ -381,16 +387,18 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Reduce/reduce conflict on tokens b, c:
 3:    3 A: B .
 3:    5 A: . %empty
-Example  B  •  b  A  A  c  A
-First  derivation  S ::=[ B ::=[ A ::=[ B  • ]  b  A ]  C ::=[ A  c  A ] ]
-Second derivation  S ::=[ B  C ::=[ A ::=[ B ::=[ A ::=[ • ]  b  A ] ]  c  A ] ]
+Example              B • b A A c A
+First derivation     S ::=[ B ::=[ A ::=[ B • ] b A ] C ::=[ A c A ] ]
+Example              B • b A c A
+Second derivation    S ::=[ B C ::=[ A ::=[ B ::=[ A ::=[ • ] b A ] ] c A ] ]
 
 Reduce/reduce conflict on tokens b, c:
 4:    4 A: C .
 4:    5 A: . %empty
-Example  C  •  c  A  A  b  A
-First  derivation  S ::=[ C ::=[ A ::=[ C  • ]  c  A ]  B ::=[ A  b  A ] ]
-Second derivation  S ::=[ C  B ::=[ A ::=[ C ::=[ A ::=[ • ]  c  A ] ]  b  A ] ]
+Example              C • c A A b A
+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]
 ]])
@@ -417,67 +425,69 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Reduce/reduce conflict on token A:
 0:    3 b: . %empty
 0:    4 c: . %empty
-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 ]
+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:
 2:    3 b: . %empty
 2:    4 c: . %empty
 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 ]
+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:
 3:    3 b: . %empty
 3:    4 c: . %empty
 time limit exceeded: XXX
-First  Example c  •  c  A  A  $end
-First  derivation  $accept ::=[ a ::=[ c  d ::=[ a ::=[ b ::=[ • ]  d ::=[ c  A  A ] ] ] ]  $end ]
-Second Example c  •  A  $end
-Second derivation  $accept ::=[ a ::=[ c  d ::=[ c ::=[ • ]  A ] ]  $end ]
+First example        c • c A A $end
+First derivation     $accept ::=[ a ::=[ c d ::=[ a ::=[ b ::=[ • ] d ::=[ c A A ] ] ] ] $end ]
+Second example       c • A $end
+Second derivation    $accept ::=[ a ::=[ c d ::=[ c ::=[ • ] A ] ] $end ]
 
 Shift/reduce conflict on token A:
 6:    3 b: . %empty
 6:    6 d: c . A
 time limit exceeded: XXX
-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
-Second derivation  a ::=[ b  d ::=[ c  •  A ] ]
+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
+Second derivation    a ::=[ b d ::=[ c • A ] ]
 
 Reduce/reduce conflict on token A:
 6:    3 b: . %empty
 6:    4 c: . %empty
-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
-Second derivation  $accept ::=[ a ::=[ b  d ::=[ a ::=[ c  d ::=[ c ::=[ • ]  A ] ] ] ]  $end ]
+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
+Second derivation    $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ c ::=[ • ] A ] ] ] ] $end ]
 
 Shift/reduce conflict on token A:
 6:    4 c: . %empty
 6:    6 d: c . A
-First  Example b  c  •  A  $end
-First  derivation  $accept ::=[ a ::=[ b  d ::=[ a ::=[ c  d ::=[ c ::=[ • ]  A ] ] ] ]  $end ]
-Second Example b  c  •  A
-Second derivation  a ::=[ b  d ::=[ c  •  A ] ]
+First example        b c • A $end
+First derivation     $accept ::=[ a ::=[ b d ::=[ a ::=[ c d ::=[ c ::=[ • ] A ] ] ] ] $end ]
+Second example       b c • A
+Second derivation    a ::=[ b d ::=[ c • A ] ]
 
 Reduce/reduce conflict on token $end:
 7:    1 a: b d .
 7:    7 d: d .
-Example  b  d  •
-First  derivation  a ::=[ b  d  • ]
-Second derivation  a ::=[ b  d ::=[ d  • ] ]
+Example              b d •
+First derivation     a ::=[ b d • ]
+Example              b d •
+Second derivation    a ::=[ b d ::=[ d • ] ]
 
 Reduce/reduce conflict on token $end:
 8:    2 a: c d .
 8:    7 d: d .
-Example  c  d  •
-First  derivation  a ::=[ c  d  • ]
-Second derivation  a ::=[ c  d ::=[ d  • ] ]
+Example              c d •
+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]
@@ -509,9 +519,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Shift/reduce conflict on token J:
 7:    5 i: i J .
 7:    3 a: H i J . J
-Example  H  i  J  •  J  J
-First  derivation  s ::=[ a ::=[ H  i ::=[ i  J  • ]  J  J ] ]
-Second derivation  s ::=[ a ::=[ H  i  J  •  J ]  J ]
+Example              H i J • J J
+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]
@@ -543,9 +554,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Shift/reduce conflict on token D:
 3:    5 c: . %empty
 3:    6 d: . D
-Example  A  a  •  D
-First  derivation  s ::=[ A  a  a ::=[ b ::=[ c ::=[ • ] ] ]  d ::=[ D ] ]
-Second derivation  s ::=[ A  a  d ::=[ •  D ] ]
+Example              A a • D
+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]
 ]])
@@ -575,10 +587,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[Shift/reduce conflict on token D:
 3:    5 c: . %empty
 3:    6 d: . D
-First  Example A  a  •  D  E  $end
-First  derivation  $accept ::=[ s ::=[ A  a  a ::=[ b ::=[ c ::=[ • ] ] ]  d ::=[ D ]  E ]  $end ]
-Second Example A  a  •  D  $end
-Second derivation  $accept ::=[ s ::=[ A  a  d ::=[ •  D ] ]  $end ]
+First example        A a • D E $end
+First derivation     $accept ::=[ s ::=[ A a a ::=[ b ::=[ c ::=[ • ] ] ] d ::=[ D ] E ] $end ]
+Second example       A a • D $end
+Second derivation    $accept ::=[ s ::=[ A a d ::=[ • D ] ] $end ]
 
 input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 ]])
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.