bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 5/5] cex: display the rule numbers


From: Akim Demaille
Subject: [PATCH 5/5] cex: display the rule numbers
Date: Wed, 29 Jul 2020 06:46:56 +0200

From

    Example: "if" expr "then" "if" expr "then" stmt • "else" stmt
    Shift derivation
      if_stmt
      ↳ "if" expr "then" stmt
                         ↳ if_stmt
                           ↳ "if" expr "then" stmt • "else" stmt
    Reduce derivation
      if_stmt
      ↳ "if" expr "then" stmt                        "else" stmt
                         ↳ if_stmt
                           ↳ "if" expr "then" stmt •

to

    Example: "if" expr "then" "if" expr "then" stmt • "else" stmt
    Shift derivation
      if_stmt
      ↳ 3: "if" expr "then" stmt
                            ↳ 2: if_stmt
                                 ↳ 4: "if" expr "then" stmt • "else" stmt
    Example: "if" expr "then" "if" expr "then" stmt • "else" stmt
    Reduce derivation
      if_stmt
      ↳ 4: "if" expr "then" stmt                              "else" stmt
                            ↳ 2: if_stmt
                                 ↳ 3: "if" expr "then" stmt •

* src/state-item.h, src/state-item.c (state_item_rule): New.
* src/derivation.h, src/derivation.c (struct derivation): Add a rule
member.
Adjust dependencies.
* src/counterexample.c, src/parse-simulation.c: Pass the rule to
derivation_new.
* src/derivation.c (fprintf_if): New.
(derivation_width, derivation_print_tree_impl): Take the rule number
into account.

* tests/conflicts.at, tests/counterexample.at, tests/diagnostics.at,
* tests/report.at: Adjust.
---
 src/counterexample.c    |   5 +-
 src/derivation.c        |  28 ++-
 src/derivation.h        |   7 +-
 src/parse-simulation.c  |   6 +-
 src/state-item.c        |   6 +
 src/state-item.h        |   1 +
 tests/conflicts.at      |  44 ++---
 tests/counterexample.at | 370 ++++++++++++++++++++--------------------
 tests/diagnostics.at    |  66 +++----
 tests/report.at         |  88 +++++-----
 10 files changed, 330 insertions(+), 291 deletions(-)

diff --git a/src/counterexample.c b/src/counterexample.c
index cdf3f218..c0dc796c 100644
--- a/src/counterexample.c
+++ b/src/counterexample.c
@@ -293,7 +293,8 @@ expand_to_conflict (state_item_number start, symbol_number 
conflict_sym)
             derivation_list_append (result, derivation_new_leaf (*i));
           symbol_number lhs =
             rules[item_number_as_rule_number (*i)].lhs->number;
-          derivation *deriv = derivation_new (lhs, result);
+          derivation *deriv = derivation_new (lhs, result,
+                                              state_item_rule (si));
           result = derivation_list_new ();
           derivation_list_append (result, deriv);
         }
@@ -427,7 +428,7 @@ complete_diverging_example (symbol_number conflict_sym,
             derivation_list_prepend (result, derivation_new_leaf (*i));
         }
       // completing the derivation
-      derivation *new_deriv = derivation_new (r->lhs->number, result);
+      derivation *new_deriv = derivation_new (r->lhs->number, result, r);
       result = derivation_list_new ();
       derivation_list_append (result, new_deriv);
     }
diff --git a/src/derivation.c b/src/derivation.c
index 9772cabd..030cc17b 100644
--- a/src/derivation.c
+++ b/src/derivation.c
@@ -25,6 +25,7 @@
 #include <c-ctype.h>
 #include <gl_linked_list.h>
 #include <mbswidth.h>
+#include <vasnprintf.h>
 
 #include "system.h"
 #include "complain.h"
@@ -34,13 +35,15 @@ struct derivation
   symbol_number sym;
   derivation_list children;
   int reference_count;
+  // The rule SYM -> CHILDREN.
+  const rule *rule;
   // Color assigned for styling.  Guarantees that the derivation is
   // always displayed with the same color, independently of the order
   // in which the derivations are traversed.
   int color;
 };
 
-static derivation d_dot = { -1, NULL, -1, -1 };
+static derivation d_dot = { -1, NULL, -1, NULL, -1 };
 
 derivation *
 derivation_dot (void)
@@ -74,12 +77,14 @@ void derivation_list_free (derivation_list dl)
 }
 
 derivation *
-derivation_new (symbol_number sym, derivation_list children)
+derivation_new (symbol_number sym, derivation_list children,
+                const rule *r)
 {
   derivation *res = xmalloc (sizeof *res);
   res->sym = sym;
   res->children = children;
   res->reference_count = 0;
+  res->rule = r;
   res->color = -1;
   return res;
 }
@@ -211,6 +216,23 @@ fputs_if (bool cond, FILE *out, int *padding, const char 
*s)
   return res;
 }
 
+static int
+fprintf_if (bool cond, FILE *out, int *padding, const char *fmt, ...)
+{
+  char buf[256];
+  size_t len = sizeof (buf);
+  va_list args;
+  va_start (args, fmt);
+  char *cp = vasnprintf (buf, &len, fmt, args);
+  va_end (args);
+  if (!cp)
+    xalloc_die ();
+  int res = fputs_if (cond, out, padding, cp);
+  if (cp != buf)
+    free (cp);
+  return res;
+}
+
 // The width taken to report this derivation recursively down to its
 // leaves.
 static int
@@ -223,6 +245,7 @@ derivation_width (const derivation *deriv)
 
       // Arrow and space.
       int children_width = down_arrow_width;
+      children_width += snprintf (NULL, 0, "%d: ", deriv->rule->number);
       if (gl_list_size (deriv->children) == 0)
         // Empty rhs.
         children_width += empty_width;
@@ -287,6 +310,7 @@ derivation_print_tree_impl (const derivation *deriv, FILE 
*out,
       else
         {
           res += fputs_if (depth == 1, out, padding, down_arrow);
+          res += fprintf_if (depth == 1, out, padding, "%d: ", 
deriv->rule->number);
           if (gl_list_size (deriv->children) == 0)
             // Empty rhs.
             res += fputs_if (depth == 1, out, padding, empty);
diff --git a/src/derivation.h b/src/derivation.h
index 4dfba945..3f376642 100644
--- a/src/derivation.h
+++ b/src/derivation.h
@@ -54,11 +54,14 @@ void derivation_list_append (derivation_list dl, derivation 
*d);
 void derivation_list_prepend (derivation_list dl, derivation *d);
 void derivation_list_free (derivation_list dl);
 
-derivation *derivation_new (symbol_number sym, derivation_list children);
+// rule_num is the number of the rule SYM -> CHILDREN.
+derivation *
+derivation_new (symbol_number sym, derivation_list children,
+                const rule *r);
 
 static inline derivation *derivation_new_leaf (symbol_number sym)
 {
-  return derivation_new (sym, NULL);
+  return derivation_new (sym, NULL, NULL);
 }
 
 // Number of symbols.
diff --git a/src/parse-simulation.c b/src/parse-simulation.c
index ba09c44c..764a62e0 100644
--- a/src/parse-simulation.c
+++ b/src/parse-simulation.c
@@ -421,7 +421,9 @@ nullable_closure (parse_state *ps, state_item *si, 
parse_state_list state_list)
       state_item *nsi = &state_items[sin];
       current_ps = copy_parse_state (false, current_ps);
       ps_si_append (current_ps, nsi);
-      ps_derivs_append (current_ps, derivation_new (sp, derivation_list_new 
()));
+      ps_derivs_append (current_ps,
+                        derivation_new (sp, derivation_list_new (),
+                                        state_item_rule (nsi)));
       parse_state_list_append (state_list, current_ps);
     }
 }
@@ -516,7 +518,7 @@ simulate_reduction (parse_state *ps, int rule_len, bitset 
symbol_set)
   state_item *si = (state_item *) ps->state_items.tail_elt;
   const rule *r = item_rule (si->item);
   symbol_number lhs = r->lhs->number;
-  derivation *deriv = derivation_new (lhs, popped_derivs);
+  derivation *deriv = derivation_new (lhs, popped_derivs, state_item_rule 
(si));
   --new_root->depth;
   ps_derivs_append (new_root, deriv);
 
diff --git a/src/state-item.c b/src/state-item.c
index a0c5a31a..a56be1f2 100644
--- a/src/state-item.c
+++ b/src/state-item.c
@@ -482,6 +482,12 @@ state_item_print (const state_item *si, FILE *out, const 
char *prefix)
   putc ('\n', out);
 }
 
+const rule*
+state_item_rule (const state_item *si)
+{
+  return item_rule (si->item);
+}
+
 /**
  * Report the state_item graph
  */
diff --git a/src/state-item.h b/src/state-item.h
index a0a3d36f..bfe9f8be 100644
--- a/src/state-item.h
+++ b/src/state-item.h
@@ -93,6 +93,7 @@ void state_items_init (void);
 void state_items_free (void);
 
 void state_item_print (const state_item *si, FILE *out, const char *prefix);
+const rule *state_item_rule (const state_item *si);
 
 bool production_allowed (const state_item *si, const state_item *next);
 
diff --git a/tests/conflicts.at b/tests/conflicts.at
index 2b6f4315..f103a4e1 100644
--- a/tests/conflicts.at
+++ b/tests/conflicts.at
@@ -867,12 +867,12 @@ State 5
       Example: exp OP exp . OP exp
       Shift derivation
         exp
-        `-> exp OP exp
-                   `-> exp . OP exp
+        `-> 1: exp OP exp
+                      `-> 1: exp . OP exp
       Reduce derivation
         exp
-        `-> exp              OP exp
-            `-> exp OP exp .
+        `-> 1: exp                 OP exp
+               `-> 1: exp OP exp .
 
 ]])
 
@@ -1215,12 +1215,12 @@ State 1
       Example: '0' .
       First reduce derivation
         exp
-        `-> num
-            `-> '0' .
+        `-> 1: num
+               `-> 3: '0' .
       Second reduce derivation
         exp
-        `-> id
-            `-> '0' .
+        `-> 2: id
+               `-> 4: '0' .
 
 
 
@@ -1770,13 +1770,13 @@ State 4
       First example: resolved_conflict . 'a' 'a'
       Shift derivation
         start
-        `-> resolved_conflict reported_conflicts 'a'
-                              `-> . 'a'
+        `-> 1: resolved_conflict reported_conflicts 'a'
+                                 `-> 8: . 'a'
       Second example: resolved_conflict . 'a'
       Reduce derivation
         start
-        `-> resolved_conflict reported_conflicts 'a'
-                              `-> .
+        `-> 1: resolved_conflict reported_conflicts 'a'
+                                 `-> 10: .
 
     shift/reduce conflict on token 'a':
        10 reported_conflicts: . %empty
@@ -1784,13 +1784,13 @@ State 4
       First example: resolved_conflict . 'a' 'a'
       Shift derivation
         start
-        `-> resolved_conflict reported_conflicts 'a'
-                              `-> . 'a'
+        `-> 1: resolved_conflict reported_conflicts 'a'
+                                 `-> 9: . 'a'
       Second example: resolved_conflict . 'a'
       Reduce derivation
         start
-        `-> resolved_conflict reported_conflicts 'a'
-                              `-> .
+        `-> 1: resolved_conflict reported_conflicts 'a'
+                                 `-> 10: .
 
 
 
@@ -1809,10 +1809,10 @@ State 5
       Example: 'a' .
       First reduce derivation
         reported_conflicts
-        `-> 'a' .
+        `-> 8: 'a' .
       Second reduce derivation
         reported_conflicts
-        `-> 'a' .
+        `-> 9: 'a' .
 
 
 
@@ -1999,12 +1999,12 @@ AT_CHECK([[cat input.output | sed -n '/^State 
0$/,/^State 1$/p']], 0,
       Example: . 'c'
       First reduce derivation
         start
-        `-> empty_c2 'c'
-            `-> .
+        `-> 7: empty_c2  'c'
+               `-> 12: .
       Second reduce derivation
         start
-        `-> empty_c3 'c'
-            `-> .
+        `-> 8: empty_c3  'c'
+               `-> 13: .
 
 
 
diff --git a/tests/counterexample.at b/tests/counterexample.at
index 4d1709a6..bd9c1e96 100644
--- a/tests/counterexample.at
+++ b/tests/counterexample.at
@@ -58,12 +58,12 @@ input.y: warning: shift/reduce conflict on token B 
[-Wcounterexamples]
   Example: A . B C
   Shift derivation
     s
-    `-> y         c
-        `-> A . B `-> C
+    `-> 2: y            c
+           `-> 8: A . B `-> 4: C
   Reduce derivation
     s
-    `-> a       x
-        `-> A . `-> B C
+    `-> 1: a          x
+           `-> 3: A . `-> 6: B C
 input.y:4.4: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
@@ -98,29 +98,29 @@ input.y: warning: shift/reduce conflict on token B 
[-Wcounterexamples]
   Example: A . B C
   Shift derivation
     s
-    `-> ac
-        `-> A ac          C
-              `-> b
-                  `-> . B
+    `-> 1: ac
+           `-> 3: A ac                C
+                    `-> 4: b
+                           `-> 5: . B
   Reduce derivation
     s
-    `-> a       bc
-        `-> A . `-> B C
+    `-> 2: a          bc
+           `-> 7: A . `-> 10: B C
 input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
   Example: A A . B B C C
   Shift derivation
     s
-    `-> ac
-        `-> A ac                        C
-              `-> A ac                C
-                    `-> b
-                        `-> . b
-                              `-> B B
+    `-> 1: ac
+           `-> 3: A ac                                    C
+                    `-> 3: A ac                         C
+                             `-> 4: b
+                                    `-> 6: . b
+                                             `-> 5: B B
   Reduce derivation
     s
-    `-> a             bc
-        `-> A a       `-> B bc      C
-              `-> A .       `-> B C
+    `-> 2: a                   bc
+           `-> 8: A a          `-> 9: B bc          C
+                    `-> 7: A .          `-> 10: B C
 input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
@@ -160,29 +160,29 @@ input.y: warning: shift/reduce conflict on token B 
[-Wcounterexamples]
   Example: A . B
   Shift derivation
     s
-    `-> A xby
-          `-> . B
+    `-> 2: A xby
+             `-> 9: . B
   Reduce derivation
     s
-    `-> ax          by
-        `-> A x     `-> B y
-              `-> .       `-> %empty
+    `-> 1: ax                by
+           `-> 3: A x        `-> 6: B y
+                    `-> 4: .          `-> 6: %empty
 input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
   First example: A X . B Y $end
   Shift derivation
     $accept
-    `-> s                     $end
-        `-> A xby
-              `-> X xby     Y
-                    `-> . B
+    `-> 0: s                               $end
+           `-> 2: A xby
+                    `-> 10: X xby        Y
+                              `-> 9: . B
   Second example: A X . B y $end
   Reduce derivation
     $accept
-    `-> s                             $end
-        `-> ax                by
-            `-> A x           `-> B y
-                  `-> X x
-                        `-> .
+    `-> 0: s                                            $end
+           `-> 1: ax                         by
+                  `-> 3: A x                 `-> 6: B y
+                           `-> 5: X x
+                                    `-> 4: .
 input.y:5.4-9: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
@@ -223,17 +223,17 @@ input.y: warning: shift/reduce conflict on token C 
[-Wcounterexamples]
   First example: B . C $end
   Shift derivation
     $accept
-    `-> g                 $end
-        `-> x
-            `-> bc
-                `-> B . C
+    `-> 0: g                          $end
+           `-> 2: x
+                  `-> 6: bc
+                         `-> 9: B . C
   Second example: B . C D $end
   Reduce derivation
     $accept
-    `-> g                       $end
-        `-> x
-            `-> b       cd
-                `-> B . `-> C D
+    `-> 0: g                                   $end
+           `-> 2: x
+                  `-> 5: b          cd
+                         `-> 7: B . `-> 8: C D
 input.y:6.4: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
@@ -268,18 +268,18 @@ input.y: warning: shift/reduce conflict on token A 
[-Wcounterexamples]
   First example: A . A B $end
   Shift derivation
     $accept
-    `-> s                   $end
-        `-> t
-            `-> y
-                `-> A . A B
+    `-> 0: s                            $end
+           `-> 1: t
+                  `-> 4: y
+                         `-> 6: A . A B
   Second example: A . A $end
   Reduce derivation
     $accept
-    `-> s                             $end
-        `-> s               t
-            `-> t           `-> x
-                `-> x           `-> A
-                    `-> A .
+    `-> 0: s                                               $end
+           `-> 2: s                        t
+                  `-> 1: t                 `-> 3: x
+                         `-> 3: x                 `-> 5: A
+                                `-> 5: A .
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
@@ -317,26 +317,26 @@ input.y: warning: shift/reduce conflict on token A 
[-Wcounterexamples]
   Example: b . A X X Y
   Shift derivation
     a
-    `-> s
-        `-> b . xx        y
-                `-> A X X `-> Y
+    `-> 2: s
+           `-> 7: b . xx           y
+                      `-> 9: A X X `-> 11: Y
   Reduce derivation
     a
-    `-> r       t
-        `-> b . `-> A x     xy
-                      `-> X `-> X Y
+    `-> 1: r          t
+           `-> 3: b . `-> 6: A x        xy
+                               `-> 8: X `-> 10: X Y
 input.y: warning: shift/reduce conflict on token X [-Wcounterexamples]
   First example: A X . X
   Shift derivation
     a
-    `-> t
-        `-> A xx
-              `-> X . X
+    `-> 1: t
+           `-> 5: A xx
+                    `-> 9: X . X
   Second example: X . X xy
   Reduce derivation
     a
-    `-> x       t
-        `-> X . `-> X xy
+    `-> 1: x          t
+           `-> 8: X . `-> 6: X xy
 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]
 ]],
@@ -375,11 +375,11 @@ input.y: warning: reduce/reduce conflict on token $end 
[-Wcounterexamples]
   Example: A b .
   First reduce derivation
     a
-    `-> A b .
+    `-> 1: A b .
   Second reduce derivation
     a
-    `-> A b
-          `-> b .
+    `-> 1: A b
+             `-> 3: b .
 input.y:4.9: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
@@ -412,15 +412,15 @@ input.y: warning: reduce/reduce conflict on tokens A, C 
[-Wcounterexamples]
   First example: D . A $end
   First reduce derivation
     $accept
-    `-> s             $end
-        `-> a       A
-            `-> D .
+    `-> 0: s                   $end
+           `-> 1: a          A
+                  `-> 5: D .
   Second example: B D . A $end
   Second reduce derivation
     $accept
-    `-> s               $end
-        `-> B b       A
-              `-> D .
+    `-> 0: s                     $end
+           `-> 4: B b          A
+                    `-> 6: D .
 input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 2 reduce/reduce conflicts [-Wconflicts-rr]
@@ -455,15 +455,15 @@ time limit exceeded: XXX
   First example: H i . J K $end
   Shift derivation
     $accept
-    `-> a                 $end
-        `-> H i
-              `-> i . J K
+    `-> 0: a                       $end
+           `-> 2: H i
+                    `-> 4: i . J K
   Second example: H i . J $end
   Reduce derivation
     $accept
-    `-> s               $end
-        `-> a         J
-            `-> H i .
+    `-> 0: s                     $end
+           `-> 1: a            J
+                  `-> 2: H i .
 input.y:4.4-6: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
@@ -502,28 +502,28 @@ input.y: warning: shift/reduce conflict on token B 
[-Wcounterexamples]
   Example: N A . B C
   Shift derivation
     s
-    `-> n
-        `-> N b
-              `-> A . B C
+    `-> 1: n
+           `-> 6: N b
+                    `-> 8: A . B C
   Reduce derivation
     s
-    `-> n               C
-        `-> N a       B
-              `-> A .
+    `-> 2: n                     C
+           `-> 5: N a          B
+                    `-> 7: A .
 input.y: warning: shift/reduce conflict on token B [-Wcounterexamples]
   Example: N N A . B D C
   Shift derivation
     s
-    `-> n
-        `-> N n                 C
-              `-> N b
-                    `-> A . B D
+    `-> 1: n
+           `-> 4: N n                       C
+                    `-> 6: N b
+                             `-> 9: A . B D
   Reduce derivation
     s
-    `-> n                       C
-        `-> N n               D
-              `-> N a       B
-                    `-> A .
+    `-> 2: n                                C
+           `-> 3: N n                     D
+                    `-> 5: N a          B
+                             `-> 7: A .
 input.y:5.4: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
@@ -565,30 +565,30 @@ input.y: warning: reduce/reduce conflict on tokens b, c 
[-Wcounterexamples]
   Example: B . b c
   First reduce derivation
     S
-    `-> B                        C
-        `-> A       b A          `-> A          c A
-            `-> B .   `-> %empty     `-> %empty   `-> %empty
+    `-> 1: B                                 C
+           `-> 6: A          b A             `-> 7: A             c A
+                  `-> 3: B .   `-> 6: %empty        `-> 7: %empty   `-> 7: 
%empty
   Second reduce derivation
     S
-    `-> B C
-          `-> A                          c A
-              `-> B                        `-> %empty
-                  `-> A     b A
-                      `-> .   `-> %empty
+    `-> 1: B C
+             `-> 7: A                                      c A
+                    `-> 3: B                                 `-> 7: %empty
+                           `-> 6: A        b A
+                                  `-> 5: .   `-> 6: %empty
 input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
   Example: C . c b
   First reduce derivation
     S
-    `-> C                        B
-        `-> A       c A          `-> A          b A
-            `-> C .   `-> %empty     `-> %empty   `-> %empty
+    `-> 2: C                                 B
+           `-> 7: A          c A             `-> 6: A             b A
+                  `-> 4: C .   `-> 7: %empty        `-> 6: %empty   `-> 6: 
%empty
   Second reduce derivation
     S
-    `-> C B
-          `-> A                          b A
-              `-> C                        `-> %empty
-                  `-> A     c A
-                      `-> .   `-> %empty
+    `-> 2: C B
+             `-> 6: A                                      b A
+                    `-> 4: C                                 `-> 6: %empty
+                           `-> 7: A        c A
+                                  `-> 5: .   `-> 7: %empty
 ]],
 [[input.y: warning: 4 reduce/reduce conflicts [-Wconflicts-rr]
 input.y: warning: reduce/reduce conflict on tokens b, c [-Wcounterexamples]
@@ -625,119 +625,119 @@ input.y: warning: reduce/reduce conflict on token A 
[-Wcounterexamples]
   First example: . c A A $end
   First reduce derivation
     $accept
-    `-> a                   $end
-        `-> b     d
-            `-> . `-> c A A
+    `-> 0: a                            $end
+           `-> 1: b        d
+                  `-> 3: . `-> 6: c A A
   Second example: . c A A $end
   Second reduce derivation
     $accept
-    `-> a                   $end
-        `-> c     d
-            `-> . `-> c A A
+    `-> 0: a                            $end
+           `-> 2: c        d
+                  `-> 4: . `-> 6: c A A
 input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
 time limit exceeded: XXX
   First example: b . c A A $end
   First reduce derivation
     $accept
-    `-> a                             $end
-        `-> b d
-              `-> a
-                  `-> b     d
-                      `-> . `-> c A A
+    `-> 0: a                                            $end
+           `-> 1: b d
+                    `-> 5: a
+                           `-> 1: b        d
+                                  `-> 3: . `-> 6: c A A
   Second example: b . A $end
   Second reduce derivation
     $accept
-    `-> a                 $end
-        `-> b d
-              `-> c     A
-                  `-> .
+    `-> 0: a                          $end
+           `-> 1: b d
+                    `-> 6: c        A
+                           `-> 4: .
 input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
 time limit exceeded: XXX
   First example: c . c A A $end
   First reduce derivation
     $accept
-    `-> a                             $end
-        `-> c d
-              `-> a
-                  `-> b     d
-                      `-> . `-> c A A
+    `-> 0: a                                            $end
+           `-> 2: c d
+                    `-> 5: a
+                           `-> 1: b        d
+                                  `-> 3: . `-> 6: c A A
   Second example: c . A $end
   Second reduce derivation
     $accept
-    `-> a                 $end
-        `-> c d
-              `-> c     A
-                  `-> .
+    `-> 0: a                          $end
+           `-> 2: c d
+                    `-> 6: c        A
+                           `-> 4: .
 input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
 time limit exceeded: XXX
   First example: b c . A
   Shift derivation
     a
-    `-> b d
-          `-> c . A
+    `-> 1: b d
+             `-> 6: c . A
   Second example: b c . c A A $end
   Reduce derivation
     $accept
-    `-> a                                       $end
-        `-> b d
-              `-> a
-                  `-> c d
-                        `-> a
-                            `-> b     d
-                                `-> . `-> c A A
+    `-> 0: a                                                            $end
+           `-> 1: b d
+                    `-> 5: a
+                           `-> 2: c d
+                                    `-> 5: a
+                                           `-> 1: b        d
+                                                  `-> 3: . `-> 6: c A A
 input.y: warning: reduce/reduce conflict on token A [-Wcounterexamples]
   First example: b c . c A A $end
   First reduce derivation
     $accept
-    `-> a                                       $end
-        `-> b d
-              `-> a
-                  `-> c d
-                        `-> a
-                            `-> b     d
-                                `-> . `-> c A A
+    `-> 0: a                                                            $end
+           `-> 1: b d
+                    `-> 5: a
+                           `-> 2: c d
+                                    `-> 5: a
+                                           `-> 1: b        d
+                                                  `-> 3: . `-> 6: c A A
   Second example: b c . A $end
   Second reduce derivation
     $accept
-    `-> a                           $end
-        `-> b d
-              `-> a
-                  `-> c d
-                        `-> c     A
-                            `-> .
+    `-> 0: a                                          $end
+           `-> 1: b d
+                    `-> 5: a
+                           `-> 2: c d
+                                    `-> 6: c        A
+                                           `-> 4: .
 input.y: warning: shift/reduce conflict on token A [-Wcounterexamples]
   First example: b c . A
   Shift derivation
     a
-    `-> b d
-          `-> c . A
+    `-> 1: b d
+             `-> 6: c . A
   Second example: b c . A $end
   Reduce derivation
     $accept
-    `-> a                           $end
-        `-> b d
-              `-> a
-                  `-> c d
-                        `-> c     A
-                            `-> .
+    `-> 0: a                                          $end
+           `-> 1: b d
+                    `-> 5: a
+                           `-> 2: c d
+                                    `-> 6: c        A
+                                           `-> 4: .
 input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
   Example: b d .
   First reduce derivation
     a
-    `-> b d .
+    `-> 1: b d .
   Second reduce derivation
     a
-    `-> b d
-          `-> d .
+    `-> 1: b d
+             `-> 7: d .
 input.y: warning: reduce/reduce conflict on token $end [-Wcounterexamples]
   Example: c d .
   First reduce derivation
     a
-    `-> c d .
+    `-> 2: c d .
   Second reduce derivation
     a
-    `-> c d
-          `-> d .
+    `-> 2: c d
+             `-> 7: 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]
 ]],
@@ -813,13 +813,13 @@ input.y: warning: shift/reduce conflict on token J 
[-Wcounterexamples]
   Example: H i J . J J
   Shift derivation
     s
-    `-> a             J
-        `-> H i J . J
+    `-> 2: a                J
+           `-> 3: H i J . J
   Reduce derivation
     s
-    `-> a
-        `-> H i         J J
-              `-> i J .
+    `-> 1: a
+           `-> 3: H i            J J
+                    `-> 5: i J .
 input.y:5.13-15: warning: rule useless in parser due to conflicts [-Wother]
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
@@ -857,14 +857,14 @@ input.y: warning: shift/reduce conflict on token D 
[-Wcounterexamples]
   Example: A a . D
   Shift derivation
     s
-    `-> A a d
-            `-> . D
+    `-> 1: A a d
+               `-> 6: . D
   Reduce derivation
     s
-    `-> A a a             d
-            `-> b         `-> D
-                `-> c
-                    `-> .
+    `-> 2: A a a                      d
+               `-> 3: b               `-> 6: D
+                      `-> 4: c
+                             `-> 5: .
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y: warning: shift/reduce conflict on token D [-Wcounterexamples]
@@ -899,17 +899,17 @@ input.y: warning: shift/reduce conflict on token D 
[-Wcounterexamples]
   First example: A a . D $end
   Shift derivation
     $accept
-    `-> s               $end
-        `-> A a d
-                `-> . D
+    `-> 0: s                     $end
+           `-> 1: A a d
+                      `-> 6: . D
   Second example: A a . D E $end
   Reduce derivation
     $accept
-    `-> s                             $end
-        `-> A a a             d     E
-                `-> b         `-> D
-                    `-> c
-                        `-> .
+    `-> 0: s                                            $end
+           `-> 2: A a a                      d        E
+                      `-> 3: b               `-> 6: D
+                             `-> 4: c
+                                    `-> 5: .
 ]],
 [[input.y: warning: 1 shift/reduce conflict [-Wconflicts-sr]
 input.y: warning: shift/reduce conflict on token D [-Wcounterexamples]
diff --git a/tests/diagnostics.at b/tests/diagnostics.at
index e8dcb384..43b365b9 100644
--- a/tests/diagnostics.at
+++ b/tests/diagnostics.at
@@ -378,10 +378,12 @@ exp:^M
 ]],
 [0],
 [[input.y:11.9-11: <warning>warning:</warning> symbol FOO redeclared 
[<warning>-Wother</warning>]
-   11 | %token 
 <warning>FOO</warning>
+   11 | %token 
+ <warning>FOO</warning>
       |         <warning>^~~</warning>
 input.y:10.9-11: <note>note:</note> previous declaration
-   10 | %token 
 <note>FOO</note>
+   10 | %token 
+ <note>FOO</note>
       |         <note>^~~</note>
 input.y:13.5: <warning>warning:</warning> empty rule without %empty 
[<warning>-Wempty-rule</warning>]
    13 | exp:
@@ -539,46 +541,46 @@ input.y: <warning>warning:</warning> shift/reduce 
conflict on token "+" [<warnin
   Example: <cex-0><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf><cex-1> 
<cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> 
<cex-leaf>exp</cex-leaf></cex-1></cex-0>
   Shift derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-leaf>exp</cex-leaf><cex-leaf> 
"+"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
-    <cex-1><cex-step>          ↳ <cex-leaf>exp</cex-leaf><cex-dot> 
•</cex-dot><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
+    <cex-0><cex-step>↳ 3: <cex-leaf>exp</cex-leaf><cex-leaf> 
"+"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
+    <cex-1><cex-step>             ↳ 3: <cex-leaf>exp</cex-leaf><cex-dot> 
•</cex-dot><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
   Example: <cex-0><cex-1><cex-leaf>exp</cex-leaf> <cex-leaf>"+"</cex-leaf> 
<cex-leaf>exp</cex-leaf> <cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> 
<cex-leaf>exp</cex-leaf></cex-0>
   Reduce derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf>       
      "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
-    <cex-1><cex-step>  ↳ <cex-leaf>exp</cex-leaf><cex-leaf> 
"+"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-1>
+    <cex-0><cex-step>↳ 3: <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf>    
            "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
+    <cex-1><cex-step>     ↳ 3: <cex-leaf>exp</cex-leaf><cex-leaf> 
"+"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot></cex-step></cex-1>
 input.y: <warning>warning:</warning> shift/reduce conflict on token "else" 
[<warning>-Wcounterexamples</warning>]
   Example: <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>"if"</cex-leaf> 
<cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-dot>•</cex-dot> <cex-leaf>"else"</cex-leaf> 
<cex-leaf>exp</cex-leaf></cex-1></cex-0>
   Shift derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> 
exp</cex-step></cex-1></cex-step></cex-0>
-    <cex-1><cex-step>                  ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> 
•</cex-dot><cex-leaf> "else"</cex-leaf><cex-leaf> 
exp</cex-leaf></cex-step></cex-1>
+    <cex-0><cex-step>↳ 1: <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> 
exp</cex-step></cex-1></cex-step></cex-0>
+    <cex-1><cex-step>                     ↳ 2: 
<cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> 
"then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> 
"else"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
   Example: <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>"if"</cex-leaf> 
<cex-leaf>exp</cex-leaf> <cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-dot>•</cex-dot></cex-1> <cex-leaf>"else"</cex-leaf> 
<cex-leaf>exp</cex-leaf></cex-0>
   Reduce derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> 
exp</cex-step></cex-1><cex-leaf>                     
"else"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
-    <cex-1><cex-step>                  ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-1>
+    <cex-0><cex-step>↳ 2: <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> 
exp</cex-step></cex-1><cex-leaf>                        
"else"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
+    <cex-1><cex-step>                     ↳ 1: 
<cex-leaf>"if"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> 
"then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-1>
 input.y: <warning>warning:</warning> shift/reduce conflict on token "+" 
[<warning>-Wcounterexamples</warning>]
   Example: <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-leaf>"then"</cex-leaf><cex-1> <cex-leaf>exp</cex-leaf> 
<cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> 
<cex-leaf>exp</cex-leaf></cex-1></cex-0>
   Shift derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> 
exp</cex-step></cex-1></cex-step></cex-0>
-    <cex-1><cex-step>                  ↳ <cex-leaf>exp</cex-leaf><cex-dot> 
•</cex-dot><cex-leaf> "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
+    <cex-0><cex-step>↳ 1: <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-1><cex-step> 
exp</cex-step></cex-1></cex-step></cex-0>
+    <cex-1><cex-step>                     ↳ 3: 
<cex-leaf>exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> 
"+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
   Example: <cex-0><cex-1><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> 
<cex-leaf>exp</cex-leaf></cex-0>
   Reduce derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf>       
              "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
-    <cex-1><cex-step>  ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-1>
+    <cex-0><cex-step>↳ 3: <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf>    
                    "+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-0>
+    <cex-1><cex-step>     ↳ 1: <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-1>
 input.y: <warning>warning:</warning> shift/reduce conflict on token "+" 
[<warning>-Wcounterexamples</warning>]
   Example: <cex-0><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-leaf>"else"</cex-leaf><cex-1> <cex-leaf>exp</cex-leaf> 
<cex-dot>•</cex-dot> <cex-leaf>"+"</cex-leaf> 
<cex-leaf>exp</cex-leaf></cex-1></cex-0>
   Shift derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> 
"else"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
-    <cex-1><cex-step>                             ↳ 
<cex-leaf>exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> 
"+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
+    <cex-0><cex-step>↳ 2: <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> 
"else"</cex-leaf><cex-1><cex-step> exp</cex-step></cex-1></cex-step></cex-0>
+    <cex-1><cex-step>                                ↳ 3: 
<cex-leaf>exp</cex-leaf><cex-dot> •</cex-dot><cex-leaf> 
"+"</cex-leaf><cex-leaf> exp</cex-leaf></cex-step></cex-1>
   Example: <cex-0><cex-1><cex-leaf>"if"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-leaf>"then"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-leaf>"else"</cex-leaf> <cex-leaf>exp</cex-leaf> 
<cex-dot>•</cex-dot></cex-1> <cex-leaf>"+"</cex-leaf> 
<cex-leaf>exp</cex-leaf></cex-0>
   Reduce derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf>       
                         "+"</cex-leaf><cex-leaf> 
exp</cex-leaf></cex-step></cex-0>
-    <cex-1><cex-step>  ↳ <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> 
"else"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-1>
+    <cex-0><cex-step>↳ 3: <cex-1><cex-step>exp</cex-step></cex-1><cex-leaf>    
                               "+"</cex-leaf><cex-leaf> 
exp</cex-leaf></cex-step></cex-0>
+    <cex-1><cex-step>     ↳ 2: <cex-leaf>"if"</cex-leaf><cex-leaf> 
exp</cex-leaf><cex-leaf> "then"</cex-leaf><cex-leaf> exp</cex-leaf><cex-leaf> 
"else"</cex-leaf><cex-leaf> exp</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-1>
 ]])
 
 
@@ -621,23 +623,23 @@ input.y: <warning>warning:</warning> reduce/reduce 
conflict on token "X" [<warni
   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 reduce derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-1><cex-step>x1</cex-step></cex-1><cex-4><cex-step> 
         e1</cex-step></cex-4><cex-5><cex-step>  
foo1</cex-step></cex-5><cex-12><cex-step>                      
x1</cex-step></cex-12></cex-step></cex-0>
-    <cex-1><cex-step>  ↳ 
<cex-2><cex-step>x2</cex-step></cex-2></cex-step></cex-1><cex-4><cex-step>      
  ↳ ε</cex-step></cex-4><cex-5><cex-step> ↳ 
<cex-6><cex-step>foo2</cex-step></cex-6></cex-step></cex-5><cex-12><cex-step>   
                 ↳ <cex-13><cex-step>x2</cex-step></cex-13></cex-step></cex-12>
-    <cex-2><cex-step>    ↳ 
<cex-3><cex-step>x3</cex-step></cex-3></cex-step></cex-2><cex-6><cex-step>      
      ↳ 
<cex-7><cex-step>foo3</cex-step></cex-7></cex-step></cex-6><cex-13><cex-step>   
                 ↳ <cex-14><cex-step>x3</cex-step></cex-14></cex-step></cex-13>
-    <cex-3><cex-step>      ↳ <cex-leaf>"X"</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-3><cex-7><cex-step>         ↳ 
<cex-8><cex-step>x1</cex-step></cex-8><cex-11><cex-step>        
foo4</cex-step></cex-11></cex-step></cex-7><cex-14><cex-step>          ↳ 
<cex-leaf>"X"</cex-leaf></cex-step></cex-14>
-    <cex-8><cex-step>                        ↳ 
<cex-9><cex-step>x2</cex-step></cex-9></cex-step></cex-8><cex-11><cex-step>     
 ↳ <cex-leaf>"quuux"</cex-leaf></cex-step></cex-11>
-    <cex-9><cex-step>                          ↳ 
<cex-10><cex-step>x3</cex-step></cex-10></cex-step></cex-9>
-    <cex-10><cex-step>                            ↳ 
<cex-leaf>"X"</cex-leaf></cex-step></cex-10>
+    <cex-0><cex-step>↳ 1: 
<cex-1><cex-step>x1</cex-step></cex-1><cex-4><cex-step>                      
e1</cex-step></cex-4><cex-5><cex-step>     
foo1</cex-step></cex-5><cex-12><cex-step>                                       
       x1</cex-step></cex-12></cex-step></cex-0>
+    <cex-1><cex-step>     ↳ 11: 
<cex-2><cex-step>x2</cex-step></cex-2></cex-step></cex-1><cex-4><cex-step>      
          ↳ 1: ε</cex-step></cex-4><cex-5><cex-step> ↳ 3: 
<cex-6><cex-step>foo2</cex-step></cex-6></cex-step></cex-5><cex-12><cex-step>   
                                      ↳ 11: 
<cex-13><cex-step>x2</cex-step></cex-13></cex-step></cex-12>
+    <cex-2><cex-step>           ↳ 12: 
<cex-3><cex-step>x3</cex-step></cex-3></cex-step></cex-2><cex-6><cex-step>      
                ↳ 4: 
<cex-7><cex-step>foo3</cex-step></cex-7></cex-step></cex-6><cex-13><cex-step>   
                                       ↳ 12: 
<cex-14><cex-step>x3</cex-step></cex-14></cex-step></cex-13>
+    <cex-3><cex-step>                 ↳ 13: <cex-leaf>"X"</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-3><cex-7><cex-step>                  ↳ 5: 
<cex-8><cex-step>x1</cex-step></cex-8><cex-11><cex-step>                    
foo4</cex-step></cex-11></cex-step></cex-7><cex-14><cex-step>                   
  ↳ 13: <cex-leaf>"X"</cex-leaf></cex-step></cex-14>
+    <cex-8><cex-step>                                                   ↳ 11: 
<cex-9><cex-step>x2</cex-step></cex-9></cex-step></cex-8><cex-11><cex-step>     
         ↳ 6: <cex-leaf>"quuux"</cex-leaf></cex-step></cex-11>
+    <cex-9><cex-step>                                                         
↳ 12: <cex-10><cex-step>x3</cex-step></cex-10></cex-step></cex-9>
+    <cex-10><cex-step>                                                         
      ↳ 13: <cex-leaf>"X"</cex-leaf></cex-step></cex-10>
   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>
   Second reduce derivation
     <cex-0><cex-step>exp</cex-step></cex-0>
-    <cex-0><cex-step>↳ <cex-1><cex-step>y1</cex-step></cex-1><cex-4><cex-step> 
         e2</cex-step></cex-4><cex-5><cex-step>  
bar1</cex-step></cex-5><cex-12><cex-step>                      
y1</cex-step></cex-12></cex-step></cex-0>
-    <cex-1><cex-step>  ↳ 
<cex-2><cex-step>y2</cex-step></cex-2></cex-step></cex-1><cex-4><cex-step>      
  ↳ ε</cex-step></cex-4><cex-5><cex-step> ↳ 
<cex-6><cex-step>bar2</cex-step></cex-6></cex-step></cex-5><cex-12><cex-step>   
                 ↳ <cex-13><cex-step>y2</cex-step></cex-13></cex-step></cex-12>
-    <cex-2><cex-step>    ↳ 
<cex-3><cex-step>y3</cex-step></cex-3></cex-step></cex-2><cex-6><cex-step>      
      ↳ 
<cex-7><cex-step>bar3</cex-step></cex-7></cex-step></cex-6><cex-13><cex-step>   
                 ↳ <cex-14><cex-step>y3</cex-step></cex-14></cex-step></cex-13>
-    <cex-3><cex-step>      ↳ <cex-leaf>"X"</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-3><cex-7><cex-step>         ↳ 
<cex-8><cex-step>y1</cex-step></cex-8><cex-11><cex-step>        
bar4</cex-step></cex-11></cex-step></cex-7><cex-14><cex-step>          ↳ 
<cex-leaf>"X"</cex-leaf></cex-step></cex-14>
-    <cex-8><cex-step>                        ↳ 
<cex-9><cex-step>y2</cex-step></cex-9></cex-step></cex-8><cex-11><cex-step>     
 ↳ <cex-leaf>"quuux"</cex-leaf></cex-step></cex-11>
-    <cex-9><cex-step>                          ↳ 
<cex-10><cex-step>y3</cex-step></cex-10></cex-step></cex-9>
-    <cex-10><cex-step>                            ↳ 
<cex-leaf>"X"</cex-leaf></cex-step></cex-10>
+    <cex-0><cex-step>↳ 2: 
<cex-1><cex-step>y1</cex-step></cex-1><cex-4><cex-step>                      
e2</cex-step></cex-4><cex-5><cex-step>     
bar1</cex-step></cex-5><cex-12><cex-step>                                       
        y1</cex-step></cex-12></cex-step></cex-0>
+    <cex-1><cex-step>     ↳ 14: 
<cex-2><cex-step>y2</cex-step></cex-2></cex-step></cex-1><cex-4><cex-step>      
          ↳ 2: ε</cex-step></cex-4><cex-5><cex-step> ↳ 7: 
<cex-6><cex-step>bar2</cex-step></cex-6></cex-step></cex-5><cex-12><cex-step>   
                                       ↳ 14: 
<cex-13><cex-step>y2</cex-step></cex-13></cex-step></cex-12>
+    <cex-2><cex-step>           ↳ 15: 
<cex-3><cex-step>y3</cex-step></cex-3></cex-step></cex-2><cex-6><cex-step>      
                ↳ 8: 
<cex-7><cex-step>bar3</cex-step></cex-7></cex-step></cex-6><cex-13><cex-step>   
                                        ↳ 15: 
<cex-14><cex-step>y3</cex-step></cex-14></cex-step></cex-13>
+    <cex-3><cex-step>                 ↳ 16: <cex-leaf>"X"</cex-leaf><cex-dot> 
•</cex-dot></cex-step></cex-3><cex-7><cex-step>                  ↳ 9: 
<cex-8><cex-step>y1</cex-step></cex-8><cex-11><cex-step>                    
bar4</cex-step></cex-11></cex-step></cex-7><cex-14><cex-step>                   
   ↳ 16: <cex-leaf>"X"</cex-leaf></cex-step></cex-14>
+    <cex-8><cex-step>                                                   ↳ 14: 
<cex-9><cex-step>y2</cex-step></cex-9></cex-step></cex-8><cex-11><cex-step>     
         ↳ 10: <cex-leaf>"quuux"</cex-leaf></cex-step></cex-11>
+    <cex-9><cex-step>                                                         
↳ 15: <cex-10><cex-step>y3</cex-step></cex-10></cex-step></cex-9>
+    <cex-10><cex-step>                                                         
      ↳ 16: <cex-leaf>"X"</cex-leaf></cex-step></cex-10>
 input.y: <warning>warning:</warning> fix-its can be applied.  Rerun with 
option '--update'. [<warning>-Wother</warning>]
 ]])
 
diff --git a/tests/report.at b/tests/report.at
index 9021f6d5..35493b93 100644
--- a/tests/report.at
+++ b/tests/report.at
@@ -1541,60 +1541,60 @@ input.y: warning: shift/reduce conflict on token "⊕" 
[-Wcounterexamples]
   Example: exp "+" exp • "⊕" exp
   Shift derivation
     exp
-    ↳ exp "+" exp
-              ↳ exp • "⊕" exp
+    ↳ 2: exp "+" exp
+                 ↳ 1: exp • "⊕" exp
   Reduce derivation
     exp
-    ↳ exp             "⊕" exp
-      ↳ exp "+" exp •
+    ↳ 1: exp                "⊕" exp
+         ↳ 2: exp "+" exp •
 input.y: warning: reduce/reduce conflict on tokens $end, "+", "⊕" 
[-Wcounterexamples]
   Example: exp "+" exp •
   First reduce derivation
     exp
-    ↳ exp "+" exp •
+    ↳ 2: exp "+" exp •
   Second reduce derivation
     exp
-    ↳ exp "+" exp •
+    ↳ 3: exp "+" exp •
 input.y: warning: shift/reduce conflict on token "⊕" [-Wcounterexamples]
   Example: exp "+" exp • "⊕" exp
   Shift derivation
     exp
-    ↳ exp "+" exp
-              ↳ exp • "⊕" exp
+    ↳ 2: exp "+" exp
+                 ↳ 1: exp • "⊕" exp
   Reduce derivation
     exp
-    ↳ exp             "⊕" exp
-      ↳ exp "+" exp •
+    ↳ 1: exp                "⊕" exp
+         ↳ 3: exp "+" exp •
 input.y: warning: shift/reduce conflict on token "⊕" [-Wcounterexamples]
   Example: exp "⊕" exp • "⊕" exp
   Shift derivation
     exp
-    ↳ exp "⊕" exp
-              ↳ exp • "⊕" exp
+    ↳ 1: exp "⊕" exp
+                 ↳ 1: exp • "⊕" exp
   Reduce derivation
     exp
-    ↳ exp             "⊕" exp
-      ↳ exp "⊕" exp •
+    ↳ 1: exp                "⊕" exp
+         ↳ 1: exp "⊕" exp •
 input.y: warning: shift/reduce conflict on token "+" [-Wcounterexamples]
   Example: exp "⊕" exp • "+" exp
   Shift derivation
     exp
-    ↳ exp "⊕" exp
-              ↳ exp • "+" exp
+    ↳ 1: exp "⊕" exp
+                 ↳ 2: exp • "+" exp
   Reduce derivation
     exp
-    ↳ exp             "+" exp
-      ↳ exp "⊕" exp •
+    ↳ 2: exp                "+" exp
+         ↳ 1: exp "⊕" exp •
 input.y: warning: shift/reduce conflict on token "+" [-Wcounterexamples]
   Example: exp "⊕" exp • "+" exp
   Shift derivation
     exp
-    ↳ exp "⊕" exp
-              ↳ exp • "+" exp
+    ↳ 1: exp "⊕" exp
+                 ↳ 3: exp • "+" exp
   Reduce derivation
     exp
-    ↳ exp             "+" exp
-      ↳ exp "⊕" exp •
+    ↳ 2: exp                "+" exp
+         ↳ 1: exp "⊕" exp •
 input.y:6.3-13: warning: rule useless in parser due to conflicts [-Wother]
 ]])
 
@@ -1745,12 +1745,12 @@ State 7
       Example: exp "+" exp • "⊕" exp
       Shift derivation
         exp
-        ↳ exp "+" exp
-                  ↳ exp • "⊕" exp
+        ↳ 2: exp "+" exp
+                     ↳ 1: exp • "⊕" exp
       Reduce derivation
         exp
-        ↳ exp             "⊕" exp
-          ↳ exp "+" exp •
+        ↳ 1: exp                "⊕" exp
+             ↳ 2: exp "+" exp •
 
     reduce/reduce conflict on tokens $end, "+", "⊕":
         2 exp: exp "+" exp •
@@ -1758,10 +1758,10 @@ State 7
       Example: exp "+" exp •
       First reduce derivation
         exp
-        ↳ exp "+" exp •
+        ↳ 2: exp "+" exp •
       Second reduce derivation
         exp
-        ↳ exp "+" exp •
+        ↳ 3: exp "+" exp •
 
     shift/reduce conflict on token "⊕":
         3 exp: exp "+" exp •
@@ -1769,12 +1769,12 @@ State 7
       Example: exp "+" exp • "⊕" exp
       Shift derivation
         exp
-        ↳ exp "+" exp
-                  ↳ exp • "⊕" exp
+        ↳ 2: exp "+" exp
+                     ↳ 1: exp • "⊕" exp
       Reduce derivation
         exp
-        ↳ exp             "⊕" exp
-          ↳ exp "+" exp •
+        ↳ 1: exp                "⊕" exp
+             ↳ 3: exp "+" exp •
 
 
 
@@ -1798,12 +1798,12 @@ State 8
       Example: exp "⊕" exp • "⊕" exp
       Shift derivation
         exp
-        ↳ exp "⊕" exp
-                  ↳ exp • "⊕" exp
+        ↳ 1: exp "⊕" exp
+                     ↳ 1: exp • "⊕" exp
       Reduce derivation
         exp
-        ↳ exp             "⊕" exp
-          ↳ exp "⊕" exp •
+        ↳ 1: exp                "⊕" exp
+             ↳ 1: exp "⊕" exp •
 
     shift/reduce conflict on token "+":
         1 exp: exp "⊕" exp •
@@ -1811,12 +1811,12 @@ State 8
       Example: exp "⊕" exp • "+" exp
       Shift derivation
         exp
-        ↳ exp "⊕" exp
-                  ↳ exp • "+" exp
+        ↳ 1: exp "⊕" exp
+                     ↳ 2: exp • "+" exp
       Reduce derivation
         exp
-        ↳ exp             "+" exp
-          ↳ exp "⊕" exp •
+        ↳ 2: exp                "+" exp
+             ↳ 1: exp "⊕" exp •
 
     shift/reduce conflict on token "+":
         1 exp: exp "⊕" exp •
@@ -1824,12 +1824,12 @@ State 8
       Example: exp "⊕" exp • "+" exp
       Shift derivation
         exp
-        ↳ exp "⊕" exp
-                  ↳ exp • "+" exp
+        ↳ 1: exp "⊕" exp
+                     ↳ 3: exp • "+" exp
       Reduce derivation
         exp
-        ↳ exp             "+" exp
-          ↳ exp "⊕" exp •
+        ↳ 2: exp                "+" exp
+             ↳ 1: exp "⊕" exp •
 
 ]])
 
-- 
2.27.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]