hammer/src/backends/ll.c

106 lines
2.6 KiB
C
Raw Normal View History

2013-04-17 15:10:33 +02:00
#include <assert.h>
#include "../internal.h"
#include "../cfgrammar.h"
2013-04-17 15:10:33 +02:00
#include "../parsers/parser_internal.h"
/* LL parse table and associated data */
typedef struct HLLTable_ {
unsigned int **arr; // Nonterminals numbered from 1, 0 = error.
} HLLTable;
typedef struct HLLData_ {
HCFGrammar *grammar;
HLLTable *table;
} HLLData;
#if 0
/* Interface to look up an entry in the parse table. */
unsigned int h_ll_lookup(const HLLTable *table, unsigned int nonterminal, uint8_t token)
{
assert(nonterminal > 0);
return table->arr[n*257+token];
}
#endif
2013-05-08 16:12:34 +02:00
/* Compute the predict set of production "A -> rhs". */
HHashSet *h_predict(HCFGrammar *g, const HCFChoice *A, const HCFSequence *rhs)
{
// predict(A -> rhs) = first(rhs) u follow(A) if "" can be derived from rhs
// predict(A -> rhs) = first(rhs) otherwise
HHashSet *first_rhs = h_first_sequence(g, rhs->items);
if(h_sequence_derives_epsilon(g, rhs->items)) {
HHashSet *ret = h_hashset_new(g->arena, h_eq_ptr, h_hash_ptr);
h_hashset_put_all(ret, first_rhs);
h_hashset_put_all(ret, h_follow(g, A));
return ret;
} else {
return first_rhs;
}
}
int h_ll_compile(HAllocator* mm__, const HParser* parser, const void* params)
{
// Convert parser to a CFG. This can fail as indicated by a NULL return.
2013-05-07 23:37:02 +02:00
HCFGrammar *grammar = h_cfgrammar(mm__, parser);
if(grammar == NULL)
return -1; // -> Backend unsuitable for this parser.
// TODO: eliminate common prefixes
// TODO: eliminate left recursion
// TODO: avoid conflicts by splitting occurances?
// XXX generate table and store in parser->data.
// XXX any other data structures needed?
return -1; // XXX 0 on success
}
/* LL driver */
HParseResult *h_ll_parse(HAllocator* mm__, const HParser* parser, HParseState* parse_state)
{
// get table from parser->data.
// run driver.
2013-04-17 15:10:33 +02:00
return NULL; // TODO
}
2013-04-17 15:10:33 +02:00
HParserBackendVTable h__ll_backend_vtable = {
.compile = h_ll_compile,
.parse = h_ll_parse
};
2013-05-05 22:15:40 +02:00
// dummy!
int test_ll(void)
{
const HParser *c = h_many(h_ch('x'));
const HParser *q = h_sequence(c, h_ch('y'), NULL);
const HParser *p = h_choice(q, h_end_p(), NULL);
2013-05-07 23:37:02 +02:00
HCFGrammar *g = h_cfgrammar(&system_allocator, p);
2013-05-05 22:15:40 +02:00
if(g == NULL) {
2013-05-07 23:37:02 +02:00
fprintf(stderr, "h_cfgrammar failed\n");
2013-05-05 22:15:40 +02:00
return 1;
}
h_pprint_grammar(stdout, g, 0);
printf("generate epsilon: ");
h_pprint_symbolset(stdout, g, g->geneps, 0);
printf("first(A) = ");
h_pprint_tokenset(stdout, g, h_first_symbol(g, g->start), 0);
printf("follow(C) = ");
h_pprint_tokenset(stdout, g, h_follow(g, h_desugar(&system_allocator, c)), 0);
return 0;
}