No more cycles in table generation! (Merge branch 'LL' of https://github.com/pesco/hammer)
This commit is contained in:
commit
b6d9c0c0c4
4 changed files with 29 additions and 37 deletions
|
|
@ -148,7 +148,7 @@ static void stringmap_merge(HHashSet *workset, HCFStringMap *dst, HCFStringMap *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate entries for the production "A" in the given table row. */
|
/* Generate entries for the productions of A in the given table row. */
|
||||||
static int fill_table_row(size_t kmax, HCFGrammar *g, HCFStringMap *row,
|
static int fill_table_row(size_t kmax, HCFGrammar *g, HCFStringMap *row,
|
||||||
const HCFChoice *A)
|
const HCFChoice *A)
|
||||||
{
|
{
|
||||||
|
|
@ -162,8 +162,6 @@ static int fill_table_row(size_t kmax, HCFGrammar *g, HCFStringMap *row,
|
||||||
// run until workset exhausted or kmax hit
|
// run until workset exhausted or kmax hit
|
||||||
size_t k;
|
size_t k;
|
||||||
for(k=1; k<=kmax; k++) {
|
for(k=1; k<=kmax; k++) {
|
||||||
printf("k=%lu\n", k); // XXX debug
|
|
||||||
|
|
||||||
// allocate a fresh workset for the next round
|
// allocate a fresh workset for the next round
|
||||||
HHashSet *nextset = h_hashset_new(g->arena, h_eq_ptr, h_hash_ptr);
|
HHashSet *nextset = h_hashset_new(g->arena, h_eq_ptr, h_hash_ptr);
|
||||||
|
|
||||||
|
|
@ -182,27 +180,11 @@ static int fill_table_row(size_t kmax, HCFGrammar *g, HCFStringMap *row,
|
||||||
HCFStringMap *pred = h_predict(k, g, A, rhs);
|
HCFStringMap *pred = h_predict(k, g, A, rhs);
|
||||||
h_stringmap_replace(pred, NULL, rhs);
|
h_stringmap_replace(pred, NULL, rhs);
|
||||||
|
|
||||||
// XXX debug
|
|
||||||
printf("predict(");
|
|
||||||
h_pprint_sequence(stdout, g, rhs);
|
|
||||||
printf(") = ");
|
|
||||||
h_pprint_stringset(stdout, pred, 0);
|
|
||||||
|
|
||||||
// merge predict set into the row
|
// merge predict set into the row
|
||||||
// accumulates conflicts in new workset
|
// accumulates conflicts in new workset
|
||||||
stringmap_merge(nextset, row, pred);
|
stringmap_merge(nextset, row, pred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX debug
|
|
||||||
printf("row(");
|
|
||||||
h_pprint_symbol(stdout, g, A);
|
|
||||||
printf(") = ");
|
|
||||||
h_pprint_stringset(stdout, row, 0);
|
|
||||||
if(h_stringmap_get(row, (uint8_t *)"a", 1, false)) {
|
|
||||||
printf(" a -> ");
|
|
||||||
h_pprint_sequence(stdout, g, h_stringmap_get(row, (uint8_t *)"a", 1, false));
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// switch to the updated workset
|
// switch to the updated workset
|
||||||
h_hashset_free(workset);
|
h_hashset_free(workset);
|
||||||
|
|
@ -343,6 +325,9 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
||||||
if(p == NULL)
|
if(p == NULL)
|
||||||
goto no_parse;
|
goto no_parse;
|
||||||
|
|
||||||
|
// an infinite loop case that shouldn't happen
|
||||||
|
assert(!p->items[0] || p->items[0] != x);
|
||||||
|
|
||||||
// push production's rhs onto the stack (in reverse order)
|
// push production's rhs onto the stack (in reverse order)
|
||||||
HCFChoice **s;
|
HCFChoice **s;
|
||||||
for(s = p->items; *s; s++);
|
for(s = p->items; *s; s++);
|
||||||
|
|
@ -457,9 +442,9 @@ int test_llk(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HParser *X = h_optional(h_ch('x'));
|
HParser *X = h_optional(h_ch('x'));
|
||||||
//HParser *Y = h_epsilon_p(); //h_sequence(h_ch('y'), NULL);
|
HParser *Y = h_sequence(h_ch('y'), h_ch('y'), NULL);
|
||||||
HParser *A = h_sequence(X, h_ch('a'), NULL);
|
HParser *A = h_sequence(X, Y, h_ch('a'), NULL);
|
||||||
HParser *B = h_sequence(h_ch('b'), NULL);
|
HParser *B = h_sequence(Y, h_ch('b'), NULL);
|
||||||
HParser *p = h_choice(A, B, NULL);
|
HParser *p = h_choice(A, B, NULL);
|
||||||
|
|
||||||
HCFGrammar *g = h_cfgrammar(&system_allocator, p);
|
HCFGrammar *g = h_cfgrammar(&system_allocator, p);
|
||||||
|
|
@ -477,12 +462,12 @@ int test_llk(void)
|
||||||
//printf("follow(C) = ");
|
//printf("follow(C) = ");
|
||||||
//h_pprint_stringset(stdout, h_follow(3, g, h_desugar(&system_allocator, c)), 0);
|
//h_pprint_stringset(stdout, h_follow(3, g, h_desugar(&system_allocator, c)), 0);
|
||||||
|
|
||||||
if(h_compile(p, PB_LLk, (void *)2)) {
|
if(h_compile(p, PB_LLk, (void *)3)) {
|
||||||
fprintf(stderr, "does not compile\n");
|
fprintf(stderr, "does not compile\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
HParseResult *res = h_parse(p, (uint8_t *)"ab", 2);
|
HParseResult *res = h_parse(p, (uint8_t *)"xyya", 4);
|
||||||
if(res)
|
if(res)
|
||||||
h_pprint(stdout, res->ast, 0, 2);
|
h_pprint(stdout, res->ast, 0, 2);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -248,12 +248,18 @@ void h_stringmap_put_char(HCFStringMap *m, uint8_t c, void *v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper for h_stringmap_update
|
// helper for h_stringmap_update
|
||||||
static void *combine_stringmap(void *v1, void *v2)
|
static void *combine_stringmap(void *v1, const void *v2)
|
||||||
{
|
{
|
||||||
h_stringmap_update((HCFStringMap *)v1, (HCFStringMap *)v2);
|
HCFStringMap *m1 = v1;
|
||||||
return v1;
|
const HCFStringMap *m2 = v2;
|
||||||
|
if(!m1)
|
||||||
|
m1 = h_stringmap_new(m2->arena);
|
||||||
|
h_stringmap_update(m1, m2);
|
||||||
|
|
||||||
|
return m1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note: Does *not* reuse submaps from n in building m. */
|
||||||
void h_stringmap_update(HCFStringMap *m, const HCFStringMap *n)
|
void h_stringmap_update(HCFStringMap *m, const HCFStringMap *n)
|
||||||
{
|
{
|
||||||
if(n->epsilon_branch)
|
if(n->epsilon_branch)
|
||||||
|
|
@ -456,7 +462,8 @@ static void remove_all_shorter(size_t k, HCFStringMap *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// h_follow adapted to the signature of StringSetFun
|
// h_follow adapted to the signature of StringSetFun
|
||||||
static inline const HCFStringMap *h_follow_(size_t k, HCFGrammar *g, HCFChoice **s)
|
static inline
|
||||||
|
const HCFStringMap *h_follow_(size_t k, HCFGrammar *g, HCFChoice **s)
|
||||||
{
|
{
|
||||||
return h_follow(k, g, *s);
|
return h_follow(k, g, *s);
|
||||||
}
|
}
|
||||||
|
|
@ -532,6 +539,10 @@ HCFStringMap *h_predict(size_t k, HCFGrammar *g,
|
||||||
// { ab | a <- first_k(rhs), b <- follow_k(A), |ab|=k }
|
// { ab | a <- first_k(rhs), b <- follow_k(A), |ab|=k }
|
||||||
|
|
||||||
const HCFStringMap *first_rhs = h_first_seq(k, g, rhs->items);
|
const HCFStringMap *first_rhs = h_first_seq(k, g, rhs->items);
|
||||||
|
|
||||||
|
// casting the const off of A below. note: stringset_extend does
|
||||||
|
// not touch this argument, only passes it through to h_follow
|
||||||
|
// in this case, which accepts it, once again, as const.
|
||||||
stringset_extend(g, ret, k, first_rhs, h_follow_, (HCFChoice **)&A);
|
stringset_extend(g, ret, k, first_rhs, h_follow_, (HCFChoice **)&A);
|
||||||
|
|
||||||
// make sure there are only strings of length _exactly_ k
|
// make sure there are only strings of length _exactly_ k
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ void h_hashtable_update(HHashTable *dst, const HHashTable *src) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void h_hashtable_merge(void *(*combine)(void *v1, void *v2),
|
void h_hashtable_merge(void *(*combine)(void *v1, const void *v2),
|
||||||
HHashTable *dst, const HHashTable *src) {
|
HHashTable *dst, const HHashTable *src) {
|
||||||
size_t i;
|
size_t i;
|
||||||
HHashTableEntry *hte;
|
HHashTableEntry *hte;
|
||||||
|
|
@ -209,13 +209,9 @@ void h_hashtable_merge(void *(*combine)(void *v1, void *v2),
|
||||||
for(hte = &src->contents[i]; hte; hte = hte->next) {
|
for(hte = &src->contents[i]; hte; hte = hte->next) {
|
||||||
if(hte->key == NULL)
|
if(hte->key == NULL)
|
||||||
continue;
|
continue;
|
||||||
void *oldvalue = h_hashtable_get(dst, hte->key);
|
void *dstvalue = h_hashtable_get(dst, hte->key);
|
||||||
void *newvalue;
|
void *srcvalue = hte->value;
|
||||||
if(oldvalue)
|
h_hashtable_put(dst, hte->key, combine(dstvalue, srcvalue));
|
||||||
newvalue = combine(oldvalue, hte->value);
|
|
||||||
else
|
|
||||||
newvalue = hte->value;
|
|
||||||
h_hashtable_put(dst, hte->key, newvalue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -255,7 +255,7 @@ HHashTable* h_hashtable_new(HArena *arena, HEqualFunc equalFunc, HHashFunc hashF
|
||||||
void* h_hashtable_get(const HHashTable* ht, const void* key);
|
void* h_hashtable_get(const HHashTable* ht, const void* key);
|
||||||
void h_hashtable_put(HHashTable* ht, const void* key, void* value);
|
void h_hashtable_put(HHashTable* ht, const void* key, void* value);
|
||||||
void h_hashtable_update(HHashTable* dst, const HHashTable *src);
|
void h_hashtable_update(HHashTable* dst, const HHashTable *src);
|
||||||
void h_hashtable_merge(void *(*combine)(void *v1, void *v2),
|
void h_hashtable_merge(void *(*combine)(void *v1, const void *v2),
|
||||||
HHashTable *dst, const HHashTable *src);
|
HHashTable *dst, const HHashTable *src);
|
||||||
int h_hashtable_present(const HHashTable* ht, const void* key);
|
int h_hashtable_present(const HHashTable* ht, const void* key);
|
||||||
void h_hashtable_del(HHashTable* ht, const void* key);
|
void h_hashtable_del(HHashTable* ht, const void* key);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue