consider HCF_CHARSET terminal symbols (as the LL driver already treats them)

This commit is contained in:
Sven M. Hallberg 2013-05-14 16:15:58 +02:00
parent efae603c6b
commit c794be5b6f
2 changed files with 21 additions and 32 deletions

View file

@ -113,6 +113,7 @@ static int fill_table(HCFGrammar *g, HLLkTable *table)
if(hte->key == NULL)
continue;
const HCFChoice *a = hte->key; // production's left-hand symbol
assert(a->type == HCF_CHOICE);
// create table row for this nonterminal
HHashTable *row = h_hashtable_new(table->arena, h_eq_ptr, h_hash_ptr);

View file

@ -100,6 +100,8 @@ static void collect_nts(HCFGrammar *grammar, HCFChoice *symbol)
break; // it's a terminal symbol, nothing to do
case HCF_CHARSET:
break; // NB charsets are considered terminal, too
case HCF_CHOICE:
// exploiting the fact that HHashSet is also a HHashTable to number the
// nonterminals.
@ -107,7 +109,6 @@ static void collect_nts(HCFGrammar *grammar, HCFChoice *symbol)
h_hashtable_put(grammar->nts, symbol,
(void *)(uintptr_t)grammar->nts->used);
if(symbol->type == HCF_CHOICE) {
// each element s of symbol->seq (HCFSequence) represents the RHS of
// a production. call self on all symbols (HCFChoice) in s.
for(s = symbol->seq; *s != NULL; s++) {
@ -115,7 +116,6 @@ static void collect_nts(HCFGrammar *grammar, HCFChoice *symbol)
collect_nts(grammar, *x);
}
}
}
break;
default: // should not be reachable
@ -172,10 +172,7 @@ static void collect_geneps(HCFGrammar *g)
if(hte->key == NULL)
continue;
const HCFChoice *symbol = hte->key;
// only "choice" nonterminals can derive epsilon.
if(symbol->type != HCF_CHOICE)
continue;
assert(symbol->type == HCF_CHOICE);
// this NT derives epsilon if any of its productions does.
HCFSequence **p;
@ -298,9 +295,7 @@ HHashSet *h_follow(HCFGrammar *g, const HCFChoice *x)
if(hte->key == NULL)
continue;
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;
assert(a->type == HCF_CHOICE);
// iterate over the productions for A
HCFSequence **p;
@ -412,6 +407,8 @@ static void pprint_symbol(FILE *f, const HCFGrammar *g, const HCFChoice *x)
case HCF_END:
fputc('$', f);
break;
case HCF_CHARSET:
pprint_charset(f, x->charset);
default:
fputs(nonterminal_name(g, x), f);
}
@ -456,25 +453,15 @@ void pprint_ntrules(FILE *f, const HCFGrammar *g, const HCFChoice *nt,
for(; i<column; i++) fputc(' ', f);
fputs(" ->", f);
HCFSequence **p;
switch(nt->type) {
case HCF_CHARSET:
pprint_charset(f, nt->charset);
break;
case HCF_CHOICE:
p = nt->seq;
if(*p == NULL) break; // shouldn't happen
assert(nt->type == HCF_CHOICE);
HCFSequence **p = nt->seq;
if(*p == NULL) return; // shouldn't happen
pprint_sequence(f, g, *p++); // print first production on the same line
for(; *p; p++) { // print the rest below with "or" bars
for(i=0; i<column; i++) fputc(' ', f); // indent
fputs(" |", f);
pprint_sequence(f, g, *p);
}
break;
default: // should not be reached
fputs(" ???\n", f);
assert_message(0, "unexpected nonterminal type");
}
}
void h_pprint_grammar(FILE *file, const HCFGrammar *g, int indent)
@ -495,6 +482,7 @@ void h_pprint_grammar(FILE *file, const HCFGrammar *g, int indent)
if(hte->key == NULL)
continue;
const HCFChoice *a = hte->key; // production's left-hand symbol
assert(a->type == HCF_CHOICE);
pprint_ntrules(file, g, a, indent, len);
}