From 5d77c4307f99efddf58cc45842f542d1de577129 Mon Sep 17 00:00:00 2001 From: Dan Hirsch <thequux@thequux.com> Date: Thu, 24 May 2012 15:35:04 +0200 Subject: [PATCH] Fix difference and butnot --- src/hammer.c | 44 ++++++++++++++++++++------------------------ src/hammer.h | 3 ++- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/hammer.c b/src/hammer.c index 046cd260..1e34e53c 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -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; diff --git a/src/hammer.h b/src/hammer.h index a0b93e56..85b2da43 100644 --- a/src/hammer.h +++ b/src/hammer.h @@ -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. */ -- GitLab