cex: display the rule numbers

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.

* doc/bison.texi: Adjust.
This commit is contained in:
Akim Demaille
2020-07-28 19:50:22 +02:00
parent 2becdace96
commit 3c36d871fa
13 changed files with 407 additions and 357 deletions

View File

@@ -288,7 +288,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);
}
@@ -422,7 +423,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);
}

View File

@@ -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;
}
@@ -205,6 +210,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
@@ -217,6 +239,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;
@@ -281,6 +304,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);

View File

@@ -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.

View File

@@ -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);

View File

@@ -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
*/

View File

@@ -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);