Files
regex-tools/docs/FLAVOUR_SUPPORT.md

88 lines
7.9 KiB
Markdown

# Flavour support
Version 0.4.0 exposes twelve executable profiles. “Partial lexical provider”
means that Regex Tools recognizes common structure and replacement tokens for
explanation only; the named runtime compiler and replacement operation remain
authoritative.
| Profile | Syntax and execution identity | Replacement | Captures and native offsets |
| ----------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| JavaScript (ECMAScript) | regexpp 4.12.2 with ECMAScript 2025 syntax; current browser `RegExp` executes | Bounded ECMAScript `GetSubstitution` | Named/numbered, final repeated capture; UTF-16 |
| PCRE2 | Partial provider; official standalone PCRE2 10.47 8-bit WASM executes in mandatory UTF/UCP mode | Native bounded `pcre2_substitute()` loop | Native named/numbered records, no history; UTF-8 bytes |
| PHP | Partial provider; actual PHP 8.5.8 `preg_*` in `@php-wasm/web-8-5` 3.1.46, reporting PCRE2 10.44 | Fixed bounded PHP-token expansion; load-time `preg_replace()` parity | Native named/numbered records, no history; UTF-8 bytes |
| Perl | Partial provider; actual Perl 5.28.1 through legacy WebPerl 0.09-beta | Fixed bounded literal/`$$`/`$n`/`${name}` expansion; arbitrary Perl expressions unavailable | Native numbered spans plus bounded name annotations, no history; Unicode code points |
| Python | Partial provider; CPython 3.14.2 `re` in Pyodide 314.0.3 | Native bounded `re` expansion | Native named/numbered spans, no history; Unicode code points |
| Ruby | Partial provider; CRuby 4.0.0 `Regexp` in ruby.wasm 2.9.3-2.9.4 | Native `gsub`/`sub` iteration plus bounded CRuby 4.0.0-compatible expansion | Native named/numbered spans, no history; Unicode code points |
| Java | Partial provider; TeaVM 0.15.0 `java.util.regex`, not OpenJDK | TeaVM single-digit `$n`; no `${name}` | Native numbered ranges plus lexical names, no history; UTF-16 |
| C++ | Partial provider; Emscripten 6.0.4 libc++ `std::wregex`; modified ECMAScript grammar by default | Fixed bounded formatter; load-time libc++ `match.format` parity | Numbered captures only, no history; 32-bit `wchar_t` code points |
| Go | Partial provider; Go 1.26.5 standard-library `regexp` with RE2 syntax | Fixed bounded expansion; load-time `regexp.ExpandString` parity | Native named/numbered records, no history; UTF-8 bytes |
| Rust | Partial provider; Rust `regex` crate 1.13.1, built with rustc 1.97.1 | Fixed bounded expansion; load-time `Captures::expand` parity | Native named/numbered records, no history; UTF-8 bytes |
| .NET | Partial provider; .NET 10.0.10 `System.Text.RegularExpressions`, invariant culture | Fixed streaming .NET-token expansion with load-time native `Match.Result` parity | Named/numbered final records, no capture history in this adapter; UTF-16 |
| Scala/JVM compatibility | Partial provider; explicitly shares TeaVM 0.15.0 `java.util.regex`; no Scala runtime | Same TeaVM single-digit `$n` subset; no `${name}` | Same ranges as the TeaVM Java adapter; UTF-16 |
## Flags and options
- JavaScript exposes `g`, `i`, `m`, `s`, `u`, `v`, `y` and `d`; `u` and `v`
are mutually exclusive.
- Standalone PCRE2 exposes application iteration `g` plus `i`, `m`, `s`, `x`,
`U` and `J`, with match-step, depth and heap limits. UTF/UCP is mandatory.
- PHP exposes application iteration `g` plus the reviewed `preg` modifiers
`i`, `m`, `s`, `x`, `u`, `U`, `A`, `D`, `J`, `n` and `r`. PHP's `u` is not
conflated with standalone PCRE2's mandatory UTF/UCP configuration.
- Legacy Perl exposes `g`, `i`, `m`, `s`, `x`, `n` and one of `a`, `d`, `l` or
`u`. The two-character `/aa` mode is not exposed.
- Python exposes application iteration `g` plus `a`, `i`, `m`, `s` and `x`.
- Ruby exposes application iteration `g` plus `i`, `m` and `x`; Ruby `m`
includes dot-all behavior.
- Java and Scala compatibility expose application iteration `g` plus TeaVM
`Pattern` flags `i`, `d`, `m`, `s`, `u`, `x` and the documented `U`
compatibility request.
- C++ exposes application iteration `g` plus `i`, `n`, `o` and `c`, and a
required grammar option: `ECMAScript`, `basic`, `extended`, `awk`, `grep` or
`egrep`.
- Go exposes application iteration `g` plus `i`, `m`, `s` and `U`.
- Rust exposes application iteration `g` plus `i`, `m`, `s`, `U`, `u`, `x` and
`R`; Unicode is enabled by default.
- .NET exposes application iteration `g` plus `i`, `m`, `s`, `n`, `x`, `r`,
`c` and `b`. Execution is always culture invariant; `c` makes that fixed
compatibility choice explicit.
## Verified boundaries
Every adapter has focused identity, request and result-contract tests.
Conformance and browser suites exercise compilation errors, bounded matching,
zero-length iteration, range normalization, replacement and worker recovery
across the profile set. Pack verifiers additionally check self-hosted assets,
metadata, closed-file-set checksums and applicable licences/notices.
TeaVM supplies an Apache Harmony-derived class library. It is not OpenJDK and
does not implement OpenJDK `Pattern.UNICODE_CHARACTER_CLASS`; `U` means the
documented TeaVM compatibility behavior in both the Java and Scala profiles.
The Scala profile also does not implement `scala.util.matching.Regex` wrapper
or extractor APIs.
The Perl target is intentionally legacy. Its unmodified WebPerl loader contains
one `eval(code)` site in an optional Perl-to-JavaScript interoperability import.
The fixed Regex Tools bridge does not load that facility, accepts pattern and
replacement values only as JSON data, uses `no re 'eval'`, rejects `(?{...})`
and `(??{...})`, and passes the documented CSP smoke without broad
`'unsafe-eval'`.
## Feature scope
Static findings, bounded growth probes, benchmarks, generated cases and
formatting are ECMAScript-only. Generated-case version 1 requires the complete
accepted regexpp AST and verifies every retained label through the actual
browser engine. No partial provider is passed through that generator or
formatter.
Automatic-callout tracing and reviewed C17 code generation are standalone
PCRE2-only. The PHP profile does not reuse the standalone PCRE2 10.47 trace or
code-generation path because its authoritative engine is PHP `preg` with
PCRE2 10.44.
Exact-request semantic comparison and subject minimization support only their
reviewed ECMAScript/standalone-PCRE2 paths. Other selections are disabled
rather than routed through another profile. Results never claim generic
twelve-way equivalence.