[PATCH 7/7] cex: replace state-item data structures

Vincent Imbimbo <[email protected]>
Newsgroups gmane.comp.parsers.bison.patches
Message-ID <[email protected]>
* src/state-item.h: add trans, prods, and revs edges to state-item struct.
Remove si_trans, si_revs, and si_prods_lookup.
* src/state-item.c, src/lssi.c, src/parse-simulation.c, src/counterexample.c: update state-item API usage accordingly.
---
 src/counterexample.c   |  9 +++---
 src/lssi.c             | 20 ++++++-------
 src/parse-simulation.c | 18 +++++-------
 src/state-item.c       | 66 ++++++++++++++++++++----------------------
 src/state-item.h       | 21 +++++---------
 5 files changed, 62 insertions(+), 72 deletions(-)

diff --git a/src/counterexample.c b/src/counterexample.c
index 6201d9f3..d5dca5e3 100644
--- a/src/counterexample.c
+++ b/src/counterexample.c
@@ -196,7 +196,7 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
           // add each production to the search
           bitset_iterator biter;
           state_item_number sin;
-          bitset sib = si_prods_lookup (node->si);
+          bitset sib = silast->prods;
           BITSET_FOR_EACH (biter, sib, sin, 0)
             {
               // ignore productions already in the path
@@ -208,7 +208,7 @@ expand_to_conflict (state_item_number start, symbol_number conflict_sym)
           // for nullable nonterminals, add its goto to the search
           if (nullable[sym - ntokens])
             {
-              si_bfs_node *next = si_bfs_new (si_trans[node->si], node);
+              si_bfs_node *next = si_bfs_new (silast->trans, node);
               gl_list_add_last (queue, next);
             }
         }
@@ -304,7 +304,8 @@ complete_diverging_example (symbol_number conflict_sym,
       // go through each symbol after the dot in the current rule, and
       // add each symbol to its derivation.
       for (state_item_number nsi = si - state_items;
-           !item_number_is_rule_number (*i); ++i, nsi = si_trans[nsi])
+           !item_number_is_rule_number (*i);
+           ++i, nsi = state_items[nsi].trans)
         {
           // if the item is a reduction, we could skip to the wrong rule
           // by starting at i + 1, so this continue is necessary
@@ -433,7 +434,7 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
           // if the current state-item is a production item,
           // its reverse production items get added to the queue.
           // Otherwise, look for a reverse transition to the target state.
-          bitset rsi = si_revs[sis->si];
+          bitset rsi = search_si->revs;
           bitset_iterator biter;
           state_item_number sin;
           BITSET_FOR_EACH (biter, rsi, sin, 0)
diff --git a/src/lssi.c b/src/lssi.c
index 293daafb..406a5ebb 100644
--- a/src/lssi.c
+++ b/src/lssi.c
@@ -132,7 +132,7 @@ eligible_state_items (state_item *target)
         continue;
       bitset_set (result, si - state_items);
       // search all reverse edges.
-      bitset rsi = si_revs[si - state_items];
+      bitset rsi = si->revs;
       bitset_iterator biter;
       state_item_number sin;
       BITSET_FOR_EACH (biter, rsi, sin, 0)
@@ -175,13 +175,13 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
           finished = true;
           break;
         }
+      state_item *si = state_items + last;
       // Transitions don't change follow_L
-      if (si_trans[last] >= 0)
+      if (si->trans >= 0)
         {
-          state_item_number nextSI = si_trans[last];
-          if (bitset_test (eligible, nextSI))
+          if (bitset_test (eligible, si->trans))
             {
-              lssi *next = new_lssi (nextSI, n, n->lookahead, false);
+              lssi *next = new_lssi (si->trans, n, n->lookahead, false);
               append_lssi (next, visited, queue);
             }
         }
@@ -192,13 +192,11 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
       // if the symbol is not nullable, follow_L is its FIRSTS set
       // if the symbol is nullable, follow_L is its FIRSTS set unioned with
       // this logic applied to the next symbol in the rule
-      bitset p = si_prods_lookup (last);
-      if (p)
+      if (si->prods)
         {
-          state_item si = state_items[last];
           // Compute follow_L as above
           bitset lookahead = bitset_create (nsyms, BITSET_FIXED);
-          item_number *pos = si.item + 1;
+          item_number *pos = si->item + 1;
           for (; !item_number_is_rule_number (*pos); ++pos)
             {
               item_number it = *pos;
@@ -221,7 +219,7 @@ shortest_path_from_start (state_item_number target, symbol_number next_sym)
           // Try all possible production steps within this parser state.
           bitset_iterator biter;
           state_item_number nextSI;
-          BITSET_FOR_EACH (biter, p, nextSI, 0)
+          BITSET_FOR_EACH (biter, si->prods, nextSI, 0)
             {
               if (!bitset_test (eligible, nextSI))
                 continue;
@@ -320,7 +318,7 @@ lssi_reverse_production (const state_item *si, bitset lookahead)
   // compatible with the lookahead.
   bitset_iterator biter;
   state_item_number sin;
-  BITSET_FOR_EACH (biter, si_revs[si - state_items], sin, 0)
+  BITSET_FOR_EACH (biter, si->revs, sin, 0)
   {
     state_item *prevsi = state_items + sin;
     if (!production_allowed (prevsi, si))
diff --git a/src/parse-simulation.c b/src/parse-simulation.c
index 6886593e..e314bee2 100644
--- a/src/parse-simulation.c
+++ b/src/parse-simulation.c
@@ -400,8 +400,8 @@ nullable_closure (parse_state *ps, state_item *si, parse_state_list state_list)
 {
   parse_state *current_ps = ps;
   state_item_number prev_sin = si - state_items;
-  for (state_item_number sin = si_trans[prev_sin];
-       sin != -1; prev_sin = sin, sin = si_trans[sin])
+  for (state_item_number sin = si->trans; sin != -1;
+       prev_sin = sin, sin = state_items[sin].trans)
     {
       state_item *psi = state_items + prev_sin;
       symbol_number sp = item_number_as_symbol_number (*psi->item);
@@ -424,7 +424,7 @@ simulate_transition (parse_state *ps)
   // Transition on the same next symbol, taking nullable
   // symbols into account.
   gl_list_t result = parse_state_list_new ();
-  state_item_number si_next = si_trans[si - state_items];
+  state_item_number si_next = si->trans;
   // check for disabled transition, shouldn't happen
   // as any state_items that lead to these should be
   // disabled.
@@ -463,12 +463,11 @@ simulate_production (parse_state *ps, symbol_number compat_sym)
 {
   gl_list_t result = parse_state_list_new ();
   const state_item *si = parse_state_tail (ps);
-  bitset prod = si_prods_lookup (si - state_items);
-  if (prod)
+  if (si->prods)
     {
       bitset_iterator biter;
       state_item_number sin;
-      BITSET_FOR_EACH (biter, prod, sin, 0)
+      BITSET_FOR_EACH (biter, si->prods, sin, 0)
         {
           // Take production step only if lhs is not nullable and
           // if first rhs symbol is compatible with compat_sym
@@ -515,7 +514,7 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
   if (s_size != rule_len + 1)
     {
       state_item *tail = (state_item *) new_root->state_items.tail_elt;
-      ps_si_append (new_root, state_items + si_trans[tail - state_items]);
+      ps_si_append (new_root, state_items + tail->trans);
       parse_state_list_append (result, new_root);
     }
   else
@@ -545,7 +544,7 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
               copy = copy_parse_state (false, copy);
               struct si_chunk *sis = &copy->state_items;
               const state_item *tail = sis->tail_elt;
-              ps_si_append (copy, state_items + si_trans[tail - state_items]);
+              ps_si_append (copy, state_items + tail->trans);
               parse_state_list_append (result, copy);
               nullable_closure (copy, (state_item *) sis->tail_elt, result);
             }
@@ -560,12 +559,11 @@ parser_prepend (parse_state *ps)
 {
   gl_list_t result = parse_state_list_new ();
   const state_item *head = ps->state_items.head_elt;
-  bitset prev = si_revs[head - state_items];
   symbol_number prepend_sym =
     item_number_as_symbol_number (*(head->item - 1));
   bitset_iterator biter;
   state_item_number sin;
-  BITSET_FOR_EACH (biter, prev, sin, 0)
+  BITSET_FOR_EACH (biter, head->revs, sin, 0)
   {
     parse_state *copy = copy_parse_state (true, ps);
     ps_si_prepend (copy, state_items + sin);
diff --git a/src/state-item.c b/src/state-item.c
index 62d2d210..23561e87 100644
--- a/src/state-item.c
+++ b/src/state-item.c
@@ -35,10 +35,6 @@ size_t nstate_items;
 state_item_number *state_item_map;
 state_item *state_items;
 
-state_item_number *si_trans;
-bitsetv si_revs;
-Hash_table *si_prods;
-
 // hash functions for index -> bitset hash maps
 typedef struct
 {
@@ -118,7 +114,9 @@ state_item_set (state_item_number sidx, const state *s, item_number off)
   state_items[sidx].state = s;
   state_items[sidx].item = &ritem[off];
   state_items[sidx].lookahead = NULL;
-  si_trans[sidx] = -1;
+  state_items[sidx].trans = -1;
+  state_items[sidx].prods = NULL;
+  state_items[sidx].revs = bitset_create (nstate_items, BITSET_SPARSE);
 }
 
 /**
@@ -144,8 +142,6 @@ init_state_items (void)
     }
   state_item_map = xnmalloc (nstates + 1, sizeof (state_item_number));
   state_items = xnmalloc (nstate_items, sizeof (state_item));
-  si_trans = xnmalloc (nstate_items, sizeof (state_item_number));
-  si_revs = bitsetv_create (nstate_items, nstate_items, BITSET_SPARSE);
   state_item_number sidx = 0;
   for (int i = 0; i < nstates; ++i)
     {
@@ -240,8 +236,8 @@ init_trans (void)
                   state_item_number dstSI =
                     state_item_index_lookup (dst->number, k);
 
-                  si_trans[j] = dstSI;
-                  bitset_set (si_revs[dstSI], j);
+                  state_items[j].trans = dstSI;
+                  bitset_set (state_items[dstSI].revs, j);
                   break;
                 }
             }
@@ -250,16 +246,9 @@ init_trans (void)
     }
 }
 
-bitset
-si_prods_lookup (state_item_number si)
-{
-  return hash_pair_lookup (si_prods, si);
-}
-
 static void
 init_prods (void)
 {
-  si_prods = hash_pair_table_create (nstate_items);
   for (int i = 0; i < nstates; ++i)
     {
       state *s = states[i];
@@ -299,13 +288,13 @@ init_prods (void)
               bitset copy = bitset_create (nstate_items, BITSET_SPARSE);
               bitset_copy (copy, lb);
               // update prods.
-              hash_pair_insert (si_prods, j, copy);
+              state_items[j].prods = copy;
 
               // update revs.
               bitset_iterator biter;
               state_item_number prod;
               BITSET_FOR_EACH (biter, copy, prod, 0)
-                bitset_set (si_revs[prod], j);
+                bitset_set (state_items[prod].revs, j);
             }
         }
       hash_free (closure_map);
@@ -340,7 +329,7 @@ gen_lookaheads (void)
           prev->lookahead = lookahead;
           if (SI_TRANSITION (prev))
             {
-              bitset rsi = si_revs[prev - state_items];
+              bitset rsi = state_items[prev - state_items].revs;
               bitset_iterator biter;
               state_item_number sin;
               BITSET_FOR_EACH (biter, rsi, sin, 0)
@@ -400,8 +389,11 @@ init_firsts (void)
 static inline void
 disable_state_item (state_item_number sin)
 {
-  si_trans[sin] = -2;
-  hash_pair_remove (si_prods, sin);
+  state_item *si = state_items + sin;
+  si->trans = -2;
+  bitset_free (si->revs);
+  if (si->prods)
+    bitset_free (si->prods);
 }
 
 /*
@@ -414,10 +406,10 @@ prune_disabled_paths (void)
   for (int i = nstate_items - 1; i >= 0; --i)
     {
       state_item *si = state_items + i;
-      if (si_trans[i] == -1 && item_number_is_symbol_number (*si->item))
+      if (si->trans == -1 && item_number_is_symbol_number (*si->item))
         {
           // disable the transitions out of i
-          for (state_item_number j = si_trans[i]; j != -1; j = si_trans[j])
+          for (state_item_number j = si->trans; j != -1; j = state_items[j].trans)
             disable_state_item (j);
 
           gl_list_t queue =
@@ -432,9 +424,8 @@ prune_disabled_paths (void)
               const state_item *prev = gl_list_get_at (queue, 0);
               gl_list_remove_at (queue, 0);
               state_item_number prev_num = prev - state_items;
-              disable_state_item (prev_num);
 
-              bitset rsi = si_revs[prev_num];
+              bitset rsi = prev->revs;
               bitset_iterator biter;
               state_item_number sin;
               BITSET_FOR_EACH (biter, rsi, sin, 0)
@@ -443,11 +434,12 @@ prune_disabled_paths (void)
                   gl_list_add_first (queue, &state_items[sin]);
                 else
                   {
-                    bitset p = si_prods_lookup (sin);
+                    bitset p = state_items[sin].prods;
                     if (p)
                       bitset_reset (p, prev_num);
                   }
               }
+              disable_state_item (prev_num);
             }
           gl_list_free (queue);
         }
@@ -463,7 +455,7 @@ print_state_item (const state_item *si, FILE *out)
 }
 
 /**
- * Report set counts and the state_item graph if trace is enabled
+ * Report the state_item graph
  */
 static void
 state_items_report (void)
@@ -474,15 +466,16 @@ state_items_report (void)
       printf ("State %d:\n", i);
       for (int j = state_item_map[i]; j < state_item_map[i + 1]; ++j)
         {
-          item_print (state_items[j].item, NULL, stdout);
+          state_item *si = state_items + j;
+          item_print (si->item, NULL, stdout);
           puts ("");
-          if (si_trans[j] >= 0)
+          if (si->trans >= 0)
             {
               fputs ("    -> ", stdout);
-              print_state_item (state_items + si_trans[j], stdout);
+              print_state_item (state_items + si->trans, stdout);
             }
 
-          bitset sets[2] = { si_prods_lookup (j), si_revs[j] };
+          bitset sets[2] = { si->prods, si->revs };
           const char *txt[2] = { "    => ", "    <- " };
           for (int seti = 0; seti < 2; ++seti)
             {
@@ -533,9 +526,14 @@ state_items_init (void)
 void
 state_items_free (void)
 {
-  hash_free (si_prods);
-  bitsetv_free (si_revs);
-  free (si_trans);
+  for (int i = 0; i < nstate_items; ++i)
+    if (!SI_DISABLED(i))
+      {
+        state_item *si = state_items + i;
+        if (si->prods)
+          bitset_free (si->prods);
+        bitset_free (si->revs);
+      }
   free (state_items);
   bitsetv_free (firsts);
 }
diff --git a/src/state-item.h b/src/state-item.h
index 3b98132d..3e606b6e 100644
--- a/src/state-item.h
+++ b/src/state-item.h
@@ -42,20 +42,18 @@
    There are two type of edges in this graph transitions and
    productions.  Transitions are the same as transitions from the
    parser except edges are only between items from the same
-   rule. These are stored as an array "si_trans" (as most items will
-   have transitions) which are indexed the same way as state_items.
+   rule.
 
    Productions are edges from items with a nonterminal after the dot to
    the production of that nonterminal in the same state. These edges are
-   stored as a hash map "si_prods" from a state_item to a set of what productions
-   it goes from/to
+   stored as a bitset in a state-item.
 
-   The inverses of these edges are stored in an array of bitsets,
-   "si_revs."  A state-item that begins with a dot will have reverse
+   The inverses of these edges are stored in a bitset in the state-item,
+   "revs."  A state-item that begins with a dot will have reverse
    production edges, and all others will have reverse transition
    edges. */
 
-# define SI_DISABLED(sin) (si_trans[sin] == -2)
+# define SI_DISABLED(sin) (state_items[sin].trans == -2)
 # define SI_PRODUCTION(si) ((si) == state_items || *((si)->item - 1) < 0)
 # define SI_TRANSITION(si) ((si) != state_items && *((si)->item - 1) >= 0)
 
@@ -65,6 +63,9 @@ typedef struct
 {
   const state *state;
   item_number *item;
+  state_item_number trans;
+  bitset prods;
+  bitset revs;
   bitset lookahead;
 } state_item;
 
@@ -77,10 +78,6 @@ extern state_item_number *state_item_map;
 /** Array mapping state_item_numbers to state_items */
 extern state_item *state_items;
 
-/** state-item graph edges */
-extern state_item_number *si_trans;
-extern bitsetv si_revs;
-
 state_item *state_item_lookup (state_number s, state_item_number off);
 
 static inline state_item_number
@@ -89,8 +86,6 @@ state_item_index_lookup (state_number s, state_item_number off)
   return state_item_map[s] + off;
 }
 
-bitset si_prods_lookup (state_item_number si);
-
 void state_items_init (void);
 void print_state_item (const state_item *si, FILE *out);
 void state_items_free (void);
-- 
2.20.1 (Apple Git-117)
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.