refactor hashtable iterations to use H_FOREACH

This commit is contained in:
Sven M. Hallberg 2013-06-15 19:06:10 +02:00
parent e56f052255
commit 9a96314931

View file

@ -61,6 +61,27 @@ typedef struct HLREnhGrammar_ {
} HLREnhGrammar; } HLREnhGrammar;
// XXX move to internal.h or something
// XXX replace other hashtable iterations with this
#define H_FOREACH_(HT) { \
const HHashTable *ht__ = HT; \
for(size_t i__=0; i__ < ht__->capacity; i__++) { \
for(HHashTableEntry *hte__ = &ht__->contents[i__]; \
hte__; \
hte__ = hte__->next) { \
if(hte__->key == NULL) continue;
#define H_FOREACH_KEY(HT, KEYVAR) H_FOREACH_(HT) \
const KEYVAR = hte__->key;
#define H_FOREACH(HT, KEYVAR, VALVAR) H_FOREACH_KEY(HT, KEYVAR) \
VALVAR = hte__->value;
#define H_END_FOREACH \
} \
} \
}
// compare symbols - terminals by value, others by pointer // compare symbols - terminals by value, others by pointer
static bool eq_symbol(const void *p, const void *q) static bool eq_symbol(const void *p, const void *q)
{ {
@ -117,15 +138,9 @@ static HHashValue hash_lalr_itemset(const void *p)
{ {
HHashValue hash = 0; HHashValue hash = 0;
const HHashTable *ht = p; H_FOREACH_KEY((const HHashSet *)p, HLRItem *item)
for(size_t i=0; i < ht->capacity; i++) { hash += hash_lalr_item(item);
for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) { H_END_FOREACH
if(hte->key == NULL)
continue;
hash += hash_lalr_item(hte->key);
}
}
return hash; return hash;
} }
@ -179,27 +194,6 @@ void h_lrtable_free(HLRTable *table)
h_free(table); h_free(table);
} }
// XXX replace other hashtable iterations with this
// XXX move to internal.h or something
#define H_FOREACH_(HT) { \
const HHashTable *ht__ = HT; \
for(size_t i__=0; i__ < ht__->capacity; i__++) { \
for(HHashTableEntry *hte__ = &ht__->contents[i__]; \
hte__; \
hte__ = hte__->next) { \
if(hte__->key == NULL) continue;
#define H_FOREACH_KEY(HT, KEYVAR) H_FOREACH_(HT) \
const KEYVAR = hte__->key;
#define H_FOREACH(HT, KEYVAR, VALVAR) H_FOREACH_KEY(HT, KEYVAR) \
VALVAR = hte__->value;
#define H_END_FOREACH \
} \
} \
}
/* Constructing the characteristic automaton (handle recognizer) */ /* Constructing the characteristic automaton (handle recognizer) */
@ -220,18 +214,11 @@ static HHashSet *closure(HCFGrammar *g, const HHashSet *items)
HHashSet *ret = h_lrstate_new(arena); HHashSet *ret = h_lrstate_new(arena);
HSlist *work = h_slist_new(arena); HSlist *work = h_slist_new(arena);
// iterate over items - initialize work list with them // initialize work list with items
const HHashTable *ht = items; H_FOREACH_KEY(items, HLRItem *item)
for(size_t i=0; i < ht->capacity; i++) {
for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
if(hte->key == NULL)
continue;
const HLRItem *item = hte->key;
h_hashset_put(ret, item); h_hashset_put(ret, item);
h_slist_push(work, (void *)item); h_slist_push(work, (void *)item);
} H_END_FOREACH
}
while(!h_slist_empty(work)) { while(!h_slist_empty(work)) {
const HLRItem *item = h_slist_pop(work); const HLRItem *item = h_slist_pop(work);
@ -322,13 +309,7 @@ HLRDFA *h_lr0_dfa(HCFGrammar *g)
HHashTable *neighbors = h_hashtable_new(arena, eq_symbol, hash_symbol); HHashTable *neighbors = h_hashtable_new(arena, eq_symbol, hash_symbol);
// iterate over closure and generate neighboring sets // iterate over closure and generate neighboring sets
const HHashTable *ht = closure(g, state); H_FOREACH_KEY(closure(g, state), HLRItem *item)
for(size_t i=0; i < ht->capacity; i++) {
for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
if(hte->key == NULL)
continue;
const HLRItem *item = hte->key;
HCFChoice *sym = item->rhs[item->mark]; // symbol after mark HCFChoice *sym = item->rhs[item->mark]; // symbol after mark
if(sym != NULL) { // mark was not at the end if(sym != NULL) { // mark was not at the end
@ -342,19 +323,10 @@ HLRDFA *h_lr0_dfa(HCFGrammar *g)
// ...and add the advanced item to it // ...and add the advanced item to it
h_hashset_put(neighbor, advance_mark(arena, item)); h_hashset_put(neighbor, advance_mark(arena, item));
} }
} H_END_FOREACH
}
// merge neighbor sets into the set of existing states // merge neighbor sets into the set of existing states
ht = neighbors; H_FOREACH(neighbors, HCFChoice *symbol, HLRState *neighbor)
for(size_t i=0; i < ht->capacity; i++) {
for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
if(hte->key == NULL)
continue;
const HCFChoice *symbol = hte->key;
HLRState *neighbor = hte->value;
// look up existing state, allocate new if not found // look up existing state, allocate new if not found
size_t neighbor_idx; size_t neighbor_idx;
if(!h_hashset_present(states, neighbor)) { if(!h_hashset_present(states, neighbor)) {
@ -372,25 +344,17 @@ HLRDFA *h_lr0_dfa(HCFGrammar *g)
t->to = neighbor_idx; t->to = neighbor_idx;
t->symbol = symbol; t->symbol = symbol;
h_slist_push(transitions, t); h_slist_push(transitions, t);
} H_END_FOREACH
}
} // end while(work) } // end while(work)
// fill DFA struct // fill DFA struct
HLRDFA *dfa = h_arena_malloc(arena, sizeof(HLRDFA)); HLRDFA *dfa = h_arena_malloc(arena, sizeof(HLRDFA));
dfa->nstates = states->used; dfa->nstates = states->used;
dfa->states = h_arena_malloc(arena, dfa->nstates*sizeof(HLRState *)); dfa->states = h_arena_malloc(arena, dfa->nstates*sizeof(HLRState *));
for(size_t i=0; i < states->capacity; i++) { H_FOREACH(states, HLRState *state, void *v)
for(HHashTableEntry *hte = &states->contents[i]; hte; hte = hte->next) { size_t idx = (uintptr_t)v;
if(hte->key == NULL)
continue;
const HLRState *state = hte->key;
size_t idx = (uintptr_t)hte->value;
dfa->states[idx] = state; dfa->states[idx] = state;
} H_END_FOREACH
}
dfa->transitions = transitions; dfa->transitions = transitions;
return dfa; return dfa;
@ -911,21 +875,13 @@ void h_pprint_lrstate(FILE *f, const HCFGrammar *g,
const HLRState *state, unsigned int indent) const HLRState *state, unsigned int indent)
{ {
bool first = true; bool first = true;
const HHashTable *ht = state; H_FOREACH_KEY(state, HLRItem *item)
for(size_t i=0; i < ht->capacity; i++) {
for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
if(hte->key == NULL)
continue;
const HLRItem *item = hte->key;
if(!first) if(!first)
for(unsigned int i=0; i<indent; i++) fputc(' ', f); for(unsigned int i=0; i<indent; i++) fputc(' ', f);
first = false; first = false;
h_pprint_lritem(f, g, item); h_pprint_lritem(f, g, item);
fputc('\n', f); fputc('\n', f);
} H_END_FOREACH
}
} }
static void pprint_transition(FILE *f, const HCFGrammar *g, const HLRTransition *t) static void pprint_transition(FILE *f, const HCFGrammar *g, const HLRTransition *t)