add (untested) follow set computation
This commit is contained in:
parent
85aaf94332
commit
950bed8b8c
1 changed files with 56 additions and 1 deletions
|
|
@ -10,7 +10,8 @@ typedef struct HCFGrammar_ {
|
|||
HHashSet *nts; // HCFChoices, each representing the alternative
|
||||
// productions for one nonterminal
|
||||
HHashSet *geneps; // set of NTs that can generate the empty string
|
||||
HHashTable *first; // memoized "first" sets of the grammar's symbols
|
||||
HHashTable *first; // memoized first sets of the grammar's symbols
|
||||
HHashTable *follow; // memoized follow sets of the grammar's NTs
|
||||
HArena *arena;
|
||||
} HCFGrammar;
|
||||
|
||||
|
|
@ -247,6 +248,60 @@ HHashSet *h_first_sequence(HCFGrammar *g, HCFChoice **s)
|
|||
}
|
||||
|
||||
|
||||
/* Compute follow set of symbol x. Memoized. */
|
||||
HHashSet *h_follow(HCFGrammar *g, const HCFChoice *x)
|
||||
{
|
||||
// consider all occurances of X in g
|
||||
// the follow set of X is the union of:
|
||||
// given a production "A -> alpha X tail":
|
||||
// if tail derives epsilon:
|
||||
// first(tail) u follow(A)
|
||||
// else:
|
||||
// first(tail)
|
||||
|
||||
HHashSet *ret;
|
||||
|
||||
// memoize via g->follow
|
||||
assert(g->follow != NULL);
|
||||
ret = h_hashtable_get(g->follow, x);
|
||||
if(ret != NULL)
|
||||
return ret;
|
||||
ret = h_hashset_new(g->arena, h_eq_ptr, h_hash_ptr);
|
||||
assert(ret != NULL);
|
||||
h_hashtable_put(g->follow, x, ret);
|
||||
|
||||
// iterate over g->nts
|
||||
size_t i;
|
||||
HHashTableEntry *hte;
|
||||
for(i=0; i < g->nts->capacity; i++) {
|
||||
for(hte = &g->nts->contents[i]; hte; hte = hte->next) {
|
||||
const HCFChoice *a = hte->key; // production's left-hand symbol
|
||||
|
||||
// X can only occur in a proper HCF_CHOICE
|
||||
if(a->type != HCF_CHOICE) continue;
|
||||
|
||||
// iterate over the productions for A
|
||||
HCFSequence **p;
|
||||
for(p=a->seq; *p; p++) {
|
||||
HCFChoice **s = (*p)->items; // production's right-hand side
|
||||
|
||||
for(; *s; s++) {
|
||||
if(*s == x) { // occurance found
|
||||
HCFChoice **tail = s+1;
|
||||
|
||||
h_hashset_put_all(ret, h_first_sequence(g, tail));
|
||||
if(h_sequence_derives_epsilon(g, tail))
|
||||
h_hashset_put_all(ret, h_follow(g, a));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* LL parse table and associated data */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue