Skip to content

fix(grammar): accept Unicode identifiers in Pascal (#2211) - #2356

Open
DeusData wants to merge 1 commit into
mainfrom
fix/issue-2211
Open

DeusData wants to merge 1 commit into
mainfrom
fix/issue-2211

Conversation

@DeusData

Copy link
Copy Markdown
Owner

Delphi code that calls 1C's OLE API through late-bound Variants uses Cyrillic member names. The vendored tree-sitter-pascal (Isopod @ 042119eca2e1, = upstream HEAD) has an ASCII-only identifier token, so every such name was an ERROR node: the unit was flagged parse_partial and Cyrillic-named procedures were dropped.

  • pascal becomes a self-maintained fork (arkts / JSX model) in tools/tree-sitter-pascal/. One patch changes only the identifier token to /[&]?[\p{L}_][\p{L}\p{M}\p{Nd}_]*/. Keywords (word extraction), node types and ABI (14) are unchanged; the vendored parser.c has 0 non-ASCII bytes; the LICENSE is upstream's MIT, byte-identical.
  • Fidelity: the unpatched 0.25.10 regeneration and the patched parser give parse trees byte-identical to upstream's shipped parser on upstream's 88 corpus cases and its 3 example units.
  • Proof on 7 Pascal files: parse_partial 3 → 1 (only the genuinely broken unit), nodes 581 → 582 (the Cyrillic procedure), edges 1480 → 1482; ASCII files unchanged.
  • Tests: parse_coverage covers the report's snippet, a Cyrillic procedure name, an ASCII control, and a guard that broken Pascal is still flagged; plus the fork corpus test/corpus/unicode_identifiers.txt.
  • Registered: MANIFEST.md, audit FORKS map, THIRD_PARTY.md, vendored checksums (updated after the final MANIFEST edit). Local security-static scripts pass; license-gate (scancode) and audit-license-provenance.py run in CI only.

Merge note: this PR and #2327 (JSX fork) edit the same lines (MANIFEST.md summary counts, THIRD_PARTY.md fork list, the audit FORKS map, vendored-checksums.txt). Whichever merges second needs a rebase, a recount (first-party/self-maintained becomes 17 with both), and a final scripts/security-vendored.sh --update.

The fork can be dropped if upstream adopts Unicode identifiers.

Fixes #2211

Delphi code that calls 1C's OLE API through late-bound Variants uses
Cyrillic member names (v8_Base.<Cyrillic>.<Cyrillic>('1', Now),
NM.<Cyrillic>()). Every such name produced a tree-sitter ERROR node, so the
unit was reported as parse_partial and a procedure whose own name is
Cyrillic was dropped from the graph.

Root cause is upstream tree-sitter-pascal (Isopod, the pin we vendor):
its identifier token is ASCII-only, /[&]?[a-zA-Z_]+[0-9_a-zA-Z]*/, and
there is no other token a non-ASCII letter can lex as.

Fix: pascal becomes a self-maintained fork of the pin we already vendored
(Isopod/tree-sitter-pascal @ 042119eca2e1, v0.10.2 = upstream master),
following the arkts model. One patch
(tools/tree-sitter-pascal/patches/unicode-identifiers.patch) changes only
that token to /[&]?[\p{L}_][\p{L}\p{M}\p{Nd}_]*/. Keywords are still
extracted from this `word` token, so begin/end/procedure lex as before
(`begin` glued to Cyrillic letters is one identifier; `&begin` stays an
escaped identifier). Node types are unchanged. The \p{} classes compile
to numeric code-point ranges: the vendored parser.c has 0 non-ASCII bytes.
Regenerated with tree-sitter-cli 0.25.10 --abi 14 (ABI unchanged, no
external scanner; tree_sitter/parser.h is byte-identical to chialisp's).

Fidelity: the UNPATCHED grammar regenerated with 0.25.10 gives the same
symbol/token/field/production counts as upstream's shipped parser and
byte-identical parse trees on upstream's 88 corpus cases and its three
examples/*.pas (37,773 tree lines for codetoolmanager.pas); the patched
parser gives the same identical trees on all of those ASCII inputs and
passes all 88 corpus cases.

Proof (7 Pascal files: the report's snippet, a Cyrillic procedure with
keyword-boundary cases, an ASCII control, a broken unit, upstream's three
examples; fresh caches): parse_partial 3 -> 1 (only the genuinely broken
unit remains), nodes 581 -> 582 (the Cyrillic-named procedure), edges
1480 -> 1482 (+1 DEFINES, +1 SEMANTICALLY_RELATED); per-file function
counts for the ASCII files are unchanged.

Registered like arkts: MANIFEST.md fork row + note, audit FORKS map,
THIRD_PARTY.md, vendored checksums. LICENSE stays upstream's MIT,
byte-identical.

Tests: parse_coverage gains the report's snippet and a Cyrillic-named
procedure (not partial, definitions extracted), an ASCII control, and a
guard that broken Pascal is still flagged; the fork carries
test/corpus/unicode_identifiers.txt.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>

This branch has not been deployed

No deployments
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.

Indexing gap: 1C.pas using Cyrillic identifiers

1 participant