use lookahead stream directly for LR (terminal) lookup
This commit is contained in:
parent
853e1fba46
commit
9585a5946e
4 changed files with 32 additions and 46 deletions
|
|
@ -21,7 +21,7 @@ typedef struct HLLkTable_ {
|
||||||
|
|
||||||
/* Interface to look up an entry in the parse table. */
|
/* Interface to look up an entry in the parse table. */
|
||||||
const HCFSequence *h_llk_lookup(const HLLkTable *table, const HCFChoice *x,
|
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);
|
const HStringMap *row = h_hashtable_get(table->rows, x);
|
||||||
assert(row != NULL); // the table should have one row for each nonterminal
|
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
|
assert(!row->epsilon_branch); // would match without looking at the input
|
||||||
// XXX cases where this could be useful?
|
// XXX cases where this could be useful?
|
||||||
|
|
||||||
const HStringMap *m = row;
|
return h_stringmap_get_lookahead(row, *stream);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a new parse table. */
|
/* Allocate a new parse table. */
|
||||||
|
|
@ -321,7 +300,7 @@ HParseResult *h_llk_parse(HAllocator* mm__, const HParser* parser, HInputStream*
|
||||||
seq = h_carray_new(arena);
|
seq = h_carray_new(arena);
|
||||||
|
|
||||||
// look up applicable production in parse table
|
// 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)
|
if(p == NULL)
|
||||||
goto no_parse;
|
goto no_parse;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ HLREngine *h_lrengine_new(HArena *arena, HArena *tarena, const HLRTable *table,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const HLRAction *
|
static const HLRAction *
|
||||||
terminal_lookup(const HLREngine *engine, const HCFChoice *symbol)
|
terminal_lookup(const HLREngine *engine, const HInputStream *stream)
|
||||||
{
|
{
|
||||||
const HLRTable *table = engine->table;
|
const HLRTable *table = engine->table;
|
||||||
size_t state = engine->state;
|
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
|
assert(h_lrtable_row_empty(table, state)); // that would be a conflict
|
||||||
return table->forall[state];
|
return table->forall[state];
|
||||||
} else {
|
} else {
|
||||||
// XXX use the lookahead stream directly here (cf. llk)
|
return h_stringmap_get_lookahead(table->tmap[state], *stream);
|
||||||
if(symbol->type == HCF_END)
|
|
||||||
return table->tmap[state]->end_branch;
|
|
||||||
else
|
|
||||||
return h_stringmap_get(table->tmap[state], &symbol->chr, 1, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -248,22 +244,7 @@ nonterminal_lookup(const HLREngine *engine, const HCFChoice *symbol)
|
||||||
|
|
||||||
const HLRAction *h_lrengine_action(const HLREngine *engine)
|
const HLRAction *h_lrengine_action(const HLREngine *engine)
|
||||||
{
|
{
|
||||||
HArena *tarena = engine->tarena;
|
return terminal_lookup(engine, &engine->input);
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HParsedToken *consume_input(HLREngine *engine)
|
static HParsedToken *consume_input(HLREngine *engine)
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,31 @@ void *h_stringmap_get(const HStringMap *m, const uint8_t *str, size_t n, bool en
|
||||||
return m->epsilon_branch;
|
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)
|
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);
|
return (h_stringmap_get(m, str, n, end) != NULL);
|
||||||
|
|
|
||||||
|
|
@ -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_update(HStringMap *m, const HStringMap *n);
|
||||||
void h_stringmap_replace(HStringMap *m, void *old, void *new);
|
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(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(const HStringMap *m, const uint8_t *str, size_t n, bool end);
|
||||||
bool h_stringmap_present_epsilon(const HStringMap *m);
|
bool h_stringmap_present_epsilon(const HStringMap *m);
|
||||||
bool h_stringmap_empty(const HStringMap *m);
|
bool h_stringmap_empty(const HStringMap *m);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue