Fix difference and butnot
This commit is contained in:
parent
56a5845674
commit
5d77c4307f
2 changed files with 22 additions and 25 deletions
42
src/hammer.c
42
src/hammer.c
|
|
@ -166,9 +166,19 @@ parse_result_t* do_parse(const parser_t* parser, parse_state_t *state) {
|
||||||
// parse the input
|
// parse the input
|
||||||
parse_result_t *tmp_res;
|
parse_result_t *tmp_res;
|
||||||
if (parser) {
|
if (parser) {
|
||||||
|
input_stream_t bak = state->input_stream;
|
||||||
tmp_res = parser->fn(parser->env, state);
|
tmp_res = parser->fn(parser->env, state);
|
||||||
if (tmp_res)
|
if (tmp_res) {
|
||||||
tmp_res->arena = state->arena;
|
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
|
} else
|
||||||
tmp_res = NULL;
|
tmp_res = NULL;
|
||||||
if (state->input_stream.overrun)
|
if (state->input_stream.overrun)
|
||||||
|
|
@ -517,33 +527,19 @@ typedef struct {
|
||||||
const parser_t *p2;
|
const parser_t *p2;
|
||||||
} two_parsers_t;
|
} two_parsers_t;
|
||||||
|
|
||||||
|
// return token size in bits...
|
||||||
size_t accumulate_size(parse_result_t *pr) {
|
size_t accumulate_size(parse_result_t *pr) {
|
||||||
if (NULL != ((parse_result_t*)pr)->ast) {
|
if (pr) {
|
||||||
switch (pr->ast->token_type) {
|
return pr->bit_length;
|
||||||
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;
|
|
||||||
}
|
|
||||||
} // no else, if the AST is null then acc doesn't change
|
} // no else, if the AST is null then acc doesn't change
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t token_length(parse_result_t *pr) {
|
size_t token_length(parse_result_t *pr) {
|
||||||
if (NULL == pr) {
|
if (pr) {
|
||||||
return 0;
|
return pr->bit_length;
|
||||||
} else {
|
} 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 r1len = token_length(r1);
|
||||||
size_t r2len = token_length(r2);
|
size_t r2len = token_length(r2);
|
||||||
// if both match but p1's text is as long as or longer than p2's, fail
|
// if both match but p1's text is shorter than than p2's (or the same length), fail
|
||||||
if (r1len >= r2len) {
|
if (r1len <= r2len) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
return r1;
|
return r1;
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ typedef struct parsed_token {
|
||||||
*/
|
*/
|
||||||
typedef struct parse_result {
|
typedef struct parse_result {
|
||||||
const parsed_token_t *ast;
|
const parsed_token_t *ast;
|
||||||
|
long long bit_length;
|
||||||
arena_t arena;
|
arena_t arena;
|
||||||
} parse_result_t;
|
} 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
|
* Given two parsers, p1 and p2, this parser succeeds in the following
|
||||||
* cases:
|
* cases:
|
||||||
* - if p1 succeeds and p2 fails
|
* - 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.
|
* Result token type: p1's result type.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue