Skip to content

refactor(json): scan string escapes with lexscan - #4095

Open
bobzhang wants to merge 1 commit into
agent/json-stringscannerfrom
agent/json-lexscan-string
Open

refactor(json): scan string escapes with lexscan#4095
bobzhang wants to merge 1 commit into
agent/json-stringscannerfrom
agent/json-lexscan-string

Conversation

@bobzhang

Copy link
Copy Markdown
Contributor

Step 2 of the plan behind #4094: with the parser state now being
@lexbuf.StringScanner, `lexscan` can drive parts of the lexer directly.
This converts the designated performance-non-critical spot — the string
slow path, entered only when a string contains an escape — to a lexscan
loop whose cases read like RFC 8259 §7: closing quote, longest ordinary
run, the eight single-character escapes, a BMP `\uXXXX` (first-digit
classes exclude the surrogate range), and a whole escaped surrogate
pair in one regex. The manual run bookkeeping (`start`/`flush`) is gone;
the compiler statically rejects shadowed cases (unused_lexcase).

Everything invalid falls to the wildcard, which leaves the cursor at
the failure point; `lex_string_failure` re-reads it with the old
per-character primitives so every error position is unchanged: bad
escape characters and hex digits are blamed themselves, unpaired
surrogate escapes at their opening backslash, EOF raises InvalidEof.
The 209-test suite (including the parse_error suites pinning exact
positions for every malformed-escape shape) passes unchanged on
wasm-gc, native and js, plus a new test for astral characters inside
slow-path runs — the negated class traverses surrogate pairs, and raw
lone surrogates still pass through as before (probed).

Measured on a new escape-heavy bench (previously zero bench coverage
for this path): js 687->682us and wasm-gc 1.21->1.22ms are unchanged;
native is 473->840us (~1.8x slower on escape-heavy strings), the cost
of DFA-generated code on the RC backend. Accepted deliberately: this
path is cold (ordinary strings never enter it), and the readability is
the point of the experiment. Fast-path benches are unchanged on all
targets.

Codex CLI review: approved — "Regex coverage, fallback error positions,
hex classes, surrogate arithmetic, and comments are consistent with the
prior behavior and RFC 8259. The hex partition and full surrogate range
also check out exhaustively."

Signed-off-by: Codex CLI <codex@openai.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant