snapkitty-regex / README.md
SNAPKITTYWEST's picture
Model card: restore full README from GitHub, add commercial license option
d0ab4ec verified
|
Raw History Blame Contribute Delete
4.31 kB
---
license: agpl-3.0
tags:
- snapkitty
- october-2026-drop
- c
- python
- regex
- thompson-nfa
- zero-dependency
- developer-tools
---
> Mirrored from [https://github.com/SNAPKITTYWEST/snapkitty-regex](https://github.com/SNAPKITTYWEST/snapkitty-regex) at commit `b14a2eb`. Part of the **SnapKitty October 2026 main drop**.
# snapkitty-regex
A Thompson NFA regular expression engine in C — under 700 lines, zero
dependencies, no exponential backtracking, ever.
Built as an exercise from the guides in
[AHMADALIPARR/build-your-own-x](https://github.com/AHMADALIPARR/build-your-own-x)
("Build your own `Regex Engine`"), primarily Russ Cox's
*[Regular Expression Matching Can Be Simple And Fast](https://swtch.com/~rsc/regexp/regexp1.html)*.
## The idea
Most popular regex engines (Perl, Python, Ruby, Java, PCRE) simulate an
NFA by *backtracking*: guess a path, and retry on failure. On patterns
like `a?a?a?aaa` that means trying all 2^n combinations — Perl needs
**60+ seconds** to match a 29-character string.
This engine instead simulates *all* NFA paths in parallel, tracking the
set of reachable states one input character at a time (Thompson's 1968
algorithm). Matching is **O(m·n)** worst case for pattern length m and
text length n. There are no pathological inputs.
```
infix pattern --re2post--> postfix --post2nfa--> NFA --pump--> match?
(explicit '.' concat) (Thompson construction)
```
## Syntax
| construct | meaning |
|---|---|
| `abc` | literal characters match themselves |
| `e1 e2` | concatenation |
| `e1\|e2` | alternation |
| `e*` | zero or more |
| `e+` | one or more |
| `e?` | zero or one |
| `(e)` | grouping |
| `\` + metachar | literal metacharacter: `\* \+ \? \| \( \) \\` |
| `.` | literal dot (no wildcard — see roadmap) |
Precedence: `|` weakest, then concatenation, then `* + ?`. Matching is
byte-oriented.
## Build & test
```sh
make # builds ./regex, clean compile, zero warnings
make test # 82-check correctness harness (fullmatch, search, bad patterns)
make bench # pathological benchmark vs Python's re
```
## Usage
```sh
$ ./regex 'a(bb)+a' abbbba abba abbba
abbbba: MATCH
abba: MATCH
abbba: NO MATCH
$ ./regex -s 'colou?r' 'the colour blue'
the colour blue: MATCH
```
Exit codes: `0` all matched, `1` some didn't, `2` usage/bad pattern.
As a library (`src/regex.h`):
```c
Regex *re = re_compile("(ab|cd)+e");
int m = re_fullmatch(re, "cdabe"); /* whole string */
int p = re_match(re, "cdabex"); /* prefix of string */
int s = re_search(re, "xxcdabexx"); /* anywhere in string */
re_free(re);
```
## Benchmark
`a?`^n`a`^n against `a`^n — the article's pathological case:
| n | snapkitty-regex | python `re` |
|---|---|---|
| 10 | 0.0011s | 0.0000s |
| 20 | 0.0010s | 0.0442s |
| 24 | 0.0013s | 0.7139s |
| 26 | 0.0014s | 3.0580s |
| 500 | 0.0021s | (heat death of universe) |
(The ~1ms floor on our side is process-spawn overhead, not matching.)
## What's hardened vs the article's reference code
- **No fixed static buffers** — postfix output and the paren stack are
sized from the input instead of `char buf[8000]` / `paren[100]`.
- **Backslash escapes** for metacharacters.
- **Literal dots** — a `.` in the pattern can't collide with the postfix
concatenation operator anymore (this crashes the original).
- **Real error paths** — malformed patterns and `malloc` failures return
`NULL` instead of crashing; partial allocations unwind cleanly.
- **Reusable, releasable** — compiled patterns are opaque `Regex*`
values with `re_free`; the accept state and dedup generation are
per-pattern, not globals.
- **Prefix match + search** on top of full match.
## Roadmap
- `.` wildcard / character classes `[a-z]`
- Capture groups and submatch extraction
- DFA / hybrid execution for very large inputs
- Streaming matcher API
---
### 💼 Commercial License
SnapKitty code is free and open under **AGPL-3.0** for open-source use. Building a commercial product or service? A **proprietary commercial license** from Snapkitty Collective LLC lets you ship this code without the AGPL's source-sharing and network-use obligations.
**[→ Get a commercial license](mailto:A.parr@belespritdaccord.uk?subject=Commercial%20license:%20snapkitty-regex)** · A.parr@belespritdaccord.uk