diff --git a/Makefile b/Makefile index 2670f87..ba5fd3a 100644 --- a/Makefile +++ b/Makefile @@ -95,6 +95,6 @@ uninstall: fi profile: - perf stat -r 20 -e L1-dcache-loads,L1-dcache-load-misses,L1-dcache-stores -e cycles bp -f plain -g bp -p Grammar grammars/bp.bp >/dev/null + perf stat -r 100 -e L1-dcache-loads,L1-dcache-load-misses,L1-dcache-stores -e cycles bp -f plain -g bp -p Grammar grammars/bp.bp >/dev/null .PHONY: all clean install install-lib uninstall leaktest splint test tutorial lua profile diff --git a/match.c b/match.c index 6c55fbc..0ff6243 100644 --- a/match.c +++ b/match.c @@ -364,11 +364,11 @@ static match_t *match(match_ctx_t *ctx, const char *str, pat_t *pat) // a special case, but if a pattern invokes itself at a later // point, it can be handled with normal recursion. // See: left-recursion.md for more details. - if (str == pat->args.leftrec.at) { - pat->args.leftrec.visited = true; - return clone_match(pat->args.leftrec.match); + if (str == pat->args.leftrec->at) { + pat->args.leftrec->visited = true; + return clone_match(pat->args.leftrec->match); } else { - return match(pat->args.leftrec.ctx, str, pat->args.leftrec.fallback); + return match(pat->args.leftrec->ctx, str, pat->args.leftrec->fallback); } } case BP_ANYCHAR: { @@ -678,7 +678,7 @@ static match_t *match(match_ctx_t *ctx, const char *str, pat_t *pat) .type = BP_LEFTRECURSION, .start = ref->start, .end = ref->end, .min_matchlen = 0, .max_matchlen = -1, - .args.leftrec = { + .args.leftrec = &(leftrec_info_t){ .match = NULL, .visited = false, .at = str, @@ -702,10 +702,10 @@ static match_t *match(match_ctx_t *ctx, const char *str, pat_t *pat) match_t *m = match(&ctx2, str, ref); // If left recursion was involved, keep retrying while forward progress can be made: - if (m && rec_op.args.leftrec.visited) { + if (m && rec_op.args.leftrec->visited) { while (1) { const char *prev = m->end; - rec_op.args.leftrec.match = m; + rec_op.args.leftrec->match = m; ctx2.cache = &(cache_t){0}; match_t *m2 = match(&ctx2, str, ref); cache_destroy(&ctx2); diff --git a/pattern.c b/pattern.c index 9620c5d..9eee45a 100644 --- a/pattern.c +++ b/pattern.c @@ -723,7 +723,7 @@ void delete_pat(pat_t **at_pat, bool recursive) delete_pat(&pat->args.pat, true); break; case BP_LEFTRECURSION: - delete_pat(&pat->args.leftrec.fallback, true); + delete_pat(&pat->args.leftrec->fallback, true); break; default: break; } diff --git a/pattern.h b/pattern.h index 7569849..a36885e 100644 --- a/pattern.h +++ b/pattern.h @@ -5,6 +5,7 @@ #define PATTERN__H #include +#include #include #define UNBOUNDED(pat) ((pat)->max_matchlen == -1) @@ -47,27 +48,28 @@ enum pattype_e { typedef struct pat_s { struct pat_s *next, **home; enum pattype_e type; + uint32_t id; const char *start, *end; // The bounds of the match length (used for backtracking) - size_t min_matchlen; - ssize_t max_matchlen; // -1 means unbounded length + uint32_t min_matchlen; + int32_t max_matchlen; // -1 means unbounded length union { const char *string; struct { const char *name; - size_t len; + uint32_t len; } ref; struct { const char *name; - size_t namelen; + uint32_t namelen; struct pat_s *meaning, *next_def; } def; struct { unsigned char low, high; } range; struct { - size_t min; - ssize_t max; + uint32_t min; + int32_t max; struct pat_s *sep, *repeat_pat; } repetitions; // TODO: use a linked list instead of a binary tree @@ -77,29 +79,30 @@ typedef struct pat_s { struct { struct pat_s *pat; const char *text; - size_t len; + uint32_t len; } replace; struct { struct pat_s *capture_pat; const char *name; - size_t namelen; + uint16_t namelen; bool backreffable; } capture; - struct { - struct match_s *match; - const char *at; - struct pat_s *fallback; - void *ctx; - bool visited; - } leftrec; + struct leftrec_info_s *leftrec; struct { const char *start, *end, *msg; } error; struct pat_s *pat; } args; - size_t id; } pat_t; +typedef struct leftrec_info_s { + struct match_s *match; + const char *at; + struct pat_s *fallback; + void *ctx; + bool visited; +} leftrec_info_t; + typedef struct { bool success; union {