Highlights
This release introduces first-character dispatch for parser tokenization, delivering a consistent 1.6–1.8× speedup on parser workloads, and adds crash-safe golden-file validation to the test suite infrastructure.
New Features
TRegexSet — First-character dispatch for multi-regex matching
A new TRegexSet class precomputes a dispatch table that maps each possible first input byte to the subset of regexes that could match. This replaces the parser's linear scan over all rules with an O(1) table lookup followed by iteration over only the candidate regexes.
The dispatch table has three tiers:
- 128 per-ASCII-byte candidate lists, populated from each regex's start-state epsilon closure.
- A shared candidate list for non-ASCII first bytes (128–255).
- A precomputed index for the first empty-matchable regex (used when input is exhausted).
API additions:
TRegexSet— constructors accepting pointer+count,initializer_list, iterator pairs, and iterator+projection.TRegexMatch::try_match()— public entry point for attempting a match without consuming input.TRegexIterator::consume_first_match(TRegexMatch&, TRegexSet&)— consumes the first matching regex from a set.RegexEngine::FirstCharInfo— struct describing the set of bytes that can start a match for a regex (withtest(),minimal(),maximal()helpers).RegexEngine::first_char_info()— returns cachedFirstCharInfocomputed during construction.regex::is_ascii(rune_t)— utility predicate.
The Parse class now builds a TRegexSet per mode and uses consume_first_match() internally. No changes are required to existing parser code — the speedup is automatic.
Testsuite crash rejection and multi-suite support
- Crash-safe golden files: A new validation gate runs between test execution and golden-file copying during
update-dump. It rejects non-numeric exit codes (e.g."Segmentation fault","Aborted") so that crashes are never silently accepted as expected output. - Custom validators: Collection
.cmakefiles can setTESTSUITE_VALIDATORto a CMake script for additional project-specific checks. - Multiple test suites per project:
testsuite()can now be called multiple times. Each call creates per-suite targets (e.g.infix-update-dump,shrubbery-update-dump), and the globalupdate-dump/update-dump-cleantargets aggregate all suites. Duplicatetestsuite()calls with the same name produce a clear error.
Breaking Changes
- The internal
Parse::rulesmember was renamed torules_. This is a private member and should not affect downstream users. - Per-collection
update-dump-*CMake targets are now prefixed with the suite name (e.g.update-dump-examples→infix-update-dump-examples). The globalupdate-dumpandupdate-dump-cleantargets continue to work unchanged.