Skip to content

Fix parsing of valid tag names that collide with move/NAG tokens#65

Merged
yo35 merged 1 commit into
yo35:masterfrom
siansell:fix/header-tag-name-token-collision
Jun 15, 2026
Merged

Fix parsing of valid tag names that collide with move/NAG tokens#65
yo35 merged 1 commit into
yo35:masterfrom
siansell:fix/header-tag-name-token-collision

Conversation

@siansell

Copy link
Copy Markdown
Contributor

Closes #64

Summary

Fixes parsing of spec-valid PGN tag pairs whose tag name looks like a SAN move or a NAG token (e.g. [New "..."], [N "..."], [RR "..."], [Nf3 "..."], [e4 "..."]), which previously threw Missing or invalid PGN game header ID.

Root cause

TokenStream.consumeToken() is context-free and tries the move-number / move / NAG matchers before HEADER_ID.

Right after a BEGIN_HEADER ([) the only valid token is the tag name, but a name matching the NAG regex (N, RR) or the move regex (Nf3, e4) was tokenized as a NAG/move first, so the header parser failed.

Fix

Make the tokenizer header-context-aware: when the previously emitted token is BEGIN_HEADER, match HEADER_ID first (and only).

If no tag name is present, throw the existing MISSING_PGN_HEADER_ID error at the same position, preserving the diagnostic for malformed input like ["Somewhere"].

_matchHeaderId (/(\w+)/) already matches exactly the spec-permitted tag-name characters (letters/digits/underscore, section 8.1), so no regex change is needed — only the dispatch order.

Tests

Adds a resource-driven regression fixture tag-name-token-collision (6 games covering New, bare N, RR, Nf3, e4, and New alongside a recognized Annotator).

13 content-tests fail without the fix; the whole suite (5616 tests) passes with it, and npm test (lint + unit) is green.

The PGN tokenizer (TokenStream.consumeToken) is context-free and tries the
move-number / move / NAG matchers before HEADER_ID. Immediately after a
BEGIN_HEADER ('['), the only valid token is the tag name, but a name matching
the NAG regex (e.g. N, RR) or the move regex (e.g. Nf3, e4) was tokenized as a
NAG/move first, so the header parser rejected it with "Missing or invalid PGN
game header ID". This made spec-valid tag pairs such as [New "..."] impossible
to parse.

Make the tokenizer header-context-aware: when the previously emitted token is
BEGIN_HEADER, match HEADER_ID first (and only), falling back to the existing
MISSING_PGN_HEADER_ID error at the same position when no tag name is present
(preserving the diagnostic for malformed input like ["Somewhere"]). _matchHeaderId
already matches exactly the spec-permitted tag-name characters, so only the
dispatch order changes.

Adds a resource-driven regression fixture (tag-name-token-collision) covering
New, bare N, RR, Nf3, e4, and New alongside a recognized Annotator tag.
@yo35 yo35 merged commit ae3a371 into yo35:master Jun 15, 2026
1 of 2 checks passed
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.

Valid PGN tag names that collide with move/NAG tokens fail to parse (e.g. [New "..."])

2 participants