State numbers are not defined in items modules
authorThadeu Lima de Souza Cascardo <cascardo@dcc.ufmg.br>
Mon, 3 Oct 2005 00:27:20 +0000 (00:27 +0000)
committerThadeu Lima de Souza Cascardo <cascardo@dcc.ufmg.br>
Mon, 3 Oct 2005 00:27:20 +0000 (00:27 +0000)
Do not define state numbers for each item set. Instead, let the goto
point to another key in the hash table, so they can uniquely be
referenced by their memory address. Any other code can associate any
state number it finds more suitable.

git-archimport-id: cascardo@tlscascardo--private/libgrammatic--dev--0.1--patch-19

item.c

diff --git a/item.c b/item.c
index 9c05e06..8634d90 100644 (file)
--- a/item.c
+++ b/item.c
@@ -282,66 +282,46 @@ GHashTable* item_set_goto (GHashTable* item_set, Grammar* grammar,
  * In fact, the counter may be the hash table size.
  */
 
-typedef struct
-{
-  GHashTable* symbols;
-  gint code;
-} state_t;
-
-state_t* state_new (gint code)
-{
-  state_t* state;
-  state = g_malloc (sizeof (state_t));
-  state->code = code;
-  state->symbols = g_hash_table_new_full (symbol_hash, symbol_equal,
-                                         g_free, NULL);
-  return state;
-}
-
-void state_delete (state_t* state)
-{
-  g_hash_table_destroy (state->symbols);
-  g_free (state);
-}
-
 GHashTable* item_collection_new ()
 {
   return g_hash_table_new_full (item_set_hash, item_set_equal,
-                               g_hash_table_destroy, state_delete);
+                               g_hash_table_destroy, g_hash_table_destroy);
 }
 
-gboolean item_collection_add (GHashTable* collection, GHashTable* item_set)
+gboolean item_collection_add (GHashTable* collection, GHashTable* item_set,
+                             GHashTable** key)
 {
-  if (!g_hash_table_lookup_extended (collection, item_set, NULL, NULL))
+  if (!g_hash_table_lookup_extended (collection, item_set,
+                                    (gpointer*)key, NULL))
     {
-      state_t* state;
-      state = state_new (g_hash_table_size (collection));
-      g_hash_table_insert (collection, item_set, state);
+      GHashTable* symbols;
+      symbols = g_hash_table_new_full (symbol_hash, symbol_equal,
+                                      g_free, NULL);
+      g_hash_table_insert (collection, item_set, symbols);
       return TRUE;
     }
   return FALSE;
 }
 
-state_t* item_collection_lookup (GHashTable* collection,
-                                GHashTable* item_set)
+GHashTable* item_collection_lookup (GHashTable* collection,
+                                   GHashTable* item_set)
 {
-  state_t* state;
+  GHashTable* symbols;
   if (!g_hash_table_lookup_extended (collection, item_set,
-                                    NULL, (gpointer*)&state))
+                                    NULL, (gpointer*)&symbols))
     {
       return NULL;
     }
-  return state;
+  return symbols;
 }
 
+#define HASH_ITEM_SET(item_set) (((GPOINTER_TO_INT(item_set) & 0x3f00) >> 8))
 #ifdef DEBUG
 void item_collection_print_each (gpointer key, gpointer val, gpointer data)
 {
   GHashTable* item_set;
-  state_t* state;
   item_set = (GHashTable*) key;
-  state = (state_t*) val;
-  fprintf (stdout, "Item %d:\n", state->code);
+  fprintf (stdout, "Item %x:\n", HASH_ITEM_SET(key));
   item_set_print (item_set);
   fprintf (stdout, "\n");
 }
@@ -349,20 +329,16 @@ void item_collection_print_each (gpointer key, gpointer val, gpointer data)
 void item_set_print_goto (gpointer key, gpointer val, gpointer data)
 {
   symbol_t* symbol;
-  gint code;
-  state_t* state;
   symbol = (symbol_t*) key;
-  code = GINT_TO_POINTER (val);
-  state = (state_t*) data;
-  fprintf (stdout, "GOTO (%d, %s) =\t %d\n", state->code,
-          g_quark_to_string (symbol->value), code);
+  fprintf (stdout, "GOTO (%x, %s) =\t %x\n", HASH_ITEM_SET(data),
+          g_quark_to_string (symbol->value), HASH_ITEM_SET(val));
 }
 
 void item_collection_print_goto (gpointer key, gpointer val, gpointer data)
 {
-  state_t* state;
-  state = (state_t*) val;
-  g_hash_table_foreach (state->symbols, item_set_print_goto, state);
+  GHashTable* symbols;
+  symbols = (GHashTable*) val;
+  g_hash_table_foreach (symbols, item_set_print_goto, key);
   fprintf (stdout, "\n");
 }
 
@@ -376,30 +352,32 @@ void item_collection_print (GHashTable* collection)
 GHashTable* item_collection_goto (GHashTable* collection, Grammar* grammar,
                                  GHashTable* item_set, symbol_t* symbol)
 {
-  state_t* state;
-  state_t* goto_state;
+  GHashTable* symbols;
   GHashTable* newitem_set;
   GHashTable* goto_item_set;
-  GHashTable* return_item_set;
+  GHashTable* old_item_set;
   newitem_set = item_set_copy (item_set);
-  if (!item_collection_add (collection, newitem_set))
+  if (!item_collection_add (collection, newitem_set, NULL))
     {
       g_hash_table_destroy (newitem_set);
     }
-  state = item_collection_lookup (collection, item_set);
-  if (g_hash_table_lookup_extended (state->symbols, symbol, NULL, NULL))
+  symbols = item_collection_lookup (collection, item_set);
+  if (g_hash_table_lookup_extended (symbols, symbol, NULL, NULL))
     {
       return NULL;
     }
   goto_item_set = item_set_goto (item_set, grammar, symbol);
-  if (!item_collection_add (collection, goto_item_set))
-    return_item_set = NULL;
+  if (!item_collection_add (collection, goto_item_set, &old_item_set))
+    {
+      g_hash_table_insert (symbols, symbol, old_item_set);
+      g_hash_table_destroy (goto_item_set);
+      return NULL;
+    }
   else
-    return_item_set = goto_item_set;
-  goto_state = item_collection_lookup (collection, goto_item_set);
-  g_hash_table_insert (state->symbols, symbol,
-                      GINT_TO_POINTER (goto_state->code));
-  return return_item_set;
+    {
+      g_hash_table_insert (symbols, symbol, goto_item_set);
+      return goto_item_set;
+    }
 }
 
 void item_set_collection (Grammar* grammar, symbol_t* start)
@@ -417,7 +395,7 @@ void item_set_collection (Grammar* grammar, symbol_t* start)
   item_set_closure (item_set, grammar);
   collection = g_hash_table_new_full (item_set_hash, item_set_equal,
                                      g_hash_table_destroy, NULL);
-  item_collection_add (collection, item_set);
+  item_collection_add (collection, item_set, NULL);
   new_item_sets = g_list_append (NULL, item_set);
   while (new_item_sets != NULL)
     {