Don't cache dummy results for primitive parsers.
This commit is contained in:
parent
578ac05154
commit
969d768205
30 changed files with 50 additions and 16 deletions
|
|
@ -3,7 +3,7 @@
|
|||
#include "../internal.h"
|
||||
#include "../parsers/parser_internal.h"
|
||||
|
||||
// short-hand for creating cache values (regular case)
|
||||
// short-hand for creating lowlevel parse cache values (parse result case)
|
||||
static
|
||||
HParserCacheValue * cached_result(HParseState *state, HParseResult *result) {
|
||||
HParserCacheValue *ret = a_new(HParserCacheValue, 1);
|
||||
|
|
@ -13,7 +13,7 @@ HParserCacheValue * cached_result(HParseState *state, HParseResult *result) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
// short-hand for caching parse results (left recursion case)
|
||||
// short-hand for creating lowlevel parse cache values (left recursion case)
|
||||
static
|
||||
HParserCacheValue *cached_lr(HParseState *state, HLeftRec *lr) {
|
||||
HParserCacheValue *ret = a_new(HParserCacheValue, 1);
|
||||
|
|
@ -186,18 +186,22 @@ HParseResult* h_do_parse(const HParser* parser, HParseState *state) {
|
|||
if (!m) {
|
||||
// It doesn't exist, so create a dummy result to cache
|
||||
HLeftRec *base = a_new(HLeftRec, 1);
|
||||
base->seed = NULL; base->rule = parser; base->head = NULL;
|
||||
h_slist_push(state->lr_stack, base);
|
||||
// cache it
|
||||
h_hashtable_put(state->cache, key, cached_lr(state, base));
|
||||
// parse the input
|
||||
if (parser->vtable->higher) {
|
||||
base->seed = NULL; base->rule = parser; base->head = NULL;
|
||||
h_slist_push(state->lr_stack, base);
|
||||
// cache it
|
||||
h_hashtable_put(state->cache, key, cached_lr(state, base));
|
||||
// parse the input
|
||||
}
|
||||
HParseResult *tmp_res = perform_lowlevel_parse(state, parser);
|
||||
// the base variable has passed equality tests with the cache
|
||||
h_slist_pop(state->lr_stack);
|
||||
// update the cached value to our new position
|
||||
HParserCacheValue *cached = h_hashtable_get(state->cache, key);
|
||||
assert(cached != NULL);
|
||||
cached->input_stream = state->input_stream;
|
||||
if (parser->vtable->higher) {
|
||||
// the base variable has passed equality tests with the cache
|
||||
h_slist_pop(state->lr_stack);
|
||||
// update the cached value to our new position
|
||||
HParserCacheValue *cached = h_hashtable_get(state->cache, key);
|
||||
assert(cached != NULL);
|
||||
cached->input_stream = state->input_stream;
|
||||
}
|
||||
// setupLR, used below, mutates the LR to have a head if appropriate, so we check to see if we have one
|
||||
if (NULL == base->head) {
|
||||
h_hashtable_put(state->cache, key, cached_result(state, tmp_res));
|
||||
|
|
|
|||
|
|
@ -278,9 +278,9 @@ typedef struct HRecursionHead_ {
|
|||
/* A left recursion.
|
||||
*
|
||||
* Members:
|
||||
* seed -
|
||||
* rule -
|
||||
* head -
|
||||
* seed - the HResult yielded by rule
|
||||
* rule - the HParser that produces seed
|
||||
* head - the
|
||||
*/
|
||||
typedef struct HLeftRec_ {
|
||||
HParseResult *seed;
|
||||
|
|
@ -419,6 +419,7 @@ struct HParserVtable_ {
|
|||
bool (*isValidCF)(void *env);
|
||||
bool (*compile_to_rvm)(HRVMProg *prog, void* env); // FIXME: forgot what the bool return value was supposed to mean.
|
||||
void (*desugar)(HAllocator *mm__, HCFStack *stk__, void *env);
|
||||
bool higher; // false if primitive
|
||||
};
|
||||
|
||||
bool h_false(void*);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ static const HParserVtable action_vt = {
|
|||
.isValidCF = action_isValidCF,
|
||||
.desugar = desugar_action,
|
||||
.compile_to_rvm = action_ctrvm,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_action(const HParser* p, const HAction a, void* user_data) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ static const HParserVtable and_vt = {
|
|||
revision. --mlp, 18/12/12 */
|
||||
.isValidCF = h_false, /* despite TODO above, this remains false. */
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ static const HParserVtable attr_bool_vt = {
|
|||
.isValidCF = ab_isValidCF,
|
||||
.desugar = desugar_ab,
|
||||
.compile_to_rvm = ab_ctrvm,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ static const HParserVtable bind_vt = {
|
|||
.isValidRegular = h_false,
|
||||
.isValidCF = h_false,
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser *h_bind(const HParser *p, HContinuation k, void *env)
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ static const HParserVtable bits_vt = {
|
|||
.isValidCF = h_true,
|
||||
.desugar = desugar_bits,
|
||||
.compile_to_rvm = bits_ctrvm,
|
||||
.higher = false,
|
||||
};
|
||||
|
||||
HParser* h_bits(size_t len, bool sign) {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ static const HParserVtable butnot_vt = {
|
|||
.isValidRegular = h_false,
|
||||
.isValidCF = h_false, // XXX should this be true if both p1 and p2 are CF?
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_butnot(const HParser* p1, const HParser* p2) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ static const HParserVtable ch_vt = {
|
|||
.isValidCF = h_true,
|
||||
.desugar = desugar_ch,
|
||||
.compile_to_rvm = ch_ctrvm,
|
||||
.higher = false,
|
||||
};
|
||||
|
||||
HParser* h_ch(const uint8_t c) {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ static const HParserVtable charset_vt = {
|
|||
.isValidCF = h_true,
|
||||
.desugar = desugar_charset,
|
||||
.compile_to_rvm = cs_ctrvm,
|
||||
.higher = false,
|
||||
};
|
||||
|
||||
HParser* h_ch_range(const uint8_t lower, const uint8_t upper) {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ static const HParserVtable choice_vt = {
|
|||
.isValidCF = choice_isValidCF,
|
||||
.desugar = desugar_choice,
|
||||
.compile_to_rvm = choice_ctrvm,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_choice(HParser* p, ...) {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ static HParserVtable difference_vt = {
|
|||
.isValidRegular = h_false,
|
||||
.isValidCF = h_false, // XXX should this be true if both p1 and p2 are CF?
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_difference(const HParser* p1, const HParser* p2) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ static const HParserVtable end_vt = {
|
|||
.isValidCF = h_true,
|
||||
.desugar = desugar_end,
|
||||
.compile_to_rvm = end_ctrvm,
|
||||
.higher = false,
|
||||
};
|
||||
|
||||
HParser* h_end_p() {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ static const HParserVtable endianness_vt = {
|
|||
.isValidCF = h_false,
|
||||
.desugar = NULL,
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_with_endianness(char endianness, const HParser *p)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ static const HParserVtable epsilon_vt = {
|
|||
.isValidCF = h_true,
|
||||
.desugar = desugar_epsilon,
|
||||
.compile_to_rvm = epsilon_ctrvm,
|
||||
.higher = false,
|
||||
};
|
||||
|
||||
HParser* h_epsilon_p() {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ static const HParserVtable ignore_vt = {
|
|||
.isValidCF = ignore_isValidCF,
|
||||
.desugar = desugar_ignore,
|
||||
.compile_to_rvm = ignore_ctrvm,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_ignore(const HParser* p) {
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ static const HParserVtable ignoreseq_vt = {
|
|||
.isValidCF = is_isValidCF,
|
||||
.desugar = desugar_ignoreseq,
|
||||
.compile_to_rvm = is_ctrvm,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ static const HParserVtable indirect_vt = {
|
|||
.isValidCF = indirect_isValidCF,
|
||||
.desugar = desugar_indirect,
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
void h_bind_indirect__m(HAllocator *mm__, HParser* indirect, const HParser* inner) {
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ static const HParserVtable int_range_vt = {
|
|||
.isValidCF = h_true,
|
||||
.desugar = desugar_int_range,
|
||||
.compile_to_rvm = ir_ctrvm,
|
||||
.higher = false,
|
||||
};
|
||||
|
||||
HParser* h_int_range(const HParser *p, const int64_t lower, const int64_t upper) {
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ static const HParserVtable many_vt = {
|
|||
.isValidCF = many_isValidCF,
|
||||
.desugar = desugar_many,
|
||||
.compile_to_rvm = many_ctrvm,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_many(const HParser* p) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ static const HParserVtable not_vt = {
|
|||
.isValidRegular = h_false, /* see and.c for why */
|
||||
.isValidCF = h_false,
|
||||
.compile_to_rvm = h_not_regular, // Is actually regular, but the generation step is currently unable to handle it. TODO: fix this.
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_not(const HParser* p) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ static const HParserVtable nothing_vt = {
|
|||
.isValidCF = h_true,
|
||||
.desugar = desugar_nothing,
|
||||
.compile_to_rvm = nothing_ctrvm,
|
||||
.higher = false,
|
||||
};
|
||||
|
||||
HParser* h_nothing_p() {
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ static const HParserVtable optional_vt = {
|
|||
.isValidCF = opt_isValidCF,
|
||||
.desugar = desugar_optional,
|
||||
.compile_to_rvm = opt_ctrvm,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_optional(const HParser* p) {
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ static const HParserVtable permutation_vt = {
|
|||
.isValidCF = h_false,
|
||||
.desugar = NULL,
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_permutation(HParser* p, ...) {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,7 @@ static const HParserVtable sequence_vt = {
|
|||
.isValidCF = sequence_isValidCF,
|
||||
.desugar = desugar_sequence,
|
||||
.compile_to_rvm = sequence_ctrvm,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_sequence(HParser* p, ...) {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ const HParserVtable token_vt = {
|
|||
.isValidCF = h_true,
|
||||
.desugar = desugar_token,
|
||||
.compile_to_rvm = token_ctrvm,
|
||||
.higher = false,
|
||||
};
|
||||
|
||||
HParser* h_token(const uint8_t *str, const size_t len) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ static const HParserVtable unimplemented_vt = {
|
|||
.isValidCF = h_false,
|
||||
.desugar = NULL,
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
static HParser unimplemented = {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ static const HParserVtable put_vt = {
|
|||
.isValidRegular = h_false,
|
||||
.isValidCF = h_false,
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_put_value(const HParser* p, const char* name) {
|
||||
|
|
@ -55,6 +56,7 @@ static const HParserVtable get_vt = {
|
|||
.isValidRegular = h_false,
|
||||
.isValidCF = h_false,
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_get_value(const char* name) {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ static const HParserVtable whitespace_vt = {
|
|||
.isValidCF = ws_isValidCF,
|
||||
.desugar = desugar_whitespace,
|
||||
.compile_to_rvm = ws_ctrvm,
|
||||
.higher = false,
|
||||
};
|
||||
|
||||
HParser* h_whitespace(const HParser* p) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ static const HParserVtable xor_vt = {
|
|||
.isValidRegular = h_false,
|
||||
.isValidCF = h_false, // XXX should this be true if both p1 and p2 are CF?
|
||||
.compile_to_rvm = h_not_regular,
|
||||
.higher = true,
|
||||
};
|
||||
|
||||
HParser* h_xor(const HParser* p1, const HParser* p2) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue