Skip to content

Commit daafc53

Browse files
Kenneth Sheltonjulthomas
authored andcommitted
Fix backtracking
1 parent 192fa5a commit daafc53

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

src/parser.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3006,10 +3006,12 @@ PARSER_Parse(Repeat)
30063006
struct data_Repeat *const data = (struct data_Repeat*) pdata;
30073007
struct ln_pdag *endNode = NULL;
30083008
size_t strtoffs = *offs;
3009+
size_t lastMatch = strtoffs;
30093010
size_t lastKnownGood = strtoffs;
30103011
struct json_object *json_arr = NULL;
30113012
struct json_object *parsed_value = NULL;
30123013
const size_t parsedTo_save = npb->parsedTo;
3014+
const size_t longestParsedTo_save = npb->longestParsedTo;
30133015
int mergeResults = parser_name != NULL && parser_name[0] == '.' && parser_name[1] == '\0';
30143016

30153017
do {
@@ -3031,6 +3033,8 @@ PARSER_Parse(Repeat)
30313033
"parse ptr back to %zd", strtoffs);
30323034
goto success;
30333035
} else {
3036+
// Reset longest match
3037+
npb->longestParsedTo = lastMatch > longestParsedTo_save ? lastMatch : longestParsedTo_save;
30343038
goto done;
30353039
}
30363040
}
@@ -3070,6 +3074,7 @@ PARSER_Parse(Repeat)
30703074

30713075
/* now check if we shall continue */
30723076
npb->parsedTo = 0;
3077+
lastMatch = lastKnownGood;
30733078
lastKnownGood = strtoffs; /* record pos in case of fail in while */
30743079
r = ln_normalizeRec(npb, data->while_cond, strtoffs, 1, NULL, &endNode, 0, NULL, parser_name);
30753080
LN_DBGPRINTF(npb->ctx, "repeat while returns %d, parsed %zu",

src/pdag.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,7 @@ fixJSON(struct ln_pdag *dag,
13631363
/* Free the unneeded value */
13641364
json_object_put(*value);
13651365
}
1366+
*value = NULL;
13661367
} else if(prs->name[0] == '.' && prs->name[1] == '\0') {
13671368
if(json_object_get_type(*value) == json_type_object) {
13681369
struct json_object_iterator it = json_object_iter_begin(*value);
@@ -1417,6 +1418,7 @@ fixJSON(struct ln_pdag *dag,
14171418
}
14181419
}
14191420
r = 0;
1421+
*value = NULL;
14201422
return r;
14211423
}
14221424

@@ -1588,7 +1590,7 @@ ln_normalizeRec(npb_t *const __restrict__ npb,
15881590
size_t iprs;
15891591
size_t parsedTo = npb->parsedTo;
15901592
size_t parsed = 0;
1591-
struct json_object *value;
1593+
struct json_object *value = NULL;
15921594

15931595
LN_DBGPRINTF(dag->ctx, "%zu: enter parser, dag node %p, json %p", offs, dag, json);
15941596

@@ -1614,7 +1616,6 @@ LN_DBGPRINTF(dag->ctx, "%zu: enter parser, dag node %p, json %p", offs, dag, jso
16141616
: "UNKNOWN");
16151617
}
16161618
i = offs;
1617-
value = NULL;
16181619
localR = tryParser(npb, dag, &i, &parsed, &value, prs, failOnDuplicate, json, prs->name);
16191620
if(localR == 0) {
16201621
parsedTo = i + parsed;
@@ -1628,9 +1629,14 @@ LN_DBGPRINTF(dag->ctx, "%zu: enter parser, dag node %p, json %p", offs, dag, jso
16281629
if(r == 0) {
16291630
LN_DBGPRINTF(dag->ctx, "%zu: parser matches at %zu", offs, i);
16301631
CHKR(fixJSON(dag, &value, json, prs));
1632+
value = NULL;
16311633
if(npb->ctx->opts & LN_CTXOPT_ADD_RULE) {
16321634
add_rule_to_mockup(npb, prs);
16331635
}
1636+
/* did we have a longer parser --> then update */
1637+
if(parsedTo > npb->parsedTo)
1638+
npb->parsedTo = parsedTo;
1639+
16341640
} else {
16351641
++dag->stats.backtracked;
16361642
#ifdef ADVANCED_STATS
@@ -1639,14 +1645,16 @@ LN_DBGPRINTF(dag->ctx, "%zu: enter parser, dag node %p, json %p", offs, dag, jso
16391645
#endif
16401646
LN_DBGPRINTF(dag->ctx, "%zu nonmatch, backtracking required, parsed to=%zu",
16411647
offs, parsedTo);
1642-
if (value != NULL) { /* Free the value if it was created */
1643-
json_object_put(value);
1644-
}
16451648
}
16461649
}
1650+
if (value != NULL) { /* Free the value if it was created */
1651+
json_object_put(value);
1652+
value = NULL;
1653+
}
1654+
16471655
/* did we have a longer parser --> then update */
1648-
if(parsedTo > npb->parsedTo)
1649-
npb->parsedTo = parsedTo;
1656+
if(parsedTo > npb->longestParsedTo)
1657+
npb->longestParsedTo = parsedTo;
16501658
LN_DBGPRINTF(dag->ctx, "parsedTo %zu, *pParsedTo %zu", parsedTo, npb->parsedTo);
16511659
}
16521660

@@ -1725,7 +1733,7 @@ ln_normalize(ln_ctx ctx, const char *str, const size_t strLen, struct json_objec
17251733
addRuleMetadata(&npb, *json_p, endNode);
17261734
r = 0;
17271735
} else {
1728-
addUnparsedField(str, strLen, npb.parsedTo, *json_p);
1736+
addUnparsedField(str, strLen, npb.longestParsedTo, *json_p);
17291737
}
17301738

17311739
if(ctx->opts & LN_CTXOPT_ADD_RULE) {

src/pdag.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ struct npb {
159159
const char *str; /**< to-be-normalized message */
160160
size_t strLen; /**< length of it */
161161
size_t parsedTo; /**< up to which byte could this be parsed? */
162+
size_t longestParsedTo; /**< up to which byte could this be parsed? */
162163
es_str_t *rule; /**< a mock-up of the rule used to parse */
163164
es_str_t *exec_path;
164165
#ifdef ADVANCED_STATS

0 commit comments

Comments
 (0)