Skip to content

Decode Python string-literal escapes (\x, \u, \U, octal, control letters) (0041) - #490

Merged
rmorozov merged 5 commits into
masterfrom
claude/project-thread-v0hp79
Oct 12, 2026
Merged

rmorozov merged 5 commits into
masterfrom
claude/project-thread-v0hp79

Conversation

@rmorozov

Copy link
Copy Markdown
Member

Requested by Ruslan · project thread

Before: a string literal decoded only \n, \r and \t; 'A\x42' rendered Ax42, '\v' rendered v, and any unknown escape lost its backslash.

After: CompileEscapes decodes what Python's unicode-escape does: \a \b \f \n \r \t \v \\ \' \", backslash-newline (removed), 1-3 digit octal, \xHH, \uHHHH, \UHHHHHHHH (UTF-8, UTF-16 or UTF-32 by character type). An unknown escape such as \q keeps its backslash, as in Python. A truncated or out-of-range escape is a parse error (ErrorCode::UnexpectedToken on the literal), also in adjacent-literal runs.

How: CompileEscapes gains an ok out-parameter and is split into small helpers in src/helpers.h; LexerHelper::IsValidString lets the expression parser reject a bad literal before its value is built (only literals containing a backslash are scanned twice).

Deliberate divergence: \N{name} needs the Unicode name table and is rejected as malformed (literals.string_escape_named, kind rejects, still owned by 0041, which stays in-progress). Also added wide.filters.format_ascii_repr to the filters allow-list under 0035: it was hidden because é used to render as u00e9; the real cause is the wide-to-UTF-8 loss in the C locale.

Tests: 11 new corpus cases in literals.py, 3 rows leave the allow-list, unit tests in helpers_tests.cpp. Full suite and preflight (format, clang-tidy 22) pass locally.

Roles: none (main session); 0 verifier rounds; 0 red pushes so far.

🤖 Generated with Claude Code

https://claude.ai/code/session_01H8Fwx6ZYnAu1uY3tb6fSWK


Generated by Claude Code

…l letters) (0041)

CompileEscapes decodes what Python's unicode-escape does, keeps the backslash of an unknown
escape, and a malformed escape is a parse error. \N{name} is still rejected.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H8Fwx6ZYnAu1uY3tb6fSWK
…conversion (0041)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H8Fwx6ZYnAu1uY3tb6fSWK
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H8Fwx6ZYnAu1uY3tb6fSWK
@rmorozov
rmorozov merged commit 148ab1c into master Oct 12, 2026
41 checks passed
rmorozov added a commit that referenced this pull request Oct 12, 2026
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.

2 participants