Don't cache dummy results for primitive parsers.

This commit is contained in:
Meredith L. Patterson 2015-10-03 17:54:11 +02:00
parent 578ac05154
commit 969d768205
30 changed files with 50 additions and 16 deletions

View file

@ -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));

View file

@ -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*);

View file

@ -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) {

View file

@ -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,
};

View file

@ -79,6 +79,7 @@ static const HParserVtable attr_bool_vt = {
.isValidCF = ab_isValidCF,
.desugar = desugar_ab,
.compile_to_rvm = ab_ctrvm,
.higher = true,
};

View file

@ -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)

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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, ...) {

View file

@ -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) {

View file

@ -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() {

View file

@ -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)

View file

@ -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() {

View file

@ -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) {

View file

@ -103,6 +103,7 @@ static const HParserVtable ignoreseq_vt = {
.isValidCF = is_isValidCF,
.desugar = desugar_ignoreseq,
.compile_to_rvm = is_ctrvm,
.higher = true,
};

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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() {

View file

@ -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) {

View file

@ -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, ...) {

View file

@ -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, ...) {

View file

@ -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) {

View file

@ -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 = {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {