rename HCFStringMap to HStringMap
This commit is contained in:
parent
8618f9cb62
commit
dba9d41eda
3 changed files with 74 additions and 74 deletions
|
|
@ -8,7 +8,7 @@ static const size_t DEFAULT_KMAX = 1;
|
||||||
|
|
||||||
/* Generating the LL(k) parse table */
|
/* Generating the LL(k) parse table */
|
||||||
|
|
||||||
/* Maps each nonterminal (HCFChoice) of the grammar to a HCFStringMap that
|
/* Maps each nonterminal (HCFChoice) of the grammar to a HStringMap that
|
||||||
* maps lookahead strings to productions (HCFSequence).
|
* maps lookahead strings to productions (HCFSequence).
|
||||||
*/
|
*/
|
||||||
typedef struct HLLkTable_ {
|
typedef struct HLLkTable_ {
|
||||||
|
|
@ -23,13 +23,13 @@ typedef struct HLLkTable_ {
|
||||||
const HCFSequence *h_llk_lookup(const HLLkTable *table, const HCFChoice *x,
|
const HCFSequence *h_llk_lookup(const HLLkTable *table, const HCFChoice *x,
|
||||||
HInputStream lookahead)
|
HInputStream lookahead)
|
||||||
{
|
{
|
||||||
const HCFStringMap *row = h_hashtable_get(table->rows, x);
|
const HStringMap *row = h_hashtable_get(table->rows, x);
|
||||||
assert(row != NULL); // the table should have one row for each nonterminal
|
assert(row != NULL); // the table should have one row for each nonterminal
|
||||||
|
|
||||||
assert(!row->epsilon_branch); // would match without looking at the input
|
assert(!row->epsilon_branch); // would match without looking at the input
|
||||||
// XXX cases where this could be useful?
|
// XXX cases where this could be useful?
|
||||||
|
|
||||||
const HCFStringMap *m = row;
|
const HStringMap *m = row;
|
||||||
while(m) {
|
while(m) {
|
||||||
if(m->epsilon_branch) { // input matched
|
if(m->epsilon_branch) { // input matched
|
||||||
// assert: another lookahead would not bring a more specific match.
|
// assert: another lookahead would not bring a more specific match.
|
||||||
|
|
@ -103,7 +103,7 @@ static void *combine_entries(HHashSet *workset, void *dst, const void *src)
|
||||||
// add the mappings of src to dst, marking conflicts and adding the conflicting
|
// add the mappings of src to dst, marking conflicts and adding the conflicting
|
||||||
// values to workset.
|
// values to workset.
|
||||||
// note: reuses parts of src to build dst!
|
// note: reuses parts of src to build dst!
|
||||||
static void stringmap_merge(HHashSet *workset, HCFStringMap *dst, HCFStringMap *src)
|
static void stringmap_merge(HHashSet *workset, HStringMap *dst, HStringMap *src)
|
||||||
{
|
{
|
||||||
if(src->epsilon_branch) {
|
if(src->epsilon_branch) {
|
||||||
if(dst->epsilon_branch)
|
if(dst->epsilon_branch)
|
||||||
|
|
@ -135,10 +135,10 @@ static void stringmap_merge(HHashSet *workset, HCFStringMap *dst, HCFStringMap *
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
HCharKey c = (HCharKey)hte->key;
|
HCharKey c = (HCharKey)hte->key;
|
||||||
HCFStringMap *src_ = hte->value;
|
HStringMap *src_ = hte->value;
|
||||||
|
|
||||||
if(src_) {
|
if(src_) {
|
||||||
HCFStringMap *dst_ = h_hashtable_get(dst->char_branches, (void *)c);
|
HStringMap *dst_ = h_hashtable_get(dst->char_branches, (void *)c);
|
||||||
if(dst_)
|
if(dst_)
|
||||||
stringmap_merge(workset, dst_, src_);
|
stringmap_merge(workset, dst_, src_);
|
||||||
else
|
else
|
||||||
|
|
@ -149,7 +149,7 @@ static void stringmap_merge(HHashSet *workset, HCFStringMap *dst, HCFStringMap *
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate entries for the productions of 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, HStringMap *row,
|
||||||
const HCFChoice *A)
|
const HCFChoice *A)
|
||||||
{
|
{
|
||||||
HHashSet *workset;
|
HHashSet *workset;
|
||||||
|
|
@ -177,7 +177,7 @@ static int fill_table_row(size_t kmax, HCFGrammar *g, HCFStringMap *row,
|
||||||
assert(rhs != CONFLICT); // just to be sure there's no mixup
|
assert(rhs != CONFLICT); // just to be sure there's no mixup
|
||||||
|
|
||||||
// calculate predict set; let values map to rhs
|
// calculate predict set; let values map to rhs
|
||||||
HCFStringMap *pred = h_predict(k, g, A, rhs);
|
HStringMap *pred = h_predict(k, g, A, rhs);
|
||||||
h_stringmap_replace(pred, NULL, rhs);
|
h_stringmap_replace(pred, NULL, rhs);
|
||||||
|
|
||||||
// merge predict set into the row
|
// merge predict set into the row
|
||||||
|
|
@ -220,7 +220,7 @@ static int fill_table(size_t kmax, HCFGrammar *g, HLLkTable *table)
|
||||||
assert(a->type == HCF_CHOICE);
|
assert(a->type == HCF_CHOICE);
|
||||||
|
|
||||||
// create table row for this nonterminal
|
// create table row for this nonterminal
|
||||||
HCFStringMap *row = h_stringmap_new(table->arena);
|
HStringMap *row = h_stringmap_new(table->arena);
|
||||||
h_hashtable_put(table->rows, a, row);
|
h_hashtable_put(table->rows, a, row);
|
||||||
|
|
||||||
if(fill_table_row(kmax, g, row, a) < 0) {
|
if(fill_table_row(kmax, g, row, a) < 0) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ HCFGrammar *h_cfgrammar_new(HAllocator *mm__)
|
||||||
g->follow = NULL;
|
g->follow = NULL;
|
||||||
g->kmax = 0; // will be increased as needed by ensure_k
|
g->kmax = 0; // will be increased as needed by ensure_k
|
||||||
|
|
||||||
HCFStringMap *eps = h_stringmap_new(g->arena);
|
HStringMap *eps = h_stringmap_new(g->arena);
|
||||||
h_stringmap_put_epsilon(eps, INSET);
|
h_stringmap_put_epsilon(eps, INSET);
|
||||||
g->singleton_epsilon = eps;
|
g->singleton_epsilon = eps;
|
||||||
|
|
||||||
|
|
@ -219,32 +219,32 @@ static void collect_geneps(HCFGrammar *g)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HCFStringMap *h_stringmap_new(HArena *a)
|
HStringMap *h_stringmap_new(HArena *a)
|
||||||
{
|
{
|
||||||
HCFStringMap *m = h_arena_malloc(a, sizeof(HCFStringMap));
|
HStringMap *m = h_arena_malloc(a, sizeof(HStringMap));
|
||||||
m->char_branches = h_hashtable_new(a, h_eq_ptr, h_hash_ptr);
|
m->char_branches = h_hashtable_new(a, h_eq_ptr, h_hash_ptr);
|
||||||
m->arena = a;
|
m->arena = a;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
void h_stringmap_put_end(HCFStringMap *m, void *v)
|
void h_stringmap_put_end(HStringMap *m, void *v)
|
||||||
{
|
{
|
||||||
m->end_branch = v;
|
m->end_branch = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void h_stringmap_put_epsilon(HCFStringMap *m, void *v)
|
void h_stringmap_put_epsilon(HStringMap *m, void *v)
|
||||||
{
|
{
|
||||||
m->epsilon_branch = v;
|
m->epsilon_branch = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void h_stringmap_put_after(HCFStringMap *m, uint8_t c, HCFStringMap *ends)
|
void h_stringmap_put_after(HStringMap *m, uint8_t c, HStringMap *ends)
|
||||||
{
|
{
|
||||||
h_hashtable_put(m->char_branches, (void *)char_key(c), ends);
|
h_hashtable_put(m->char_branches, (void *)char_key(c), ends);
|
||||||
}
|
}
|
||||||
|
|
||||||
void h_stringmap_put_char(HCFStringMap *m, uint8_t c, void *v)
|
void h_stringmap_put_char(HStringMap *m, uint8_t c, void *v)
|
||||||
{
|
{
|
||||||
HCFStringMap *node = h_stringmap_new(m->arena);
|
HStringMap *node = h_stringmap_new(m->arena);
|
||||||
h_stringmap_put_epsilon(node, v);
|
h_stringmap_put_epsilon(node, v);
|
||||||
h_stringmap_put_after(m, c, node);
|
h_stringmap_put_after(m, c, node);
|
||||||
}
|
}
|
||||||
|
|
@ -252,8 +252,8 @@ 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, const void *v2)
|
static void *combine_stringmap(void *v1, const void *v2)
|
||||||
{
|
{
|
||||||
HCFStringMap *m1 = v1;
|
HStringMap *m1 = v1;
|
||||||
const HCFStringMap *m2 = v2;
|
const HStringMap *m2 = v2;
|
||||||
if(!m1)
|
if(!m1)
|
||||||
m1 = h_stringmap_new(m2->arena);
|
m1 = h_stringmap_new(m2->arena);
|
||||||
h_stringmap_update(m1, m2);
|
h_stringmap_update(m1, m2);
|
||||||
|
|
@ -262,7 +262,7 @@ static void *combine_stringmap(void *v1, const void *v2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: Does *not* reuse submaps from n in building m. */
|
/* Note: Does *not* reuse submaps from n in building m. */
|
||||||
void h_stringmap_update(HCFStringMap *m, const HCFStringMap *n)
|
void h_stringmap_update(HStringMap *m, const HStringMap *n)
|
||||||
{
|
{
|
||||||
if(n->epsilon_branch)
|
if(n->epsilon_branch)
|
||||||
m->epsilon_branch = n->epsilon_branch;
|
m->epsilon_branch = n->epsilon_branch;
|
||||||
|
|
@ -277,7 +277,7 @@ void h_stringmap_update(HCFStringMap *m, const HCFStringMap *n)
|
||||||
* If old is NULL, replace all values in m with new.
|
* If old is NULL, replace all values in m with new.
|
||||||
* If new is NULL, remove the respective values.
|
* If new is NULL, remove the respective values.
|
||||||
*/
|
*/
|
||||||
void h_stringmap_replace(HCFStringMap *m, void *old, void *new)
|
void h_stringmap_replace(HStringMap *m, void *old, void *new)
|
||||||
{
|
{
|
||||||
if(!old) {
|
if(!old) {
|
||||||
if(m->epsilon_branch) m->epsilon_branch = new;
|
if(m->epsilon_branch) m->epsilon_branch = new;
|
||||||
|
|
@ -294,14 +294,14 @@ void h_stringmap_replace(HCFStringMap *m, void *old, void *new)
|
||||||
if(hte->key == NULL)
|
if(hte->key == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
HCFStringMap *m_ = hte->value;
|
HStringMap *m_ = hte->value;
|
||||||
if(m_)
|
if(m_)
|
||||||
h_stringmap_replace(m_, old, new);
|
h_stringmap_replace(m_, old, new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *h_stringmap_get(const HCFStringMap *m, const uint8_t *str, size_t n, bool end)
|
void *h_stringmap_get(const HStringMap *m, const uint8_t *str, size_t n, bool end)
|
||||||
{
|
{
|
||||||
for(size_t i=0; i<n; i++) {
|
for(size_t i=0; i<n; i++) {
|
||||||
if(i==n-1 && end && m->end_branch)
|
if(i==n-1 && end && m->end_branch)
|
||||||
|
|
@ -313,20 +313,20 @@ void *h_stringmap_get(const HCFStringMap *m, const uint8_t *str, size_t n, bool
|
||||||
return m->epsilon_branch;
|
return m->epsilon_branch;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool h_stringmap_present(const HCFStringMap *m, const uint8_t *str, size_t n, bool end)
|
bool h_stringmap_present(const HStringMap *m, const uint8_t *str, size_t n, bool end)
|
||||||
{
|
{
|
||||||
return (h_stringmap_get(m, str, n, end) != NULL);
|
return (h_stringmap_get(m, str, n, end) != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool h_stringmap_present_epsilon(const HCFStringMap *m)
|
bool h_stringmap_present_epsilon(const HStringMap *m)
|
||||||
{
|
{
|
||||||
return (m->epsilon_branch != NULL);
|
return (m->epsilon_branch != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const HCFStringMap *h_first(size_t k, HCFGrammar *g, const HCFChoice *x)
|
const HStringMap *h_first(size_t k, HCFGrammar *g, const HCFChoice *x)
|
||||||
{
|
{
|
||||||
HCFStringMap *ret;
|
HStringMap *ret;
|
||||||
HCFSequence **p;
|
HCFSequence **p;
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
|
||||||
|
|
@ -372,18 +372,18 @@ const HCFStringMap *h_first(size_t k, HCFGrammar *g, const HCFChoice *x)
|
||||||
}
|
}
|
||||||
|
|
||||||
// helpers for h_first_seq, definitions below
|
// helpers for h_first_seq, definitions below
|
||||||
static bool is_singleton_epsilon(const HCFStringMap *m);
|
static bool is_singleton_epsilon(const HStringMap *m);
|
||||||
static bool any_string_shorter(size_t k, const HCFStringMap *m);
|
static bool any_string_shorter(size_t k, const HStringMap *m);
|
||||||
|
|
||||||
// pointer to functions like h_first_seq
|
// pointer to functions like h_first_seq
|
||||||
typedef const HCFStringMap *(*StringSetFun)(size_t, HCFGrammar *, HCFChoice **);
|
typedef const HStringMap *(*StringSetFun)(size_t, HCFGrammar *, HCFChoice **);
|
||||||
|
|
||||||
// helper for h_first_seq and h_follow
|
// helper for h_first_seq and h_follow
|
||||||
static void stringset_extend(HCFGrammar *g, HCFStringMap *ret,
|
static void stringset_extend(HCFGrammar *g, HStringMap *ret,
|
||||||
size_t k, const HCFStringMap *as,
|
size_t k, const HStringMap *as,
|
||||||
StringSetFun f, HCFChoice **tail);
|
StringSetFun f, HCFChoice **tail);
|
||||||
|
|
||||||
const HCFStringMap *h_first_seq(size_t k, HCFGrammar *g, HCFChoice **s)
|
const HStringMap *h_first_seq(size_t k, HCFGrammar *g, HCFChoice **s)
|
||||||
{
|
{
|
||||||
// shortcut: the first set of the empty sequence, for any k, is {""}
|
// shortcut: the first set of the empty sequence, for any k, is {""}
|
||||||
if(*s == NULL)
|
if(*s == NULL)
|
||||||
|
|
@ -394,7 +394,7 @@ const HCFStringMap *h_first_seq(size_t k, HCFGrammar *g, HCFChoice **s)
|
||||||
HCFChoice *x = s[0];
|
HCFChoice *x = s[0];
|
||||||
HCFChoice **tail = s+1;
|
HCFChoice **tail = s+1;
|
||||||
|
|
||||||
const HCFStringMap *first_x = h_first(k, g, x);
|
const HStringMap *first_x = h_first(k, g, x);
|
||||||
|
|
||||||
// shortcut: if first_k(X) = {""}, just return first_k(tail)
|
// shortcut: if first_k(X) = {""}, just return first_k(tail)
|
||||||
if(is_singleton_epsilon(first_x))
|
if(is_singleton_epsilon(first_x))
|
||||||
|
|
@ -405,7 +405,7 @@ const HCFStringMap *h_first_seq(size_t k, HCFGrammar *g, HCFChoice **s)
|
||||||
return first_x;
|
return first_x;
|
||||||
|
|
||||||
// create a new result set and build up the set described above
|
// create a new result set and build up the set described above
|
||||||
HCFStringMap *ret = h_stringmap_new(g->arena);
|
HStringMap *ret = h_stringmap_new(g->arena);
|
||||||
|
|
||||||
// extend the elements of first_k(X) up to length k from tail
|
// extend the elements of first_k(X) up to length k from tail
|
||||||
stringset_extend(g, ret, k, first_x, h_first_seq, tail);
|
stringset_extend(g, ret, k, first_x, h_first_seq, tail);
|
||||||
|
|
@ -413,14 +413,14 @@ const HCFStringMap *h_first_seq(size_t k, HCFGrammar *g, HCFChoice **s)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_singleton_epsilon(const HCFStringMap *m)
|
static bool is_singleton_epsilon(const HStringMap *m)
|
||||||
{
|
{
|
||||||
return ( m->epsilon_branch
|
return ( m->epsilon_branch
|
||||||
&& !m->end_branch
|
&& !m->end_branch
|
||||||
&& h_hashtable_empty(m->char_branches) );
|
&& h_hashtable_empty(m->char_branches) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool any_string_shorter(size_t k, const HCFStringMap *m)
|
static bool any_string_shorter(size_t k, const HStringMap *m)
|
||||||
{
|
{
|
||||||
if(k==0)
|
if(k==0)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -434,7 +434,7 @@ static bool any_string_shorter(size_t k, const HCFStringMap *m)
|
||||||
for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
|
for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
|
||||||
if(hte->key == NULL)
|
if(hte->key == NULL)
|
||||||
continue;
|
continue;
|
||||||
HCFStringMap *m_ = hte->value;
|
HStringMap *m_ = hte->value;
|
||||||
|
|
||||||
// check subtree for strings shorter than k-1
|
// check subtree for strings shorter than k-1
|
||||||
if(any_string_shorter(k-1, m_))
|
if(any_string_shorter(k-1, m_))
|
||||||
|
|
@ -446,7 +446,7 @@ static bool any_string_shorter(size_t k, const HCFStringMap *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper for h_predict
|
// helper for h_predict
|
||||||
static void remove_all_shorter(size_t k, HCFStringMap *m)
|
static void remove_all_shorter(size_t k, HStringMap *m)
|
||||||
{
|
{
|
||||||
if(k==0) return;
|
if(k==0) return;
|
||||||
m->epsilon_branch = NULL;
|
m->epsilon_branch = NULL;
|
||||||
|
|
@ -465,12 +465,12 @@ 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
|
static inline
|
||||||
const HCFStringMap *h_follow_(size_t k, HCFGrammar *g, HCFChoice **s)
|
const HStringMap *h_follow_(size_t k, HCFGrammar *g, HCFChoice **s)
|
||||||
{
|
{
|
||||||
return h_follow(k, g, *s);
|
return h_follow(k, g, *s);
|
||||||
}
|
}
|
||||||
|
|
||||||
const HCFStringMap *h_follow(size_t k, HCFGrammar *g, const HCFChoice *x)
|
const HStringMap *h_follow(size_t k, HCFGrammar *g, const HCFChoice *x)
|
||||||
{
|
{
|
||||||
// consider all occurances of X in g
|
// consider all occurances of X in g
|
||||||
// the follow set of X is the union of:
|
// the follow set of X is the union of:
|
||||||
|
|
@ -481,7 +481,7 @@ const HCFStringMap *h_follow(size_t k, HCFGrammar *g, const HCFChoice *x)
|
||||||
// first_k(tail follow_k(A)) =
|
// first_k(tail follow_k(A)) =
|
||||||
// { a b | a <- first_k(tail), b <- follow_l(A), l=k-|a| }
|
// { a b | a <- first_k(tail), b <- follow_l(A), l=k-|a| }
|
||||||
|
|
||||||
HCFStringMap *ret;
|
HStringMap *ret;
|
||||||
|
|
||||||
// shortcut: follow_0(X) is always {""}
|
// shortcut: follow_0(X) is always {""}
|
||||||
if(k==0)
|
if(k==0)
|
||||||
|
|
@ -519,7 +519,7 @@ const HCFStringMap *h_follow(size_t k, HCFGrammar *g, const HCFChoice *x)
|
||||||
if(*s == x) { // occurance found
|
if(*s == x) { // occurance found
|
||||||
HCFChoice **tail = s+1;
|
HCFChoice **tail = s+1;
|
||||||
|
|
||||||
const HCFStringMap *first_tail = h_first_seq(k, g, tail);
|
const HStringMap *first_tail = h_first_seq(k, g, tail);
|
||||||
|
|
||||||
// extend the elems of first_k(tail) up to length k from follow(A)
|
// extend the elems of first_k(tail) up to length k from follow(A)
|
||||||
stringset_extend(g, ret, k, first_tail, h_follow_, &a);
|
stringset_extend(g, ret, k, first_tail, h_follow_, &a);
|
||||||
|
|
@ -532,15 +532,15 @@ const HCFStringMap *h_follow(size_t k, HCFGrammar *g, const HCFChoice *x)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
HCFStringMap *h_predict(size_t k, HCFGrammar *g,
|
HStringMap *h_predict(size_t k, HCFGrammar *g,
|
||||||
const HCFChoice *A, const HCFSequence *rhs)
|
const HCFChoice *A, const HCFSequence *rhs)
|
||||||
{
|
{
|
||||||
HCFStringMap *ret = h_stringmap_new(g->arena);
|
HStringMap *ret = h_stringmap_new(g->arena);
|
||||||
|
|
||||||
// predict_k(A -> rhs) =
|
// predict_k(A -> rhs) =
|
||||||
// { 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 HStringMap *first_rhs = h_first_seq(k, g, rhs->items);
|
||||||
|
|
||||||
// casting the const off of A below. note: stringset_extend does
|
// casting the const off of A below. note: stringset_extend does
|
||||||
// not touch this argument, only passes it through to h_follow
|
// not touch this argument, only passes it through to h_follow
|
||||||
|
|
@ -554,8 +554,8 @@ HCFStringMap *h_predict(size_t k, HCFGrammar *g,
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the set { a b | a <- as, b <- f_l(S), l=k-|a| } to ret
|
// add the set { a b | a <- as, b <- f_l(S), l=k-|a| } to ret
|
||||||
static void stringset_extend(HCFGrammar *g, HCFStringMap *ret,
|
static void stringset_extend(HCFGrammar *g, HStringMap *ret,
|
||||||
size_t k, const HCFStringMap *as,
|
size_t k, const HStringMap *as,
|
||||||
StringSetFun f, HCFChoice **tail)
|
StringSetFun f, HCFChoice **tail)
|
||||||
{
|
{
|
||||||
if(as->epsilon_branch) {
|
if(as->epsilon_branch) {
|
||||||
|
|
@ -578,12 +578,12 @@ static void stringset_extend(HCFGrammar *g, HCFStringMap *ret,
|
||||||
uint8_t c = key_char((HCharKey)hte->key);
|
uint8_t c = key_char((HCharKey)hte->key);
|
||||||
|
|
||||||
// follow the branch to find the set { a' | t a' <- as }
|
// follow the branch to find the set { a' | t a' <- as }
|
||||||
HCFStringMap *as_ = (HCFStringMap *)hte->value;
|
HStringMap *as_ = (HStringMap *)hte->value;
|
||||||
|
|
||||||
// now the elements of ret that begin with t are given by
|
// now the elements of ret that begin with t are given by
|
||||||
// t { a b | a <- as_, b <- f_l(tail), l=k-|a|-1 }
|
// t { a b | a <- as_, b <- f_l(tail), l=k-|a|-1 }
|
||||||
// so we can use recursion over k
|
// so we can use recursion over k
|
||||||
HCFStringMap *ret_ = h_stringmap_new(g->arena);
|
HStringMap *ret_ = h_stringmap_new(g->arena);
|
||||||
h_stringmap_put_after(ret, c, ret_);
|
h_stringmap_put_after(ret, c, ret_);
|
||||||
|
|
||||||
stringset_extend(g, ret_, k-1, as_, f, tail);
|
stringset_extend(g, ret_, k-1, as_, f, tail);
|
||||||
|
|
@ -800,7 +800,7 @@ void h_pprint_symbolset(FILE *file, const HCFGrammar *g, const HHashSet *set, in
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
pprint_stringset_elems(FILE *file, bool first, char *prefix, size_t n,
|
pprint_stringset_elems(FILE *file, bool first, char *prefix, size_t n,
|
||||||
const HCFStringMap *set)
|
const HStringMap *set)
|
||||||
{
|
{
|
||||||
assert(n < BUFSIZE-4);
|
assert(n < BUFSIZE-4);
|
||||||
|
|
||||||
|
|
@ -827,7 +827,7 @@ pprint_stringset_elems(FILE *file, bool first, char *prefix, size_t n,
|
||||||
if(hte->key == NULL)
|
if(hte->key == NULL)
|
||||||
continue;
|
continue;
|
||||||
uint8_t c = key_char((HCharKey)hte->key);
|
uint8_t c = key_char((HCharKey)hte->key);
|
||||||
HCFStringMap *ends = hte->value;
|
HStringMap *ends = hte->value;
|
||||||
|
|
||||||
size_t n_ = n;
|
size_t n_ = n;
|
||||||
switch(c) {
|
switch(c) {
|
||||||
|
|
@ -852,7 +852,7 @@ pprint_stringset_elems(FILE *file, bool first, char *prefix, size_t n,
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
void h_pprint_stringset(FILE *file, const HCFStringMap *set, int indent)
|
void h_pprint_stringset(FILE *file, const HStringMap *set, int indent)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
for(j=0; j<indent; j++) fputc(' ', file);
|
for(j=0; j<indent; j++) fputc(' ', file);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ typedef struct HCFGrammar_ {
|
||||||
|
|
||||||
// constant set containing only the empty string.
|
// constant set containing only the empty string.
|
||||||
// this is only a member of HCFGrammar because it needs a pointer to arena.
|
// this is only a member of HCFGrammar because it needs a pointer to arena.
|
||||||
const struct HCFStringMap_ *singleton_epsilon;
|
const struct HStringMap_ *singleton_epsilon;
|
||||||
} HCFGrammar;
|
} HCFGrammar;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -32,25 +32,25 @@ static inline uint8_t key_char(HCharKey k) { return (0xFF & k); }
|
||||||
* input tokens.
|
* input tokens.
|
||||||
* Each path through the tree represents the string along its branches.
|
* Each path through the tree represents the string along its branches.
|
||||||
*/
|
*/
|
||||||
typedef struct HCFStringMap_ {
|
typedef struct HStringMap_ {
|
||||||
void *epsilon_branch; // points to leaf value
|
void *epsilon_branch; // points to leaf value
|
||||||
void *end_branch; // points to leaf value
|
void *end_branch; // points to leaf value
|
||||||
HHashTable *char_branches; // maps to inner nodes (HCFStringMaps)
|
HHashTable *char_branches; // maps to inner nodes (HStringMaps)
|
||||||
HArena *arena;
|
HArena *arena;
|
||||||
} HCFStringMap;
|
} HStringMap;
|
||||||
|
|
||||||
HCFStringMap *h_stringmap_new(HArena *a);
|
HStringMap *h_stringmap_new(HArena *a);
|
||||||
void h_stringmap_put_end(HCFStringMap *m, void *v);
|
void h_stringmap_put_end(HStringMap *m, void *v);
|
||||||
void h_stringmap_put_epsilon(HCFStringMap *m, void *v);
|
void h_stringmap_put_epsilon(HStringMap *m, void *v);
|
||||||
void h_stringmap_put_after(HCFStringMap *m, uint8_t c, HCFStringMap *ends);
|
void h_stringmap_put_after(HStringMap *m, uint8_t c, HStringMap *ends);
|
||||||
void h_stringmap_put_char(HCFStringMap *m, uint8_t c, void *v);
|
void h_stringmap_put_char(HStringMap *m, uint8_t c, void *v);
|
||||||
void h_stringmap_update(HCFStringMap *m, const HCFStringMap *n);
|
void h_stringmap_update(HStringMap *m, const HStringMap *n);
|
||||||
void h_stringmap_replace(HCFStringMap *m, void *old, void *new);
|
void h_stringmap_replace(HStringMap *m, void *old, void *new);
|
||||||
void *h_stringmap_get(const HCFStringMap *m, const uint8_t *str, size_t n, bool end);
|
void *h_stringmap_get(const HStringMap *m, const uint8_t *str, size_t n, bool end);
|
||||||
bool h_stringmap_present(const HCFStringMap *m, const uint8_t *str, size_t n, bool end);
|
bool h_stringmap_present(const HStringMap *m, const uint8_t *str, size_t n, bool end);
|
||||||
bool h_stringmap_present_epsilon(const HCFStringMap *m);
|
bool h_stringmap_present_epsilon(const HStringMap *m);
|
||||||
|
|
||||||
static inline HCFStringMap *h_stringmap_get_char(const HCFStringMap *m, const uint8_t c)
|
static inline HStringMap *h_stringmap_get_char(const HStringMap *m, const uint8_t c)
|
||||||
{ return h_hashtable_get(m->char_branches, (void *)char_key(c)); }
|
{ return h_hashtable_get(m->char_branches, (void *)char_key(c)); }
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -72,18 +72,18 @@ bool h_derives_epsilon(HCFGrammar *g, const HCFChoice *symbol);
|
||||||
bool h_derives_epsilon_seq(HCFGrammar *g, HCFChoice **s);
|
bool h_derives_epsilon_seq(HCFGrammar *g, HCFChoice **s);
|
||||||
|
|
||||||
/* Compute first_k set of symbol x. Memoized. */
|
/* Compute first_k set of symbol x. Memoized. */
|
||||||
const HCFStringMap *h_first(size_t k, HCFGrammar *g, const HCFChoice *x);
|
const HStringMap *h_first(size_t k, HCFGrammar *g, const HCFChoice *x);
|
||||||
|
|
||||||
/* Compute first_k set of sentential form s. s NULL-terminated. */
|
/* Compute first_k set of sentential form s. s NULL-terminated. */
|
||||||
const HCFStringMap *h_first_seq(size_t k, HCFGrammar *g, HCFChoice **s);
|
const HStringMap *h_first_seq(size_t k, HCFGrammar *g, HCFChoice **s);
|
||||||
|
|
||||||
/* Compute follow_k set of symbol x. Memoized. */
|
/* Compute follow_k set of symbol x. Memoized. */
|
||||||
const HCFStringMap *h_follow(size_t k, HCFGrammar *g, const HCFChoice *x);
|
const HStringMap *h_follow(size_t k, HCFGrammar *g, const HCFChoice *x);
|
||||||
|
|
||||||
/* Compute the predict_k set of production "A -> rhs".
|
/* Compute the predict_k set of production "A -> rhs".
|
||||||
* Always returns a newly-allocated HCFStringMap.
|
* Always returns a newly-allocated HStringMap.
|
||||||
*/
|
*/
|
||||||
HCFStringMap *h_predict(size_t k, HCFGrammar *g,
|
HStringMap *h_predict(size_t k, HCFGrammar *g,
|
||||||
const HCFChoice *A, const HCFSequence *rhs);
|
const HCFChoice *A, const HCFSequence *rhs);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -92,4 +92,4 @@ void h_pprint_grammar(FILE *file, const HCFGrammar *g, int indent);
|
||||||
void h_pprint_sequence(FILE *f, const HCFGrammar *g, const HCFSequence *seq);
|
void h_pprint_sequence(FILE *f, const HCFGrammar *g, const HCFSequence *seq);
|
||||||
void h_pprint_symbol(FILE *f, const HCFGrammar *g, const HCFChoice *x);
|
void h_pprint_symbol(FILE *f, const HCFGrammar *g, const HCFChoice *x);
|
||||||
void h_pprint_symbolset(FILE *file, const HCFGrammar *g, const HHashSet *set, int indent);
|
void h_pprint_symbolset(FILE *file, const HCFGrammar *g, const HHashSet *set, int indent);
|
||||||
void h_pprint_stringset(FILE *file, const HCFStringMap *set, int indent);
|
void h_pprint_stringset(FILE *file, const HStringMap *set, int indent);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue