All tests pass; lots of stuff is no longer const

This commit is contained in:
Dan Hirsch 2013-05-24 15:07:47 +02:00
parent b9a33f2c98
commit d71215d494
24 changed files with 216 additions and 120 deletions

View file

@ -1,3 +1,4 @@
#include <assert.h>
#include "parser_internal.h"
typedef struct {
@ -45,9 +46,35 @@ static bool action_isValidCF(void *env) {
return a->p->vtable->isValidCF(a->p->env);
}
static bool h_svm_action_action(HArena *arena, HSVMContext *ctx, void* arg) {
HParseResult res;
HAction action = arg;
assert(ctx->stack_count >= 1);
if (ctx->stack[ctx->stack_count-1]->token_type != TT_MARK) {
assert(ctx->stack_count >= 2 && ctx->stack[ctx->stack_count-2]->token_type == TT_MARK);
res.ast = ctx->stack[ctx->stack_count-2] = ctx->stack[ctx->stack_count-1];
ctx->stack_count--;
// mark replaced.
} else {
res.ast = NULL;
}
res.arena = arena;
HParsedToken *tok = action(&res);
if (tok != NULL)
ctx->stack[ctx->stack_count-1] = tok;
else
ctx->stack_count--;
return true; // action can't fail
}
static bool action_ctrvm(HRVMProg *prog, void* env) {
HParseAction *a = (HParseAction*)env;
return a->p->vtable->compile_to_rvm(prog, a->p->env);
h_rvm_insert_insn(prog, RVM_PUSH, 0);
if (!h_compile_regex(prog, a->p))
return false;
h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_action, a->action));
return true;
}
static const HParserVtable action_vt = {

View file

@ -1,3 +1,4 @@
#include <assert.h>
#include "parser_internal.h"
typedef struct {
@ -48,9 +49,30 @@ static HCFChoice* desugar_ab(HAllocator *mm__, void *env) {
return ret;
}
static bool h_svm_action_attr_bool(HArena *arena, HSVMContext *ctx, void* arg) {
HParseResult res;
HPredicate pred = arg;
assert(ctx->stack_count >= 1);
if (ctx->stack[ctx->stack_count-1]->token_type != TT_MARK) {
assert(ctx->stack_count >= 2 && ctx->stack[ctx->stack_count-2]->token_type == TT_MARK);
ctx->stack_count--;
res.ast = ctx->stack[ctx->stack_count-1] = ctx->stack[ctx->stack_count];
// mark replaced.
} else {
ctx->stack_count--;
res.ast = NULL;
}
res.arena = arena;
return pred(&res);
}
static bool ab_ctrvm(HRVMProg *prog, void *env) {
HAttrBool *ab = (HAttrBool*)env;
return h_compile_regex(prog, ab->p);
h_rvm_insert_insn(prog, RVM_PUSH, 0);
if (!h_compile_regex(prog, ab->p))
return false;
h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_attr_bool, ab->pred));
return true;
}
static const HParserVtable attr_bool_vt = {

View file

@ -45,10 +45,10 @@ static HParsedToken *reshape_bits(const HParseResult *p, bool signedp) {
return ret;
}
static const HParsedToken *reshape_bits_unsigned(const HParseResult *p) {
static HParsedToken *reshape_bits_unsigned(const HParseResult *p) {
return reshape_bits(p, false);
}
static const HParsedToken *reshape_bits_signed(const HParseResult *p) {
static HParsedToken *reshape_bits_signed(const HParseResult *p) {
return reshape_bits(p, true);
}

View file

@ -65,6 +65,7 @@ static bool choice_ctrvm(HRVMProg *prog, void* env) {
gotos[i] = h_rvm_insert_insn(prog, RVM_GOTO, 65535);
h_rvm_patch_arg(prog, insn, h_rvm_get_ip(prog));
}
h_rvm_insert_insn(prog, RVM_MATCH, 0x00FF); // fail.
uint16_t jump = h_rvm_get_ip(prog);
for (size_t i=0; i<s->len; ++i) {
h_rvm_patch_arg(prog, gotos[i], jump);

View file

@ -47,7 +47,7 @@ static bool h_svm_action_pop(HArena *arena, HSVMContext *ctx, void* arg) {
static bool ignore_ctrvm(HRVMProg *prog, void *env) {
HParser *p = (HParser*)env;
h_compile_regex(prog, p->env);
h_compile_regex(prog, p);
h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_pop, NULL));
return true;
}

View file

@ -1,3 +1,4 @@
#include <assert.h>
#include "parser_internal.h"
// TODO: split this up.
@ -14,7 +15,7 @@ static HParseResult *parse_many(void* env, HParseState *state) {
HInputStream bak;
while (env_->min_p || env_->count > count) {
bak = state->input_stream;
if (count > 0) {
if (count > 0 && env_->sep != NULL) {
HParseResult *sep = h_do_parse(env_->sep, state);
if (!sep)
goto err0;
@ -47,13 +48,15 @@ static HParseResult *parse_many(void* env, HParseState *state) {
static bool many_isValidRegular(void *env) {
HRepeat *repeat = (HRepeat*)env;
return (repeat->p->vtable->isValidRegular(repeat->p->env) &&
repeat->sep->vtable->isValidRegular(repeat->sep->env));
(repeat->sep == NULL ||
repeat->sep->vtable->isValidRegular(repeat->sep->env)));
}
static bool many_isValidCF(void *env) {
HRepeat *repeat = (HRepeat*)env;
return (repeat->p->vtable->isValidCF(repeat->p->env) &&
repeat->sep->vtable->isValidCF(repeat->sep->env));
(repeat->sep == NULL ||
repeat->sep->vtable->isValidCF(repeat->sep->env)));
}
static HCFChoice* desugar_many(HAllocator *mm__, void *env) {
@ -70,7 +73,9 @@ static HCFChoice* desugar_many(HAllocator *mm__, void *env) {
-> \epsilon
*/
HCFChoice *sep = h_desugar(mm__, repeat->sep);
HParser *epsilon = h_epsilon_p__m(mm__);
HCFChoice *sep = h_desugar(mm__, (repeat->sep != NULL) ? repeat->sep : epsilon);
HCFChoice *a = h_desugar(mm__, repeat->p);
HCFChoice *ma = h_new(HCFChoice, 1);
HCFChoice *mar = h_new(HCFChoice, 1);
@ -119,24 +124,56 @@ static HCFChoice* desugar_many(HAllocator *mm__, void *env) {
static bool many_ctrvm(HRVMProg *prog, void *env) {
HRepeat *repeat = (HRepeat*)env;
// FIXME: Implement clear_to_mark
uint16_t clear_to_mark = h_rvm_create_action(prog, h_svm_action_clear_to_mark, NULL);
h_rvm_insert_insn(prog, RVM_PUSH, 0);
// TODO: implement min and max properly. Right now, it's always min==0, max==inf
uint16_t insn = h_rvm_insert_insn(prog, RVM_FORK, 0);
if (!h_compile_regex(prog, repeat->p))
return false;
if (repeat->sep != NULL) {
h_rvm_insert_insn(prog, RVM_PUSH, 0);
if (!h_compile_regex(prog, repeat->sep))
return false;
h_rvm_insert_insn(prog, RVM_ACTION, clear_to_mark);
}
h_rvm_insert_insn(prog, RVM_GOTO, insn);
h_rvm_patch_arg(prog, insn, h_rvm_get_ip(prog));
// TODO: implement min & max properly. Right now, it's always
// max==inf, min={0,1}
h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_make_sequence, NULL));
return true;
// Structure:
// Min == 0:
// FORK end // if Min == 0
// GOTO mid
// nxt: <SEP>
// mid: <ELEM>
// FORK nxt
// end:
if (repeat->min_p) {
h_rvm_insert_insn(prog, RVM_PUSH, 0);
assert(repeat->count < 2); // TODO: The other cases should be supported later.
uint16_t end_fork;
if (repeat->count == 0)
end_fork = h_rvm_insert_insn(prog, RVM_FORK, 0xFFFF);
uint16_t goto_mid = h_rvm_insert_insn(prog, RVM_GOTO, 0xFFFF);
uint16_t nxt = h_rvm_get_ip(prog);
if (repeat->sep != NULL) {
h_rvm_insert_insn(prog, RVM_PUSH, 0);
if (!h_compile_regex(prog, repeat->sep))
return false;
h_rvm_insert_insn(prog, RVM_ACTION, clear_to_mark);
}
h_rvm_patch_arg(prog, goto_mid, h_rvm_get_ip(prog));
if (!h_compile_regex(prog, repeat->p))
return false;
h_rvm_insert_insn(prog, RVM_FORK, nxt);
h_rvm_patch_arg(prog, end_fork, h_rvm_get_ip(prog));
h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_make_sequence, NULL));
return true;
} else {
h_rvm_insert_insn(prog, RVM_PUSH, 0);
for (size_t i = 0; i < repeat->count; i++) {
if (repeat->sep != NULL && i != 0) {
h_rvm_insert_insn(prog, RVM_PUSH, 0);
if (!h_compile_regex(prog, repeat->sep))
return false;
h_rvm_insert_insn(prog, RVM_ACTION, clear_to_mark);
}
if (!h_compile_regex(prog, repeat->p))
return false;
}
h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_make_sequence, NULL));
return true;
}
}
static const HParserVtable many_vt = {
@ -153,7 +190,7 @@ HParser* h_many(const HParser* p) {
HParser* h_many__m(HAllocator* mm__, const HParser* p) {
HRepeat *env = h_new(HRepeat, 1);
env->p = p;
env->sep = h_epsilon_p__m(mm__);
env->sep = NULL;
env->count = 0;
env->min_p = true;
return h_new_parser(mm__, &many_vt, env);
@ -165,7 +202,7 @@ HParser* h_many1(const HParser* p) {
HParser* h_many1__m(HAllocator* mm__, const HParser* p) {
HRepeat *env = h_new(HRepeat, 1);
env->p = p;
env->sep = h_epsilon_p__m(mm__);
env->sep = NULL;
env->count = 1;
env->min_p = true;
return h_new_parser(mm__, &many_vt, env);
@ -177,7 +214,7 @@ HParser* h_repeat_n(const HParser* p, const size_t n) {
HParser* h_repeat_n__m(HAllocator* mm__, const HParser* p, const size_t n) {
HRepeat *env = h_new(HRepeat, 1);
env->p = p;
env->sep = h_epsilon_p__m(mm__);
env->sep = NULL;
env->count = n;
env->min_p = false;
return h_new_parser(mm__, &many_vt, env);
@ -222,7 +259,7 @@ static HParseResult* parse_length_value(void *env, HParseState *state) {
// TODO: allocate this using public functions
HRepeat repeat = {
.p = lv->value,
.sep = h_epsilon_p(),
.sep = NULL,
.count = len->ast->uint,
.min_p = false
};

View file

@ -22,7 +22,7 @@ static bool opt_isValidCF(void *env) {
return p->vtable->isValidCF(p->env);
}
static const HParsedToken* reshape_optional(const HParseResult *p) {
static HParsedToken* reshape_optional(const HParseResult *p) {
assert(p->ast);
assert(p->ast->token_type == TT_SEQUENCE);
assert(p->ast->seq->used > 0);
@ -83,7 +83,7 @@ static bool opt_ctrvm(HRVMProg *prog, void* env) {
h_rvm_insert_insn(prog, RVM_PUSH, 0);
uint16_t insn = h_rvm_insert_insn(prog, RVM_FORK, 0);
HParser *p = (HParser*) env;
if (!h_compile_regex(prog, p->env))
if (!h_compile_regex(prog, p))
return false;
h_rvm_patch_arg(prog, insn, h_rvm_get_ip(prog));
h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_optional, NULL));

View file

@ -43,7 +43,7 @@ static bool sequence_isValidCF(void *env) {
return true;
}
static const HParsedToken *reshape_sequence(const HParseResult *p) {
static HParsedToken *reshape_sequence(const HParseResult *p) {
assert(p->ast);
assert(p->ast->token_type == TT_SEQUENCE);
@ -86,7 +86,7 @@ static bool sequence_ctrvm(HRVMProg *prog, void *env) {
HSequence *s = (HSequence*)env;
h_rvm_insert_insn(prog, RVM_PUSH, 0);
for (size_t i=0; i<s->len; ++i) {
if (!s->p_array[i]->vtable->compile_to_rvm(prog, s->p_array[i]))
if (!s->p_array[i]->vtable->compile_to_rvm(prog, s->p_array[i]->env))
return false;
}
h_rvm_insert_insn(prog, RVM_ACTION, h_rvm_create_action(prog, h_svm_action_make_sequence, NULL));

View file

@ -20,7 +20,7 @@ static HParseResult* parse_token(void *env, HParseState *state) {
}
static const HParsedToken *reshape_token(const HParseResult *p) {
static HParsedToken *reshape_token(const HParseResult *p) {
// fetch sequence of uints from p
assert(p->ast);
assert(p->ast->token_type == TT_SEQUENCE);