use lookahead stream directly for LR (terminal) lookup

This commit is contained in:
Sven M. Hallberg 2013-06-21 23:22:07 +02:00
parent 853e1fba46
commit 9585a5946e
4 changed files with 32 additions and 46 deletions

View file

@ -21,7 +21,7 @@ typedef struct HLLkTable_ {
/* Interface to look up an entry in the parse table. */
const HCFSequence *h_llk_lookup(const HLLkTable *table, const HCFChoice *x,
HInputStream lookahead)
const HInputStream *stream)
{
const HStringMap *row = h_hashtable_get(table->rows, x);
assert(row != NULL); // the table should have one row for each nonterminal
@ -29,28 +29,7 @@ const HCFSequence *h_llk_lookup(const HLLkTable *table, const HCFChoice *x,
assert(!row->epsilon_branch); // would match without looking at the input
// XXX cases where this could be useful?
const HStringMap *m = row;
while(m) {
if(m->epsilon_branch) { // input matched
// assert: another lookahead would not bring a more specific match.
// this is for the table generator to ensure.
return m->epsilon_branch;
}
// note the lookahead stream is passed by value, i.e. a copy.
// reading bits from it does not consume them from the real input.
uint8_t c = h_read_bits(&lookahead, 8, false);
if(lookahead.overrun) { // end of input
// XXX assumption of byte-wise grammar and input
return m->end_branch;
}
// no match yet, descend
m = h_stringmap_get_char(m, c);
}
return NULL;
return h_stringmap_get_lookahead(row, *stream);
}
/* Allocate a new parse table. */
@ -321,7 +300,7 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream*
seq = h_carray_new(arena);
// look up applicable production in parse table
const HCFSequence *p = h_llk_lookup(table, x, *stream);
const HCFSequence *p = h_llk_lookup(table, x, stream);
if(p == NULL)
goto no_parse;

View file

@ -216,7 +216,7 @@ HLREngine *h_lrengine_new(HArena *arena, HArena *tarena, const HLRTable *table,
}
static const HLRAction *
terminal_lookup(const HLREngine *engine, const HCFChoice *symbol)
terminal_lookup(const HLREngine *engine, const HInputStream *stream)
{
const HLRTable *table = engine->table;
size_t state = engine->state;
@ -226,11 +226,7 @@ terminal_lookup(const HLREngine *engine, const HCFChoice *symbol)
assert(h_lrtable_row_empty(table, state)); // that would be a conflict
return table->forall[state];
} else {
// XXX use the lookahead stream directly here (cf. llk)
if(symbol->type == HCF_END)
return table->tmap[state]->end_branch;
else
return h_stringmap_get(table->tmap[state], &symbol->chr, 1, false);
return h_stringmap_get_lookahead(table->tmap[state], *stream);
}
}
@ -248,22 +244,7 @@ nonterminal_lookup(const HLREngine *engine, const HCFChoice *symbol)
const HLRAction *h_lrengine_action(const HLREngine *engine)
{
HArena *tarena = engine->tarena;
// XXX use statically-allocated terminal symbols
HCFChoice *x = h_arena_malloc(tarena, sizeof(HCFChoice));
HInputStream lookahead = engine->input;
uint8_t c = h_read_bits(&lookahead, 8, false);
if(lookahead.overrun) { // end of input
x->type = HCF_END;
} else {
x->type = HCF_CHAR;
x->chr = c;
}
return terminal_lookup(engine, x);
return terminal_lookup(engine, &engine->input);
}
static HParsedToken *consume_input(HLREngine *engine)

View file

@ -321,6 +321,31 @@ void *h_stringmap_get(const HStringMap *m, const uint8_t *str, size_t n, bool en
return m->epsilon_branch;
}
void *h_stringmap_get_lookahead(const HStringMap *m, HInputStream lookahead)
{
while(m) {
if(m->epsilon_branch) { // input matched
// assert: another lookahead would not bring a more specific match.
// this is for the table generator to ensure. (LLk)
return m->epsilon_branch;
}
// note the lookahead stream is passed by value, i.e. a copy.
// reading bits from it does not consume them from the real input.
uint8_t c = h_read_bits(&lookahead, 8, false);
if(lookahead.overrun) { // end of input
// XXX assumption of byte-wise grammar and input
return m->end_branch;
}
// no match yet, descend
m = h_stringmap_get_char(m, c);
}
return NULL;
}
bool h_stringmap_present(const HStringMap *m, const uint8_t *str, size_t n, bool end)
{
return (h_stringmap_get(m, str, n, end) != NULL);

View file

@ -47,6 +47,7 @@ void h_stringmap_put_char(HStringMap *m, uint8_t c, void *v);
void h_stringmap_update(HStringMap *m, const HStringMap *n);
void h_stringmap_replace(HStringMap *m, void *old, void *new);
void *h_stringmap_get(const HStringMap *m, const uint8_t *str, size_t n, bool end);
void *h_stringmap_get_lookahead(const HStringMap *m, HInputStream lookahead);
bool h_stringmap_present(const HStringMap *m, const uint8_t *str, size_t n, bool end);
bool h_stringmap_present_epsilon(const HStringMap *m);
bool h_stringmap_empty(const HStringMap *m);