Microoptimizations
This commit is contained in:
parent
6b8f1a09d0
commit
9e07e08a48
2
Makefile
2
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
|
||||
|
14
match.c
14
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
35
pattern.h
35
pattern.h
@ -5,6 +5,7 @@
|
||||
#define PATTERN__H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#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 {
|
||||
|
Loading…
Reference in New Issue
Block a user