From daafc533a440116442678c0e4b43d23460a1f2ad Mon Sep 17 00:00:00 2001 From: Kenneth Shelton Date: Fri, 11 Aug 2017 15:16:21 +0000 Subject: [PATCH] Fix backtracking --- src/parser.c | 5 +++++ src/pdag.c | 24 ++++++++++++++++-------- src/pdag.h | 1 + 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/parser.c b/src/parser.c index 2b9b3ad7..1ca407b5 100644 --- a/src/parser.c +++ b/src/parser.c @@ -3006,10 +3006,12 @@ PARSER_Parse(Repeat) struct data_Repeat *const data = (struct data_Repeat*) pdata; struct ln_pdag *endNode = NULL; size_t strtoffs = *offs; + size_t lastMatch = strtoffs; size_t lastKnownGood = strtoffs; struct json_object *json_arr = NULL; struct json_object *parsed_value = NULL; const size_t parsedTo_save = npb->parsedTo; + const size_t longestParsedTo_save = npb->longestParsedTo; int mergeResults = parser_name != NULL && parser_name[0] == '.' && parser_name[1] == '\0'; do { @@ -3031,6 +3033,8 @@ PARSER_Parse(Repeat) "parse ptr back to %zd", strtoffs); goto success; } else { + // Reset longest match + npb->longestParsedTo = lastMatch > longestParsedTo_save ? lastMatch : longestParsedTo_save; goto done; } } @@ -3070,6 +3074,7 @@ PARSER_Parse(Repeat) /* now check if we shall continue */ npb->parsedTo = 0; + lastMatch = lastKnownGood; lastKnownGood = strtoffs; /* record pos in case of fail in while */ r = ln_normalizeRec(npb, data->while_cond, strtoffs, 1, NULL, &endNode, 0, NULL, parser_name); LN_DBGPRINTF(npb->ctx, "repeat while returns %d, parsed %zu", diff --git a/src/pdag.c b/src/pdag.c index c0bc7d80..6d208598 100644 --- a/src/pdag.c +++ b/src/pdag.c @@ -1363,6 +1363,7 @@ fixJSON(struct ln_pdag *dag, /* Free the unneeded value */ json_object_put(*value); } + *value = NULL; } else if(prs->name[0] == '.' && prs->name[1] == '\0') { if(json_object_get_type(*value) == json_type_object) { struct json_object_iterator it = json_object_iter_begin(*value); @@ -1417,6 +1418,7 @@ fixJSON(struct ln_pdag *dag, } } r = 0; + *value = NULL; return r; } @@ -1588,7 +1590,7 @@ ln_normalizeRec(npb_t *const __restrict__ npb, size_t iprs; size_t parsedTo = npb->parsedTo; size_t parsed = 0; - struct json_object *value; + struct json_object *value = NULL; LN_DBGPRINTF(dag->ctx, "%zu: enter parser, dag node %p, json %p", offs, dag, json); @@ -1614,7 +1616,6 @@ LN_DBGPRINTF(dag->ctx, "%zu: enter parser, dag node %p, json %p", offs, dag, jso : "UNKNOWN"); } i = offs; - value = NULL; localR = tryParser(npb, dag, &i, &parsed, &value, prs, failOnDuplicate, json, prs->name); if(localR == 0) { parsedTo = i + parsed; @@ -1628,9 +1629,14 @@ LN_DBGPRINTF(dag->ctx, "%zu: enter parser, dag node %p, json %p", offs, dag, jso if(r == 0) { LN_DBGPRINTF(dag->ctx, "%zu: parser matches at %zu", offs, i); CHKR(fixJSON(dag, &value, json, prs)); + value = NULL; if(npb->ctx->opts & LN_CTXOPT_ADD_RULE) { add_rule_to_mockup(npb, prs); } + /* did we have a longer parser --> then update */ + if(parsedTo > npb->parsedTo) + npb->parsedTo = parsedTo; + } else { ++dag->stats.backtracked; #ifdef ADVANCED_STATS @@ -1639,14 +1645,16 @@ LN_DBGPRINTF(dag->ctx, "%zu: enter parser, dag node %p, json %p", offs, dag, jso #endif LN_DBGPRINTF(dag->ctx, "%zu nonmatch, backtracking required, parsed to=%zu", offs, parsedTo); - if (value != NULL) { /* Free the value if it was created */ - json_object_put(value); - } } } + if (value != NULL) { /* Free the value if it was created */ + json_object_put(value); + value = NULL; + } + /* did we have a longer parser --> then update */ - if(parsedTo > npb->parsedTo) - npb->parsedTo = parsedTo; + if(parsedTo > npb->longestParsedTo) + npb->longestParsedTo = parsedTo; LN_DBGPRINTF(dag->ctx, "parsedTo %zu, *pParsedTo %zu", parsedTo, npb->parsedTo); } @@ -1725,7 +1733,7 @@ ln_normalize(ln_ctx ctx, const char *str, const size_t strLen, struct json_objec addRuleMetadata(&npb, *json_p, endNode); r = 0; } else { - addUnparsedField(str, strLen, npb.parsedTo, *json_p); + addUnparsedField(str, strLen, npb.longestParsedTo, *json_p); } if(ctx->opts & LN_CTXOPT_ADD_RULE) { diff --git a/src/pdag.h b/src/pdag.h index 508bc6b0..63ee75c2 100644 --- a/src/pdag.h +++ b/src/pdag.h @@ -159,6 +159,7 @@ struct npb { const char *str; /**< to-be-normalized message */ size_t strLen; /**< length of it */ size_t parsedTo; /**< up to which byte could this be parsed? */ + size_t longestParsedTo; /**< up to which byte could this be parsed? */ es_str_t *rule; /**< a mock-up of the rule used to parse */ es_str_t *exec_path; #ifdef ADVANCED_STATS