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
* In fact, the counter may be the hash table size.
*/
* 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,
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;
}
return TRUE;
}
return FALSE;
}
-state_t* item_collection_lookup (GHashTable* collection,
- GHashTable* item_set)
+GHashTable* item_collection_lookup (GHashTable* collection,
+ GHashTable* item_set)
if (!g_hash_table_lookup_extended (collection, item_set,
if (!g_hash_table_lookup_extended (collection, item_set,
- NULL, (gpointer*)&state))
+ NULL, (gpointer*)&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;
#ifdef DEBUG
void item_collection_print_each (gpointer key, gpointer val, gpointer data)
{
GHashTable* item_set;
item_set = (GHashTable*) key;
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");
}
item_set_print (item_set);
fprintf (stdout, "\n");
}
void item_set_print_goto (gpointer key, gpointer val, gpointer data)
{
symbol_t* symbol;
void item_set_print_goto (gpointer key, gpointer val, gpointer data)
{
symbol_t* symbol;
- gint code;
- state_t* state;
symbol = (symbol_t*) key;
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)
{
}
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");
}
fprintf (stdout, "\n");
}
GHashTable* item_collection_goto (GHashTable* collection, Grammar* grammar,
GHashTable* item_set, symbol_t* symbol)
{
GHashTable* item_collection_goto (GHashTable* collection, Grammar* grammar,
GHashTable* item_set, symbol_t* symbol)
{
- state_t* state;
- state_t* goto_state;
GHashTable* newitem_set;
GHashTable* goto_item_set;
GHashTable* newitem_set;
GHashTable* goto_item_set;
- GHashTable* return_item_set;
+ GHashTable* old_item_set;
newitem_set = item_set_copy (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);
}
{
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);
{
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;
+ }
- 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)
}
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_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)
{
new_item_sets = g_list_append (NULL, item_set);
while (new_item_sets != NULL)
{