Re: [PATCH 8/8] cex: factor the definit ion of "•"

Akim Demaille <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
Good news!

> Le 14 juin 2020 à 10:25, Akim Demaille <[email protected]> a écrit :
> 
> Unfortunately we can't expect all the terminals to support "•", it is
> safer to use "." and to rely on Gettext to get the bullet when it's
> supported.
> 
> * src/gram.h, src/gram.c (dot): New.
> * src/derivation.c: Use it.
> * tests/counterexample.at, tests/report.at: Adjust the test suite.

Bruno Haible pointed me to gnulib's unicodeio module, which addresses our need.  So I am substituting this commit with the appended one.

Cheers!

commit 3fbbd4e4854789de54407d25727ee9536425ceb2
Author: Akim Demaille <[email protected]>
Date:   Sun Jun 14 09:13:39 2020 +0200

    cex: factor the definition of "•"
    
    Use of print_unicode_char suggested by Bruno Haible.
    https://lists.gnu.org/r/bug-gettext/2020-06/msg00012.html
    
    * src/gram.h (print_dot_fallback, print_dot): New.
    * src/gram.c, src/derivation.c: Use it.
    * tests/counterexample.at, tests/report.at: Adjust the test suite.

diff --git a/TODO b/TODO
index 875baeab..4f0d3c82 100644
--- a/TODO
+++ b/TODO
@@ -35,6 +35,12 @@ Unless we play it dumb (little structure).
 *** Doc
 -Wcounterexamples, --report=counterexamples
 
+Use "•" instead of ".".
+
+*** Conflict coverage
+Not all the conflicts have counterexamples generated.  See the "break"s in
+counterexample_report_state.
+
 ** Bistromathic
 - Hitting tab on a line with a syntax error is ugly
 
diff --git a/bootstrap.conf b/bootstrap.conf
index 453c4efb..d83c70d5 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -46,7 +46,7 @@ gnulib_modules='
   rename
   spawn-pipe stdbool stpcpy strdup-posix strerror strverscmp
   timevar
-  unistd unistd-safer unlink unlocked-io
+  unicodeio unistd unistd-safer unlink unlocked-io
   update-copyright unsetenv verify
   warnings
   winsz-ioctl
diff --git a/lib/.gitignore b/lib/.gitignore
index 0112ac05..d08e207a 100644
--- a/lib/.gitignore
+++ b/lib/.gitignore
@@ -150,6 +150,16 @@
 /hard-locale.h
 /hash.c
 /hash.h
+/iconv.c
+/iconv.in.h
+/iconv_close.c
+/iconv_open-aix.gperf
+/iconv_open-hpux.gperf
+/iconv_open-irix.gperf
+/iconv_open-osf.gperf
+/iconv_open-solaris.gperf
+/iconv_open-zos.gperf
+/iconv_open.c
 /intprops.h
 /inttypes.h
 /inttypes.in.h
@@ -327,11 +337,14 @@
 /timespec.h
 /timevar.c
 /timevar.h
+/unicodeio.c
+/unicodeio.h
 /unistd--.h
 /unistd-safer.h
 /unistd.c
 /unistd.h
 /unistd.in.h
+/unistr.in.h
 /unitypes.h
 /unitypes.in.h
 /uniwidth
@@ -340,6 +353,7 @@
 /unlink.c
 /unlocked-io.h
 /unsetenv.c
+/unused-parameter.h
 /vasnprintf.c
 /vasnprintf.h
 /vasprintf.c
diff --git a/m4/.gitignore b/m4/.gitignore
index eb775392..b5b86939 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -58,7 +58,10 @@
 /gnulib-tool.m4
 /host-cpu-c-abi.m4
 /iconv.m4
+/iconv_h.m4
+/iconv_open.m4
 /include_next.m4
+/inline.m4
 /intdiv0.m4
 /intl.m4
 /intldir.m4
@@ -193,6 +196,7 @@
 /timespec.m4
 /tls.m4
 /uintmax_t.m4
+/unicodeio.m4
 /unistd-safer.m4
 /unistd_h.m4
 /unlink.m4
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5b15e936..6b6d1e98 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -6,6 +6,7 @@ src/counterexample.c
 src/files.c
 src/fixits.c
 src/getargs.c
+src/gram.h
 src/gram.c
 src/graphviz.c
 src/i18n-strings.c
diff --git a/src/derivation.c b/src/derivation.c
index 14a8d852..fe00d3df 100644
--- a/src/derivation.c
+++ b/src/derivation.c
@@ -167,7 +167,7 @@ derivation_print_impl (const derivation *deriv, FILE *f,
   else if (deriv == &d_dot)
     {
       begin_use_class ("cex-dot", f);
-      fputs ("•", f);
+      print_dot (f);
       end_use_class ("cex-dot", f);
     }
   else // leaf.
diff --git a/src/gram.c b/src/gram.c
index 18f1b5e3..125eb035 100644
--- a/src/gram.c
+++ b/src/gram.c
@@ -67,7 +67,8 @@ item_print (item_number *item, rule const *previous_rule, FILE *out)
 
   for (item_number *sp = r->rhs; sp < item; sp++)
     fprintf (out, " %s", symbols[*sp]->tag);
-  fputs (" .", out);
+  putc (' ', out);
+  print_dot (out);
   if (0 <= *r->rhs)
     for (item_number *sp = item; 0 <= *sp; ++sp)
       fprintf (out, " %s", symbols[*sp]->tag);
diff --git a/src/gram.h b/src/gram.h
index 77fc7699..7f08e499 100644
--- a/src/gram.h
+++ b/src/gram.h
@@ -101,6 +101,10 @@
 
    Associativities are recorded similarly in SYMBOLS[I]->assoc.  */
 
+# include "system.h"
+
+# include <unicodeio.h>
+
 # include "location.h"
 # include "symtab.h"
 
@@ -213,6 +217,25 @@ typedef struct
 extern rule *rules;
 extern rule_number nrules;
 
+/* Fallback in case we can't print "•".  */
+static inline long
+print_dot_fallback (unsigned int code _GL_UNUSED,
+                    const char *msg _GL_UNUSED,
+                    void *callback_arg)
+{
+  FILE *out = (FILE *) callback_arg;
+  putc ('.', out);
+  return -1;
+}
+
+/* Print "•", the symbol used to represent a point in an item (aka, a
+   pointed rule).  */
+static inline void
+print_dot (FILE *out)
+{
+  unicode_to_mb (0x2022, fwrite_success_callback, print_dot_fallback, out);
+}
+
 /* Get the rule associated to this item.  ITEM points inside RITEM.  */
 rule const *item_rule (item_number const *item);
 
diff --git a/src/local.mk b/src/local.mk
index d96ecc45..aa716188 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -133,10 +133,15 @@ src_bison_LDADD =                               \
   $(ISNANL_LIBM)                                \
   $(LDEXPL_LIBM)                                \
   $(LDEXP_LIBM)                                 \
-  $(LIBINTL)                                    \
   $(LIBTHREAD)                                  \
   $(LIB_CLOCK_GETTIME)                          \
   $(LIB_GETHRXTIME)                             \
+  $(LIB_HARD_LOCALE)                            \
+  $(LIB_MBRTOWC)                                \
+  $(LIB_SETLOCALE_NULL)                         \
+  $(LIBICONV)                                   \
+  $(LIBINTL)                                    \
+  $(LIBREADLINE)                                \
   $(LIBTEXTSTYLE)
 
 
diff --git a/tests/atlocal.in b/tests/atlocal.in
index 38efc2a7..23eb9ae2 100644
--- a/tests/atlocal.in
+++ b/tests/atlocal.in
@@ -133,6 +133,7 @@ fi
 : ${PERL='@PERL@'}
 
 # Use simple quotes (lib/quote.c).
+# We have an LC_ALL=C pushed onto us via maint.mk.
 LC_CTYPE=C
 export LC_CTYPE
 
diff --git a/tests/conflicts.at b/tests/conflicts.at
index 3e061ad9..a3aadbff 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -864,10 +864,10 @@ State 5
     Shift/reduce conflict on token OP:
         1 exp: exp OP exp .
         1 exp: exp . OP exp
-      Example                  exp OP exp • OP exp
-      First derivation         exp ::=[ exp ::=[ exp OP exp • ] OP exp ]
-      Example                  exp OP exp • OP exp
-      Second derivation        exp ::=[ exp OP exp ::=[ exp • OP exp ] ]
+      Example                  exp OP exp . OP exp
+      First derivation         exp ::=[ exp ::=[ exp OP exp . ] OP exp ]
+      Example                  exp OP exp . OP exp
+      Second derivation        exp ::=[ exp OP exp ::=[ exp . OP exp ] ]
 
 ]])
 
@@ -1207,10 +1207,10 @@ State 1
     Reduce/reduce conflict on token $end:
         3 num: '0' .
         4 id: '0' .
-      Example                  '0' •
-      First derivation         exp ::=[ num ::=[ '0' • ] ]
-      Example                  '0' •
-      Second derivation        exp ::=[ id ::=[ '0' • ] ]
+      Example                  '0' .
+      First derivation         exp ::=[ num ::=[ '0' . ] ]
+      Example                  '0' .
+      Second derivation        exp ::=[ id ::=[ '0' . ] ]
 
 
 
@@ -1755,10 +1755,10 @@ State 4
     Shift/reduce conflict on token 'a':
        10 reported_conflicts: . %empty
         8 reported_conflicts: . 'a'
-      First example            resolved_conflict • 'a'
-      First derivation         start ::=[ resolved_conflict reported_conflicts ::=[ • ] 'a' ]
-      Second example           resolved_conflict • 'a' 'a'
-      Second derivation        start ::=[ resolved_conflict reported_conflicts ::=[ • 'a' ] 'a' ]
+      First example            resolved_conflict . 'a'
+      First derivation         start ::=[ resolved_conflict reported_conflicts ::=[ . ] 'a' ]
+      Second example           resolved_conflict . 'a' 'a'
+      Second derivation        start ::=[ resolved_conflict reported_conflicts ::=[ . 'a' ] 'a' ]
 
 
 
@@ -1774,10 +1774,10 @@ State 5
     Reduce/reduce conflict on token 'a':
         8 reported_conflicts: 'a' .
         9 reported_conflicts: 'a' .
-      Example                  'a' •
-      First derivation         reported_conflicts ::=[ 'a' • ]
-      Example                  'a' •
-      Second derivation        reported_conflicts ::=[ 'a' • ]
+      Example                  'a' .
+      First derivation         reported_conflicts ::=[ 'a' . ]
+      Example                  'a' .
+      Second derivation        reported_conflicts ::=[ 'a' . ]
 
 
 
@@ -1959,10 +1959,10 @@ AT_CHECK([[cat input.output | sed -n '/^State 0$/,/^State 1$/p']], 0,
     Reduce/reduce conflict on token 'c':
        12 empty_c2: . %empty
        13 empty_c3: . %empty
-      Example                  • 'c'
-      First derivation         start ::=[ empty_c2 ::=[ • ] 'c' ]
-      Example                  • 'c'
-      Second derivation        start ::=[ empty_c3 ::=[ • ] 'c' ]
+      Example                  . 'c'
+      First derivation         start ::=[ empty_c2 ::=[ . ] 'c' ]
+      Example                  . 'c'
+      Second derivation        start ::=[ empty_c3 ::=[ . ] 'c' ]
 
 
 
diff --git a/tests/counterexample.at b/tests/counterexample.at
index fa02990d..fd77e96e 100644
--- a/tests/counterexample.at
+++ b/tests/counterexample.at
@@ -46,10 +46,10 @@ y: A | A B;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 Shift/reduce conflict on token 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 ] ]
+  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]
 ]])
@@ -76,10 +76,10 @@ bc: B bc C | B C;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 Shift/reduce conflict on token B:
-  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 ] ]
+  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:6.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
@@ -107,16 +107,16 @@ xby: B | X xby Y;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
 Shift/reduce conflict on token B:
-  Example              A • B y
-  First derivation     s ::=[ ax ::=[ A x ::=[ • ] ] by ::=[ B y ] ]
-  Example              A • B
-  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:
-  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:5.4-9: warning: rule useless in parser due to conflicts [-Wother]
 ]])
@@ -144,10 +144,10 @@ bc: B C;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 Shift/reduce conflict on token 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:6.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
@@ -173,10 +173,10 @@ y: A A B;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 Shift/reduce conflict on token A:
-  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 ]
 
 ]])
 
@@ -206,16 +206,16 @@ y: Y;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
 Shift/reduce conflict on token A:
-  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 ] ] ]
+  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:
-  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:4.4: warning: rule useless in parser due to conflicts [-Wother]
 input.y:8.4: warning: rule useless in parser due to conflicts [-Wother]
@@ -240,21 +240,21 @@ b : A | b;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
 Reduce/reduce conflict on token $end:
-  Example              A b •
-  First derivation     a ::=[ A b • ]
-  Example              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:4.9: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
 AT_CLEANUP
 
-## ------------------------------- ##
-## Non-unifying R/R lr1 conflict.  ##
-## ------------------------------- ##
+## --------------------------------- ##
+## Non-unifying R/R LR(1) conflict.  ##
+## --------------------------------- ##
 
-AT_SETUP([Non-unifying R/R lr1 conflict])
+AT_SETUP([Non-unifying R/R LR(1) conflict])
 AT_KEYWORDS([cex])
 
 AT_DATA([[input.y]],
@@ -268,21 +268,21 @@ b: D;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
 Reduce/reduce conflict on tokens A, C:
-  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:5.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
 AT_CLEANUP
 
-## ------------------------------- ##
-## Non-unifying R/R lr2 conflict.  ##
-## ------------------------------- ##
+## --------------------------------- ##
+## Non-unifying R/R LR(2) conflict.  ##
+## --------------------------------- ##
 
-AT_SETUP([Non-unifying R/R lr2 conflict])
+AT_SETUP([Non-unifying R/R LR(2) conflict])
 AT_KEYWORDS([cex])
 
 AT_DATA([[input.y]],
@@ -297,10 +297,10 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 Shift/reduce conflict on token J:
 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:4.4-6: warning: rule useless in parser due to conflicts [-Wother]
 ]])
@@ -329,10 +329,10 @@ b: A B C | A B D;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 Shift/reduce conflict on token B:
-  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 ] ] ]
+  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:5.4: warning: rule useless in parser due to conflicts [-Wother]
 ]])
@@ -362,16 +362,16 @@ C : A c A;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
 Reduce/reduce conflict on tokens b, c:
-  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 ] ]
+  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:
-  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 ] ]
+  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 ] ]
 
 ]])
 
@@ -397,55 +397,55 @@ AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y: warning: 6 reduce/reduce conflicts [-Wconflicts-rr]
 Reduce/reduce conflict on token A:
-  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:
 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:
 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:
 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:
-  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:
-  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:
-  Example              b d •
-  First derivation     a ::=[ b d • ]
-  Example              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:
-  Example              c d •
-  First derivation     a ::=[ c d • ]
-  Example              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:5.4: warning: rule useless in parser due to conflicts [-Wother]
 input.y:6.15: warning: rule useless in parser due to conflicts [-Wother]
@@ -474,10 +474,10 @@ i: %empty | i J;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 Shift/reduce conflict on token 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 ]
+  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:5.13-15: warning: rule useless in parser due to conflicts [-Wother]
 ]])
@@ -507,10 +507,10 @@ d: D;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 Shift/reduce conflict on token 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 ] ]
+  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 ] ]
 
 ]])
 
@@ -538,10 +538,10 @@ d: D;
 AT_BISON_CHECK_CEX([input.y], [], [],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 Shift/reduce conflict on token 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 ]
 
 ]])
 
diff --git a/tests/report.at b/tests/report.at
index 67f3849c..bc2e5dbb 100644
--- a/tests/report.at
+++ b/tests/report.at
@@ -1240,12 +1240,12 @@ Nonterminals, with rules where they appear
 
 State 0
 
-    0 $accept: . exp $end
-    1 exp: . exp "⊕" exp
-    2    | . exp "+" exp
-    3    | . exp "+" exp
-    4    | . "number"
-    5    | . "Ñùṃéℝô"
+    0 $accept: • exp $end
+    1 exp: • exp "⊕" exp
+    2    | • exp "+" exp
+    3    | • exp "+" exp
+    4    | • "number"
+    5    | • "Ñùṃéℝô"
 
     "number"  shift, and go to state 1
     "Ñùṃéℝô"  shift, and go to state 2
@@ -1255,24 +1255,24 @@ State 0
 
 State 1
 
-    4 exp: "number" .
+    4 exp: "number" •
 
     $default  reduce using rule 4 (exp)
 
 
 State 2
 
-    5 exp: "Ñùṃéℝô" .
+    5 exp: "Ñùṃéℝô" •
 
     $default  reduce using rule 5 (exp)
 
 
 State 3
 
-    0 $accept: exp . $end
-    1 exp: exp . "⊕" exp
-    2    | exp . "+" exp
-    3    | exp . "+" exp
+    0 $accept: exp • $end
+    1 exp: exp • "⊕" exp
+    2    | exp • "+" exp
+    3    | exp • "+" exp
 
     $end  shift, and go to state 4
     "+"   shift, and go to state 5
@@ -1281,20 +1281,20 @@ State 3
 
 State 4
 
-    0 $accept: exp $end .
+    0 $accept: exp $end •
 
     $default  accept
 
 
 State 5
 
-    1 exp: . exp "⊕" exp
-    2    | . exp "+" exp
-    2    | exp "+" . exp
-    3    | . exp "+" exp
-    3    | exp "+" . exp
-    4    | . "number"
-    5    | . "Ñùṃéℝô"
+    1 exp: • exp "⊕" exp
+    2    | • exp "+" exp
+    2    | exp "+" • exp
+    3    | • exp "+" exp
+    3    | exp "+" • exp
+    4    | • "number"
+    5    | • "Ñùṃéℝô"
 
     "number"  shift, and go to state 1
     "Ñùṃéℝô"  shift, and go to state 2
@@ -1304,12 +1304,12 @@ State 5
 
 State 6
 
-    1 exp: . exp "⊕" exp
-    1    | exp "⊕" . exp
-    2    | . exp "+" exp
-    3    | . exp "+" exp
-    4    | . "number"
-    5    | . "Ñùṃéℝô"
+    1 exp: • exp "⊕" exp
+    1    | exp "⊕" • exp
+    2    | • exp "+" exp
+    3    | • exp "+" exp
+    4    | • "number"
+    5    | • "Ñùṃéℝô"
 
     "number"  shift, and go to state 1
     "Ñùṃéℝô"  shift, and go to state 2
@@ -1319,11 +1319,11 @@ State 6
 
 State 7
 
-    1 exp: exp . "⊕" exp
-    2    | exp . "+" exp
-    2    | exp "+" exp .  [$end, "+", "⊕"]
-    3    | exp . "+" exp
-    3    | exp "+" exp .  [$end, "+", "⊕"]
+    1 exp: exp • "⊕" exp
+    2    | exp • "+" exp
+    2    | exp "+" exp •  [$end, "+", "⊕"]
+    3    | exp • "+" exp
+    3    | exp "+" exp •  [$end, "+", "⊕"]
 
     "⊕"  shift, and go to state 6
 
@@ -1338,24 +1338,24 @@ State 7
     Conflict between rule 2 and token "+" resolved as reduce (%left "+").
 
     Shift/reduce conflict on token "⊕":
-        2 exp: exp "+" exp .
-        1 exp: exp . "⊕" exp
+        2 exp: exp "+" exp •
+        1 exp: exp • "⊕" exp
       Example                  exp "+" exp • "⊕" exp
       First derivation         exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
       Example                  exp "+" exp • "⊕" exp
       Second derivation        exp ::=[ exp "+" exp ::=[ exp • "⊕" exp ] ]
 
     Reduce/reduce conflict on tokens $end, "+", "⊕":
-        2 exp: exp "+" exp .
-        3 exp: exp "+" exp .
+        2 exp: exp "+" exp •
+        3 exp: exp "+" exp •
       Example                  exp "+" exp •
       First derivation         exp ::=[ exp "+" exp • ]
       Example                  exp "+" exp •
       Second derivation        exp ::=[ exp "+" exp • ]
 
     Shift/reduce conflict on token "⊕":
-        3 exp: exp "+" exp .
-        1 exp: exp . "⊕" exp
+        3 exp: exp "+" exp •
+        1 exp: exp • "⊕" exp
       Example                  exp "+" exp • "⊕" exp
       First derivation         exp ::=[ exp ::=[ exp "+" exp • ] "⊕" exp ]
       Example                  exp "+" exp • "⊕" exp
@@ -1365,10 +1365,10 @@ State 7
 
 State 8
 
-    1 exp: exp . "⊕" exp
-    1    | exp "⊕" exp .  [$end, "+", "⊕"]
-    2    | exp . "+" exp
-    3    | exp . "+" exp
+    1 exp: exp • "⊕" exp
+    1    | exp "⊕" exp •  [$end, "+", "⊕"]
+    2    | exp • "+" exp
+    3    | exp • "+" exp
 
     "+"  shift, and go to state 5
     "⊕"  shift, and go to state 6
@@ -1378,8 +1378,8 @@ State 8
     $default  reduce using rule 1 (exp)
 
     Shift/reduce conflict on token "⊕":
-        1 exp: exp "⊕" exp .
-        1 exp: exp . "⊕" exp
+        1 exp: exp "⊕" exp •
+        1 exp: exp • "⊕" exp
       Example                  exp "⊕" exp • "⊕" exp
       First derivation         exp ::=[ exp ::=[ exp "⊕" exp • ] "⊕" exp ]
       Example                  exp "⊕" exp • "⊕" exp
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.