-
Notifications
You must be signed in to change notification settings - Fork 10
/
pattern.h
92 lines (71 loc) · 2.73 KB
/
pattern.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//---------------------------------------------------------------------------
#pragma once
#include "pattern_quick_reject.h"
#include <stddef.h>
#include <string.h>
//---------------------------------------------------------------------------
class PatternComponent;
struct PatternContext;
//---------------------------------------------------------------------------
struct PatternMatch {
bool match;
const char *captures[8];
char *Replace(const char *format) const;
void SetCapture(size_t n, const char *p) {
captures[2 * n] = p;
captures[2 * n + 1] = p + strlen(p);
}
friend class Pattern;
};
// Super simple regex implementation tailored to embedded steno.
// This whole thing compiles to less than 4kb.
//
// Many typical regex library things are missing here, since they're just
// not needed. And the approaches chosen are NOT appropriate for more
// general regex libraries.
//
// But it *DOES* support group captures, which is the key thing missing
// from other tiny regex libraries.
//
// Notes:
//
// * It relies on tail call optimizations kicking in to avoid excessive
// stack usage.
//
// * There isn't even proper cleanup here, because it won't be used.
class Pattern {
public:
static Pattern Compile(const char *pattern);
PatternMatch Match(const char *text) const;
PatternMatch MatchBypassingQuickReject(const char *text) const;
PatternMatch Search(const char *text) const;
// Will free text if there's a replacement and return a new string.
char *Replace(char *text, const char *format) const;
bool IsPossibleMatch(PatternQuickReject inputQuickReject) const {
return inputQuickReject.IsPossibleMatch(quickReject);
}
const PatternQuickReject &GetQuickReject() const { return quickReject; }
private:
#if JAVELIN_USE_PATTERN_JIT
Pattern(bool (*matchMethod)(const char *start, const char **captures,
const char *text),
PatternQuickReject quickReject)
: matchMethod(matchMethod), quickReject(quickReject) {}
bool (*matchMethod)(const char *start, const char **captures,
const char *text);
#else
Pattern(PatternComponent *root, PatternQuickReject quickReject)
: root(root), quickReject(quickReject) {}
PatternComponent *root;
#endif
PatternQuickReject quickReject;
struct BuildContext;
struct BuildResult;
static BuildResult ParseAlternate(BuildContext &c);
static BuildResult ParseSequence(BuildContext &c);
static BuildResult ParseQuantifiedAtom(BuildContext &c);
static BuildResult ParseAtom(BuildContext &c);
static BuildResult ParseQuantifier(BuildContext &c, const BuildResult &atom);
static const char *FindLiteralEnd(const char *p);
};
//---------------------------------------------------------------------------