From e1783bc6863c06aaeaa0b672c2f02a648772665f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 28 Jan 2019 19:05:38 +0100 Subject: [PATCH] gram: factor the printing of items and the computation of their rule There are several places where we need to recover the rule from an item, let's factor that into item_rule. We also want to print items in a nice way: we do it when generating the *output file, but it is also useful in debug messages. * src/gram.h, src/gram.c (item_rule, item_print): New. * src/print.c (print_core): Use them. * src/state.h, src/state.c: Propagate constness. --- src/closure.c | 6 +++--- src/gram.c | 29 +++++++++++++++++++++++++++++ src/gram.h | 10 ++++++++++ src/print.c | 27 +++++---------------------- src/state.c | 6 +++--- src/state.h | 6 +++--- 6 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/closure.c b/src/closure.c index 4ff44157..e63b1fb9 100644 --- a/src/closure.c +++ b/src/closure.c @@ -192,12 +192,12 @@ closure (item_number const *core, size_t n) /* core is sorted on item index in ritem, which is sorted on rule number. Compute itemset with the same sort. */ + nitemset = 0; + size_t c = 0; + /* A bit index over RULESET. */ rule_number ruleno; bitset_iterator iter; - - nitemset = 0; - size_t c = 0; BITSET_FOR_EACH (iter, ruleset, ruleno, 0) { item_number itemno = rules[ruleno].rhs - ritem; diff --git a/src/gram.c b/src/gram.c index 54aa7342..19c588d6 100644 --- a/src/gram.c +++ b/src/gram.c @@ -48,6 +48,35 @@ int max_user_token_number = 256; int required_version = 0; +rule const * +item_rule (item_number const *item) +{ + item_number const *sp = item; + while (*sp >= 0) + ++sp; + + rule_number r = item_number_as_rule_number (*sp); + return &rules[r]; +} + + +void +item_print (item_number *item, rule const *previous_rule, FILE *out) +{ + rule const *r = item_rule (item); + rule_lhs_print (r, previous_rule ? previous_rule->lhs : NULL, out); + + for (item_number *sp = r->rhs; sp < item; sp++) + fprintf (out, " %s", symbols[*sp]->tag); + fputs (" .", out); + if (0 <= *r->rhs) + for (item_number *sp = item; 0 <= *sp; ++sp) + fprintf (out, " %s", symbols[*sp]->tag); + else + fprintf (out, " %%empty"); +} + + bool rule_useful_in_grammar_p (rule const *r) { diff --git a/src/gram.h b/src/gram.h index 3210b494..f7918cd5 100644 --- a/src/gram.h +++ b/src/gram.h @@ -166,6 +166,7 @@ item_number_is_rule_number (item_number i) return i < 0; } + /*--------. | Rules. | `--------*/ @@ -207,6 +208,15 @@ typedef struct extern rule *rules; +/* Get the rule associated to this item. ITEM points inside RITEM. */ +rule const *item_rule (item_number const *item); + +/* Pretty-print this ITEM (as in the report). ITEM points inside + RITEM. PREVIOUS_RULE is used to see if the lhs is common, in which + case LHS is factored. Passing NULL is fine. */ +void item_print (item_number *item, rule const *previous_rule, + FILE *out); + /* A function that selects a rule. */ typedef bool (*rule_filter) (rule const *); diff --git a/src/print.c b/src/print.c index 42adb1d7..7e002c14 100644 --- a/src/print.c +++ b/src/print.c @@ -63,8 +63,6 @@ print_core (FILE *out, state *s) { item_number *sitems = s->items; size_t snritems = s->nitems; - sym_content *previous_lhs = NULL; - /* Output all the items of a state, not only its kernel. */ if (report_flag & report_itemsets) { @@ -78,33 +76,18 @@ print_core (FILE *out, state *s) fputc ('\n', out); + rule const *previous_rule = NULL; for (size_t i = 0; i < snritems; i++) { item_number *sp1 = ritem + sitems[i]; - - item_number *sp = sp1; - while (*sp >= 0) - sp++; - - rule_number r = item_number_as_rule_number (*sp); - - rule_lhs_print (&rules[r], previous_lhs, out); - previous_lhs = rules[r].lhs; - - for (sp = rules[r].rhs; sp < sp1; sp++) - fprintf (out, " %s", symbols[*sp]->tag); - fputs (" .", out); - if (0 <= *rules[r].rhs) - for (/* Nothing */; 0 <= *sp; ++sp) - fprintf (out, " %s", symbols[*sp]->tag); - else - fprintf (out, " %%empty"); + rule const *r = item_rule (sp1); + item_print (sp1, previous_rule, out); + previous_rule = r; /* Display the lookahead tokens? */ if (report_flag & report_lookahead_tokens && item_number_is_rule_number (*sp1)) - state_rule_lookahead_tokens_print (s, &rules[r], out); - + state_rule_lookahead_tokens_print (s, r, out); fputc ('\n', out); } } diff --git a/src/state.c b/src/state.c index df30edb8..b673ec4f 100644 --- a/src/state.c +++ b/src/state.c @@ -218,7 +218,7 @@ state_reductions_set (state *s, int num, rule **reds) int -state_reduction_find (state *s, rule *r) +state_reduction_find (state *s, rule const *r) { reductions *reds = s->reductions; for (int i = 0; i < reds->num; ++i) @@ -247,7 +247,7 @@ state_errs_set (state *s, int num, symbol **tokens) `--------------------------------------------------*/ void -state_rule_lookahead_tokens_print (state *s, rule *r, FILE *out) +state_rule_lookahead_tokens_print (state *s, rule const *r, FILE *out) { /* Find the reduction we are handling. */ reductions *reds = s->reductions; @@ -270,7 +270,7 @@ state_rule_lookahead_tokens_print (state *s, rule *r, FILE *out) } void -state_rule_lookahead_tokens_print_xml (state *s, rule *r, +state_rule_lookahead_tokens_print_xml (state *s, rule const *r, FILE *out, int level) { /* Find the reduction we are handling. */ diff --git a/src/state.h b/src/state.h index b4a3e351..975b69d5 100644 --- a/src/state.h +++ b/src/state.h @@ -239,15 +239,15 @@ void state_transitions_set (state *s, int num, state **dst); /* Set the reductions of STATE. */ void state_reductions_set (state *s, int num, rule **reds); -int state_reduction_find (state *s, rule *r); +int state_reduction_find (state *s, rule const *r); /* Set the errs of STATE. */ void state_errs_set (state *s, int num, symbol **errors); /* Print on OUT all the lookahead tokens such that this STATE wants to reduce R. */ -void state_rule_lookahead_tokens_print (state *s, rule *r, FILE *out); -void state_rule_lookahead_tokens_print_xml (state *s, rule *r, +void state_rule_lookahead_tokens_print (state *s, rule const *r, FILE *out); +void state_rule_lookahead_tokens_print_xml (state *s, rule const *r, FILE *out, int level); /* Create/destroy the states hash table. */