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