diff --git a/src/backends/llk.c b/src/backends/llk.c index 27258e62db9ee53c75a0f19a7b4e0917d3a3f266..59ec790a367e1ea72ed1a427de76a2827329c3db 100644 --- a/src/backends/llk.c +++ b/src/backends/llk.c @@ -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, 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 size_t k; for(k=1; k<=kmax; k++) { - printf("k=%lu\n", k); // XXX debug - // allocate a fresh workset for the next round 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); 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 // accumulates conflicts in new workset 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 h_hashset_free(workset); @@ -343,6 +325,9 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream* if(p == NULL) 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) HCFChoice **s; for(s = p->items; *s; s++); @@ -457,9 +442,9 @@ int test_llk(void) */ HParser *X = h_optional(h_ch('x')); - //HParser *Y = h_epsilon_p(); //h_sequence(h_ch('y'), NULL); - HParser *A = h_sequence(X, h_ch('a'), NULL); - HParser *B = h_sequence(h_ch('b'), NULL); + HParser *Y = h_sequence(h_ch('y'), h_ch('y'), NULL); + HParser *A = h_sequence(X, Y, h_ch('a'), NULL); + HParser *B = h_sequence(Y, h_ch('b'), NULL); HParser *p = h_choice(A, B, NULL); HCFGrammar *g = h_cfgrammar(&system_allocator, p); @@ -477,12 +462,12 @@ int test_llk(void) //printf("follow(C) = "); //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"); return 2; } - HParseResult *res = h_parse(p, (uint8_t *)"ab", 2); + HParseResult *res = h_parse(p, (uint8_t *)"xyya", 4); if(res) h_pprint(stdout, res->ast, 0, 2); else diff --git a/src/cfgrammar.c b/src/cfgrammar.c index d774dd0938d2168b640089c094e17614e40d9380..0ce3cbf2ff8046d93b1a1f70ffa4379521e1489e 100644 --- a/src/cfgrammar.c +++ b/src/cfgrammar.c @@ -248,12 +248,18 @@ void h_stringmap_put_char(HCFStringMap *m, uint8_t c, void *v) } // 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); - return v1; + HCFStringMap *m1 = 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) { 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 -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); } @@ -532,6 +539,10 @@ HCFStringMap *h_predict(size_t k, HCFGrammar *g, // { ab | a <- first_k(rhs), b <- follow_k(A), |ab|=k } 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); // make sure there are only strings of length _exactly_ k diff --git a/src/datastructures.c b/src/datastructures.c index 99b4ca5736e72b2bb84689e154be79f0397e94f8..a12707ef9758db93ad79dc052533b40cdd4edcbb 100644 --- a/src/datastructures.c +++ b/src/datastructures.c @@ -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) { size_t i; 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) { if(hte->key == NULL) continue; - void *oldvalue = h_hashtable_get(dst, hte->key); - void *newvalue; - if(oldvalue) - newvalue = combine(oldvalue, hte->value); - else - newvalue = hte->value; - h_hashtable_put(dst, hte->key, newvalue); + void *dstvalue = h_hashtable_get(dst, hte->key); + void *srcvalue = hte->value; + h_hashtable_put(dst, hte->key, combine(dstvalue, srcvalue)); } } } diff --git a/src/internal.h b/src/internal.h index 889e5c3b1c377d567a0d79fcc632d3dc8e8b36f7..7655afa0a8fc62416f5fb771b55bac0f86d7be07 100644 --- a/src/internal.h +++ b/src/internal.h @@ -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_put(HHashTable* ht, const void* key, void* value); 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); int h_hashtable_present(const HHashTable* ht, const void* key); void h_hashtable_del(HHashTable* ht, const void* key);