Skip to content

fix(parser): preserve comma lists and multi-dataset bar groups verbatim - #27

Merged
BenHuddart merged 1 commit into
mainfrom
claude/dazzling-sanderson-a47350
Aug 6, 2026
Merged

BenHuddart merged 1 commit into
mainfrom
claude/dazzling-sanderson-a47350

Conversation

@BenHuddart

Copy link
Copy Markdown
Owner

Summary

Fixes two parser round-trip corruptions found by GLEstudio's Phase-3 gate review against the GLE manual corpus (reproducer: appendix/fig/single.gle).

  • Comma-list corruption: passthrough for unmodeled bar/fill statements rejoined tokens with " ".join(...), turning fill x1,d1 color gray10 into fill x1 , d1 color gray10 — which GLE rejects with illegal data set identifier. Passthrough now falls back to the statement's verbatim source text instead of a token rejoin.
  • Silent multi-dataset bar drop: bar d1,d2 fill green,blue groups multiple datasets into one GLE command (side-by-side grouped bars). gleplot has no BarSeries model for a shared group, so it silently modeled only the last dataset (bar d1 fill green) and dropped d2/blue with no warning. It's now kept verbatim in the axes passthrough with a structure: warning, satisfying the recognizer's no-silent-drops contract.

While verifying the fix against the real gle binary, I found a follow-on gap the multi-dataset fix introduced: once a bar/fill statement becomes unmodeled passthrough, nothing carries its data_file anymore, so the writer was silently omitting the data single.dat statement those datasets depend on — producing GLE that references undefined datasets. Added reconciliation logic that restores the original data statement verbatim when all its datasets end up orphaned this way (and warns instead of guessing when a data statement's datasets are a mix of modeled and orphaned).

Test plan

  • Added 5 new regression tests (Finding 17) in tests/parser/test_recognizer_adversarial.py, including an end-to-end test that compiles the regenerated GLE with the real gle binary
  • Verified the actual manual reproducer (appendix/fig/single.gle) round-trips and compiles cleanly with gle 4.3.10, and that a second parse→save cycle is a byte-exact fixed point
  • Full suite passes: PYTHONPATH=$PWD/src .venv/bin/python -m pytest tests/ -q → 2090 passed, 2 skipped
  • GUI suite passes: tests/gui/ → 432 passed
  • black --check clean on touched files

🤖 Generated with Claude Code

Two round-trip corruptions found by GLEstudio's Phase-3 gate review
against the GLE manual corpus (appendix/fig/single.gle):

- bar/fill passthrough rejoined tokens with spaces, turning
  'fill x1,d1 color gray10' into 'fill x1 , d1 color gray10', which GLE
  rejects as an illegal data set identifier. Passthrough now falls back
  to the statement's verbatim source text instead.

- 'bar d1,d2 fill green,blue' groups multiple datasets in one GLE
  command (side-by-side bars); gleplot has no model for a shared group,
  so it silently modeled only the last dataset and dropped the rest
  with no warning. It's now kept verbatim in the axes passthrough with
  a structure: warning, and the 'data' statement that declares its
  now-unmodeled datasets is restored too so the regenerated file still
  defines what the passthrough text references.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@BenHuddart
BenHuddart merged commit a70fb97 into main Aug 6, 2026
4 checks passed
@BenHuddart
BenHuddart deleted the claude/dazzling-sanderson-a47350 branch August 6, 2026 07:16
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