add DFA pretty-printer
This commit is contained in:
parent
373a7aef94
commit
67e5b2fee0
1 changed files with 95 additions and 4 deletions
|
|
@ -317,6 +317,93 @@ HParseResult *h_lr_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Pretty-printers */
|
||||||
|
|
||||||
|
void h_pprint_lritem(FILE *f, const HCFGrammar *g, const HLRItem *item)
|
||||||
|
{
|
||||||
|
h_pprint_symbol(f, g, item->lhs);
|
||||||
|
fputs(" ->", f);
|
||||||
|
|
||||||
|
HCFChoice **x = item->rhs;
|
||||||
|
HCFChoice **mark = item->rhs + item->mark;
|
||||||
|
if(*x == NULL) {
|
||||||
|
fputs("\"\"", f);
|
||||||
|
} else {
|
||||||
|
while(*x) {
|
||||||
|
if(x == mark)
|
||||||
|
fputc('.', f);
|
||||||
|
else
|
||||||
|
fputc(' ', f);
|
||||||
|
|
||||||
|
if((*x)->type == HCF_CHAR) {
|
||||||
|
// condense character strings
|
||||||
|
fputc('"', f);
|
||||||
|
h_pprint_char(f, (*x)->chr);
|
||||||
|
for(x++; *x; x++) {
|
||||||
|
if(x == mark)
|
||||||
|
break;
|
||||||
|
if((*x)->type != HCF_CHAR)
|
||||||
|
break;
|
||||||
|
h_pprint_char(f, (*x)->chr);
|
||||||
|
}
|
||||||
|
fputc('"', f);
|
||||||
|
} else {
|
||||||
|
h_pprint_symbol(f, g, *x);
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(x == mark)
|
||||||
|
fputs(".", f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void h_pprint_lrstate(FILE *f, const HCFGrammar *g,
|
||||||
|
const HLRState *state, unsigned int indent)
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
const HHashTable *ht = state;
|
||||||
|
for(size_t i=0; i < ht->capacity; i++) {
|
||||||
|
for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
|
||||||
|
if(hte->key == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const HLRItem *item = hte->key;
|
||||||
|
|
||||||
|
if(!first)
|
||||||
|
for(unsigned int i=0; i<indent; i++) fputc(' ', f);
|
||||||
|
first = false;
|
||||||
|
h_pprint_lritem(f, g, item);
|
||||||
|
fputc('\n', f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pprint_transition(FILE *f, const HCFGrammar *g, const HLRTransition *t)
|
||||||
|
{
|
||||||
|
fputs("-", f);
|
||||||
|
h_pprint_symbol(f, g, t->symbol);
|
||||||
|
fprintf(f, "->%lu", t->to);
|
||||||
|
}
|
||||||
|
|
||||||
|
void h_pprint_lrdfa(FILE *f, const HCFGrammar *g,
|
||||||
|
const HLRDFA *dfa, unsigned int indent)
|
||||||
|
{
|
||||||
|
for(size_t i=0; i<dfa->nstates; i++) {
|
||||||
|
unsigned int indent2 = indent + fprintf(f, "%4lu: ", i);
|
||||||
|
h_pprint_lrstate(f, g, dfa->states[i], indent2);
|
||||||
|
for(HSlistNode *x = dfa->transitions->head; x; x = x->next) {
|
||||||
|
const HLRTransition *t = x->elem;
|
||||||
|
if(t->from == i) {
|
||||||
|
for(unsigned int i=0; i<indent2-2; i++) fputc(' ', f);
|
||||||
|
pprint_transition(f, g, t);
|
||||||
|
fputc('\n', f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
HParserBackendVTable h__lalr_backend_vtable = {
|
HParserBackendVTable h__lalr_backend_vtable = {
|
||||||
.compile = h_lalr_compile,
|
.compile = h_lalr_compile,
|
||||||
|
|
@ -346,6 +433,7 @@ int test_lalr(void)
|
||||||
HParser *B = h_sequence(Y, h_ch('b'), NULL);
|
HParser *B = h_sequence(Y, h_ch('b'), NULL);
|
||||||
HParser *p = h_choice(A, B, NULL);
|
HParser *p = h_choice(A, B, NULL);
|
||||||
|
|
||||||
|
printf("\n==== G R A M M A R ====\n");
|
||||||
HCFGrammar *g = h_cfgrammar(&system_allocator, p);
|
HCFGrammar *g = h_cfgrammar(&system_allocator, p);
|
||||||
if(g == NULL) {
|
if(g == NULL) {
|
||||||
fprintf(stderr, "h_cfgrammar failed\n");
|
fprintf(stderr, "h_cfgrammar failed\n");
|
||||||
|
|
@ -353,18 +441,21 @@ int test_lalr(void)
|
||||||
}
|
}
|
||||||
h_pprint_grammar(stdout, g, 0);
|
h_pprint_grammar(stdout, g, 0);
|
||||||
|
|
||||||
|
printf("\n==== D F A ====\n");
|
||||||
HLRDFA *dfa = h_lalr_dfa(g);
|
HLRDFA *dfa = h_lalr_dfa(g);
|
||||||
if(dfa) {
|
if(dfa)
|
||||||
// print states of the LR(0) automaton
|
h_pprint_lrdfa(stdout, g, dfa, 0);
|
||||||
}
|
else
|
||||||
|
fprintf(stderr, "h_lalr_dfa failed\n");
|
||||||
|
|
||||||
|
printf("\n==== L A L R T A B L E ====\n");
|
||||||
if(h_compile(p, PB_LALR, NULL)) {
|
if(h_compile(p, PB_LALR, NULL)) {
|
||||||
fprintf(stderr, "does not compile\n");
|
fprintf(stderr, "does not compile\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
// print LALR(1) table
|
// print LALR(1) table
|
||||||
|
|
||||||
|
printf("\n==== P A R S E R E S U L T ====\n");
|
||||||
HParseResult *res = h_parse(p, (uint8_t *)"xyya", 4);
|
HParseResult *res = h_parse(p, (uint8_t *)"xyya", 4);
|
||||||
if(res)
|
if(res)
|
||||||
h_pprint(stdout, res->ast, 0, 2);
|
h_pprint(stdout, res->ast, 0, 2);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue