Skip to content

Instantly share code, notes, and snippets.

@hongruiqi
Forked from timshen91/compile_time_regex.cc
Created February 23, 2016 12:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hongruiqi/6ef72ff9c5b36c2bdf81 to your computer and use it in GitHub Desktop.
Save hongruiqi/6ef72ff9c5b36c2bdf81 to your computer and use it in GitHub Desktop.
template <typename Left, typename Right>
struct ConcatExpr;
template <typename Left, typename Right>
struct AltExpr;
template <typename SubExpr>
struct RepeatExpr;
template <typename SubExpr>
struct OptionalExpr;
template <char ch>
struct MatchExpr;
template <typename RegExpr>
struct MatchImpl;
template <typename Left, typename Right>
struct MatchImpl<ConcatExpr<Left, Right>> {
template <typename Continuation>
static bool Apply(const char* target, Continuation cont) {
return MatchImpl<Left>::Apply(target, [cont](const char* rest) -> bool {
return MatchImpl<Right>::Apply(rest, cont);
});
}
};
template <typename Left, typename Right>
struct MatchImpl<AltExpr<Left, Right>> {
template <typename Continuation>
static bool Apply(const char* target, Continuation cont) {
return MatchImpl<Left>::Apply(target, cont) ||
MatchImpl<Right>::Apply(target, cont);
}
};
template <typename SubExpr>
struct MatchImpl<RepeatExpr<SubExpr>> {
template <typename Continuation>
static bool Apply(const char* target, Continuation cont) {
return MatchImpl<SubExpr>::Apply(
target,
[cont](const char* rest) -> bool {
return MatchImpl<RepeatExpr<SubExpr>>::Apply(rest, cont) ||
cont(rest);
}) ||
cont(target);
}
};
template <typename SubExpr>
struct MatchImpl<OptionalExpr<SubExpr>> {
template <typename Continuation>
static bool Apply(const char* target, Continuation cont) {
return MatchImpl<SubExpr>::Apply(target, cont) || cont(target);
}
};
template <char ch>
struct MatchImpl<MatchExpr<ch>> {
template <typename Continuation>
static bool Apply(const char* target, Continuation cont) {
return *target && *target == ch && cont(target + 1);
}
};
template <typename RegExpr>
bool RegexMatch(const char* target) {
return MatchImpl<RegExpr>::Apply(
target, [](const char* rest) -> bool { return *rest == '\0'; });
}
template <typename RegExpr>
bool RegexSearch(const char* target) {
return MatchImpl<RegExpr>::Apply(
target, [](const char* rest) -> bool { return true; }) ||
(*target && RegexSearch<RegExpr>(target + 1));
}
#include <cassert>
int main() {
assert((RegexMatch<ConcatExpr<MatchExpr<'a'>, MatchExpr<'b'>>>("ab")));
assert((RegexMatch<AltExpr<MatchExpr<'a'>, MatchExpr<'b'>>>("a")));
assert((RegexMatch<AltExpr<MatchExpr<'a'>, MatchExpr<'b'>>>("b")));
assert((RegexMatch<RepeatExpr<MatchExpr<'a'>>>("aaaaa")));
assert((RegexMatch<ConcatExpr<RepeatExpr<MatchExpr<'a'>>, MatchExpr<'b'>>>(
"aaaaab")));
assert((
RegexMatch<ConcatExpr<RepeatExpr<MatchExpr<'a'>>, MatchExpr<'b'>>>("b")));
assert((RegexSearch<ConcatExpr<RepeatExpr<MatchExpr<'a'>>, MatchExpr<'b'>>>(
"aaaaabb")));
assert((RegexMatch<OptionalExpr<MatchExpr<'a'>>>("a")));
assert((RegexMatch<OptionalExpr<MatchExpr<'a'>>>("")));
assert((RegexMatch<OptionalExpr<ConcatExpr<MatchExpr<'a'>, MatchExpr<'b'>>>>(
"ab")));
assert((RegexMatch<OptionalExpr<ConcatExpr<MatchExpr<'a'>, MatchExpr<'b'>>>>(
"")));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment