Fix difference and butnot

This commit is contained in:
Dan Hirsch 2012-05-24 15:35:04 +02:00
parent 56a5845674
commit 5d77c4307f
2 changed files with 22 additions and 25 deletions

View file

@ -166,9 +166,19 @@ parse_result_t* do_parse(const parser_t* parser, parse_state_t *state) {
// parse the input
parse_result_t *tmp_res;
if (parser) {
input_stream_t bak = state->input_stream;
tmp_res = parser->fn(parser->env, state);
if (tmp_res)
if (tmp_res) {
tmp_res->arena = state->arena;
if (!state->input_stream.overrun) {
tmp_res->bit_length = ((state->input_stream.index - bak.index) << 3);
if (state->input_stream.endianness & BIT_BIG_ENDIAN)
tmp_res->bit_length += state->input_stream.bit_offset - bak.bit_offset;
else
tmp_res->bit_length += bak.bit_offset - state->input_stream.bit_offset;
} else
tmp_res->bit_length = 0;
}
} else
tmp_res = NULL;
if (state->input_stream.overrun)
@ -216,7 +226,7 @@ typedef struct {
uint8_t len;
} token_t;
static parse_result_t* parse_unimplemented(void* env, parse_state_t *state) {
static parse_result_t* parse_unimplemented(void* env, parse_state_t *state) {
(void) env;
(void) state;
static parsed_token_t token = {
@ -517,33 +527,19 @@ typedef struct {
const parser_t *p2;
} two_parsers_t;
// return token size in bits...
size_t accumulate_size(parse_result_t *pr) {
if (NULL != ((parse_result_t*)pr)->ast) {
switch (pr->ast->token_type) {
case TT_BYTES:
return pr->ast->bytes.len;
case TT_SINT:
case TT_UINT:
return sizeof(pr->ast->uint);
case TT_SEQUENCE: {
counted_array_t *arr = pr->ast->seq;
size_t ret = 0;
for (size_t i = 0; i < arr->used; i++)
ret += accumulate_size(arr->elements[i]);
return ret;
}
default:
return 0;
}
if (pr) {
return pr->bit_length;
} // no else, if the AST is null then acc doesn't change
return 0;
}
size_t token_length(parse_result_t *pr) {
if (NULL == pr) {
return 0;
if (pr) {
return pr->bit_length;
} else {
return accumulate_size(pr);
return 0;
}
}
@ -568,8 +564,8 @@ static parse_result_t* parse_butnot(void *env, parse_state_t *state) {
}
size_t r1len = token_length(r1);
size_t r2len = token_length(r2);
// if both match but p1's text is as long as or longer than p2's, fail
if (r1len >= r2len) {
// if both match but p1's text is shorter than than p2's (or the same length), fail
if (r1len <= r2len) {
return NULL;
} else {
return r1;

View file

@ -74,6 +74,7 @@ typedef struct parsed_token {
*/
typedef struct parse_result {
const parsed_token_t *ast;
long long bit_length;
arena_t arena;
} parse_result_t;
@ -254,7 +255,7 @@ const parser_t* choice(const parser_t* p, ...) __attribute__((sentinel));
* Given two parsers, p1 and p2, this parser succeeds in the following
* cases:
* - if p1 succeeds and p2 fails
* - if both succeed but p1's result is as long as or shorter than p2's
* - if both succeed but p1's result is as long as or longer than p2's
*
* Result token type: p1's result type.
*/