Skip to content

CHANGELOG

v0.53.0 (2026-06-24)

Continuous Integration

  • Fix tilde expansion, add dist-newstyle restore-keys, and update CONTRIBUTING.md (d20828a)

  • Use $HOME instead of ~ in HASKELL_ROUNDTRIP_OUT_DIR env var; GitHub Actions does not expand ~ in env: blocks, causing cache path mismatch - Add restore-keys: ${{ runner.os }}-dist-newstyle- to the dist-newstyle cache step so any change to haskell_roundtrip.bats does not force a full cold Haskell build - Update CONTRIBUTING.md test table: document e2e_haskell_roundtrip.bash, clarify functional.bash excludes the Haskell roundtrip, and update all.bash description to reflect it now includes the Haskell roundtrip

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Parallelize all test jobs and add venv/cabal/dist-newstyle caches (c848f7d)

  • Skip CI for doc-only changes via paths-ignore (0eaab7f)

Adds paths-ignore to the pull_request trigger so pushes that touch only dev-docs/, docs/, top-level markdown, or mkdocs config files do not run the test suite. Replaces the manual [skip ci] convention.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for issue 110 Haskell roundtrip CI performance [skip ci] (fb6ff8f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for issue 110 Haskell roundtrip CI performance [skip ci] (d934504)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Remove [skip ci] convention from CONTRIBUTING.md (040b32b)

CI now skips doc-only PRs automatically via paths-ignore in ci.yml. No manual annotation needed.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update issues and roadmap for 2026-06-24 [skip ci] (92995d9)

Move completed issues 106, 107, 108 to done. Add issues 109 (PlantUML EBNF diagram), 110 (e2e Haskell build performance), 111 (Mermaid extension redesign), 112 (v1.0 release prep). Update roadmap to 0 open issues.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • Add e2e_haskell_roundtrip.bash and exclude roundtrip from e2e suite (321dc68)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • Split haskell.bats into fast emit and slow roundtrip (e7d99ad)

v0.52.0 (2026-06-24)

Bug Fixes

  • diagram: Update bats command test for new plantuml inheritance arrow direction (39138ae)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Update e2e test for new plantuml inheritance arrow direction (5871141)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for Haskell language extension documentation (issue 107) (21c6102)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add Haskell language extension guide (issue 107) (b96aeba)

  • Add Haskell to Languages nav and CLI commands in mkdocs.yml (30c31ea)

  • Add implementation plan for Haskell language extension documentation (94ccc41)

  • Add implementation plan for plantuml inheritance arrow direction (15dc6aa)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add issue 108 and design spec for plantuml inheritance arrow direction (0cae21a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add Java language extension page (a0aaf00)

  • Add JavaScript language extension page (151d885)

  • Add Languages nav and JavaScript command docs to mkdocs.yml (093577f)

  • Add plcc-haskell section to language-extensions guide (2e07122)

  • Add plcc-haskell-emit/build/run CLI command reference pages (261ebcb)

  • Add plcc-javascript section to language-extensions guide (7856f69)

  • Add plcc-javascript-emit and plcc-javascript-run command reference pages (337599e)

  • Add Python language extension page (41129b7)

  • Fix Commands table separator in haskell.md (fdf9231)

  • Fix review findings in language pages (1584621)

  • Reorganize BNF tables to 4-column format with LHS/RHS clarity (aa3e6dd)

Fixes the concrete/abstract distinction: a rule with no alt name on the LHS is a concrete rule; a rule with an alt name (e.g. ) is an alternative rule that makes the base nonterminal abstract. Removes the separate "Token string value" row by folding .lexeme into the captured terminal row. Adds an "Example based on spec" column (generated or semantic code snippet) alongside the renamed "Example from spec" column.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Slim semantic.md to concepts, link to per-language pages (89df13e)

  • plan: Add implementation plan for issue 106 JavaScript language extension docs (fea564d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Add design doc for issue 106 JavaScript language extension docs (70de103)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Fix canonical example syntax and Node.js version in issue 106 design (13ccdba)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • diagram: Point plantuml inheritance arrows up (Parent <|-- Child) (5c2000b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.51.1 (2026-06-24)

Bug Fixes

  • haskell: Skip Token runtime tests when hackage package list is absent (37c6815)

Replace unconditional @pytest.mark.skip with a skipif that checks whether the hackage package list exists. Tests run where cabal has been properly initialized (devcontainer), skip cleanly in CI where cabal update has not run.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • haskell: Unskip Token runtime tests and add missing bytestring dep (1c1f5ea)

The two cabal-based tests were unconditionally skipped despite cabal being available. The build also failed because the cabal template was missing bytestring in build-depends (needed for Data.ByteString.Lazy.Char8).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Chores

  • Update close-worktree.bash to find worktrees under .claude/worktrees/ (90023de)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Close 104 and 105; update roadmap [skip ci] (c18aa23)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.51.0 (2026-06-24)

Documentation

  • Add design spec and update issue 105 for haskell fragment validation (b0e2e3d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for haskell fragment validation (e562c8d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • haskell: Add validate_fragments to detect invalid fragment class names (7e3d09f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • haskell: Wire validate_fragments into emit to enforce fragment class name rules (9e186bf)

v0.50.0 (2026-06-23)

Build System

  • Add ghci and cabal to devcontainer (c7da922)

Chores

  • issues: Close 066 and 103; add 106 and 107; update roadmap [skip ci] (d7b2adf)

Move completed issues 066 (JavaScript emitter) and 103 (run docs fix) to done/. Add issues 106 and 107 for JavaScript and Haskell language extension documentation. Update roadmap to 4 open issues.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • java: Add class fragment support to Java emitter (34be97b)

Pass class_fragments to the template and render them on the class declaration line after the extends clause, matching the original PLCC's /Cls:class/ hook behavior.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.49.0 (2026-06-23)

Bug Fixes

  • haskell: Add OverloadedStrings pragma for aeson 2.x compatibility (ab1f4a5)

aeson 2.x requires Key not String for (.:) and (.=). OverloadedStrings makes string literals polymorphic so they satisfy Key where needed.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • haskell: Dispatch FromJSON on concrete rule_name; remove unused imports (7476563)

  • haskell: Emit DuplicateRecordFields pragma to allow shared field labels (7d7985a)

  • haskell: Remove unused containers dep from generated cabal file (3b9a793)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • haskell: Run cabal update in e2e setup for fresh environments (7a9cd34)

cabal build fails if the Hackage package index has never been fetched. Running cabal update in setup() makes the test self-contained in CI.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • haskell: Use abstract class name ExprRest for evalRest fragment (3c50e47)

In one-module-per-rule, body fragments must be tagged with the abstract class name (ExprRest), not a concrete alternative (AddRest). There is no ExprRest.hs — everything for the rule lives in ExprRest.hs.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Chores

Continuous Integration

  • Cache cabal store in e2e job to speed up Haskell builds (e2b591e)

The first run downloads and compiles aeson's full dependency tree (~38 packages). Caching ~/.cabal/packages and ~/.cabal/store keyed on emit.py (which contains the fixed dep list) makes subsequent runs fast.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • issues: #105 haskell fragment concrete class name silently ignored [skip ci] (1152ba2)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add Haskell emitter implementation plan [skip ci] (66d3f5d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add Haskell emitter design spec [skip ci] (744e090)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • haskell: Add extension skeleton and entry points (c7238c9)

  • haskell: Add GHC and cabal to devcontainer (72a656c)

  • haskell: Add Token.hs runtime with parseField helper (bcff83e)

  • haskell: Emit cabal file and copy Token.hs (79bc432)

  • haskell: Emit data type declarations per rule module (171bff4)

  • haskell: Emit FromJSON instances for rule modules (5751a34)

  • haskell: Emit Main.hs entry point (9daeec2)

  • haskell: Generate default _run for start rule when not provided (5b7cfcd)

  • haskell: Handle top/import/body/file fragments in emitter (99ffa0c)

Testing

  • haskell: Add BATS command and e2e tests (b339511)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • haskell: Add unit tests for build.py and run.py (1d493df)

v0.48.0 (2026-06-22)

Chores

  • issues: Add 103 - fix run double underscore in language guide overview [skip ci] (f4c296d)

  • issues: Move 071, 072, 102 to done; update roadmap to 4 open issues [skip ci] (6f324b8)

  • issues: Move 080 to done; update roadmap to 1 open issue [skip ci] (f2613fd)

  • issues: Move 081, 101 to done; update roadmap to 2 open issues [skip ci] (fc83670)

  • roadmap: Add 103, remove completed 080, update to 2 open issues [skip ci] (57242ee)

Documentation

  • Clarify class fragment in JS spec; add issue 104 for Java gap [skip ci] (4ffd0c8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Fix run → _run in overview examples [skip ci] (44b564c)

Corrects the Python and Java semantic section examples to use the actual entry point name _run (single underscore) instead of run (double).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add JavaScript emitter implementation plan for issue 066 [skip ci] (767a604)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add JavaScript emitter design for issue 066 [skip ci] (d0b0585)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • javascript: Add emit.py and Jinja2 templates (044c57e)

Implements the JavaScript emitter: reads model JSON from stdin, writes .js, _Start.js, main.js, and runtime/ to --output. Skips SIGINT test due to readline/communicate() race in subprocess.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • javascript: Add run.py and register entry points (59dc256)

  • javascript: Add runtime deserialize.js (7853bd1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • javascript: Add runtime registry.js (c5935b7)

Implement Registry class with register() and lookup() methods.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • javascript: Scaffold extension and add runtime base.js (17cb4fa)

v0.47.2 (2026-06-22)

Bug Fixes

  • mkdocs: Add pymdownx.superfences to fix code blocks inside tabs (196d0ed)

Without superfences, fenced code blocks inside content tabs render as literal text with the ``` markers visible instead of as code blocks.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Chores

  • issues: Move 070 and 098 to done (3b360c6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 100 to done [skip ci] (9471bd7)

PR #221 implemented the CLI command classification and reference pages that issue 100 designed.

Documentation

  • acknowledgments: Add acknowledgments page placeholder [skip ci] (6934a6f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • acknowledgments: Fill in contributors, institutions, and dependencies [skip ci] (e2a3d40)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Restructure directories and nav for issue 100 [skip ci] (ab49034)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Write author-facing commands guide page [skip ci] (be44b6a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Write CLI landing page [skip ci] (29aa662)

  • cli: Write core pipeline reference pages [skip ci] (70599df)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Write diagram extension reference pages [skip ci] (bd4ea8b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Write discovery and utility reference pages [skip ci] (d8ec4c6)

  • cli: Write extension guide pages [skip ci] (58a3345)

  • cli: Write lang dispatch reference pages [skip ci] (284d199)

  • cli: Write language extension reference pages [skip ci] (f30d839)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Write plcc-diagram package reference pages [skip ci] (bcf78f0)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Write plcc-make reference page [skip ci] (1e071de)

  • cli: Write plcc-parser-table reference page [skip ci] (4893159)

  • cli: Write plcc-scan, plcc-parse, plcc-rep reference pages [skip ci] (928ff4a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Write under-the-hood guide page [skip ci] (d7a1780)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • examples: Remove explicit plcc-make build step [skip ci] (3c2f6d0)

  • installation: Add installation page with upgrade, pinning, and uninstall [skip ci] (443182c)

  • issues: Add 101 acknowledgments page [skip ci] (1a43ac5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 102 migration guide from PLCC to PLCC-ng [skip ci] (e83118b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add roadmap for 14 open issues [skip ci] (5a73a19)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Integrate 101 and 102 into roadmap [skip ci] (07341b0)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Resolve phase 1 decisions and close already-done issues (156e8ab)

  • 100: record CLI command classification decision and doc structure - #083: close (absorbed by

    #100) - #079: close (keep PlantUML via Kroki; Mermaid easy to add later if needed) - #074: close (plcc-make already removed from quickstart; output already verified) - #076: close (home page has no install redundancy) - #077: close (licensing already on home page) - #073: close (Java JDK already in prerequisites) - #078: close (CC BY-SA 4.0 already stated on home page) - #099: close (repo_url already configured in mkdocs.yml)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Add Java tab to overview grammar example (a785e9a)

  • language-guide: Add Java tab to subtract.plcc example (7645e07)

  • language-guide: Add Java tabs to semantic section examples (f748d59)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • migration: Add migration guide from PLCC to PLCC-ng [skip ci] (63fe25e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • migration: Fix missing first step in JSON parse tree pipeline [skip ci] (52a2d52)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • mkdocs: Enable content tabs feature and pymdownx.tabbed extension (a1d6812)

  • plan: Add implementation plan for issue 081 [skip ci] (8fca8c6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plan: Add implementation plan for issue 101 acknowledgments page [skip ci] (c1a8538)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add implementation plan for installation page and migration guide [skip ci] (2e59e9e)

Covers issues 071, 072, and 102.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • quick-start: Add Java tab to semantic section example (7d374d1)

  • quick-start: Rename getting-started to quick-start [skip ci] (5592e69)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • roadmap: Update to reflect 7 open issues after #100 done [skip ci] (ee6a751)

Phase 1 (CLI reference) is complete. Renumber remaining phases and update the issue count and date.

  • roadmap: Update to reflect current open issues [skip ci] (9c82dfc)

Remove resolved issues, renumber phases, and update issue count to 8. Phase 1 structural decisions are all resolved; roadmap now starts with implementing the #100 CLI classification decision.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Add design doc for issue 081 plcc-make removal from examples [skip ci] (a5aaf58)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Add design doc for issue 101 acknowledgments page [skip ci] (9cbb69a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add CLI restructure design for issue 100 [skip ci] (fc250dc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add design for installation page and PLCC migration guide [skip ci] (cc5bbee)

Covers issues 071 (upgrade instructions), 072 (version pinning), and 102 (migration guide from PLCC to PLCC-ng).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add design spec for issue 080 tabbed code blocks [skip ci] (7c16962)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add implementation plan and update spec for issue 080 tabbed code blocks [skip ci] (ee671e7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • superpowers: Add implementation plan for CLI doc restructure [skip ci] (dafed24)

v0.47.1 (2026-06-19)

Bug Fixes

  • 098: Replace readline with read1 so one ^D submits partial line (1711e01)

On a real TTY in canonical mode, readline() blocks after the first ^D flushes buffered content because it loops calling read() until it sees a newline or an empty read. A second ^D was required to produce the empty read that caused readline() to return. read1(65536) makes exactly one OS read() call and returns immediately with whatever was flushed.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • 098: Design spec for ^D partial-line regression fix [skip ci] (1291836)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 098: Implementation plan for ^D partial-line fix [skip ci] (e911059)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.47.0 (2026-06-19)

Chores

  • 096: Guard setup in commands, integration, e2e with SKIP_SETUP (3774519)

  • 096: Guard setup in units.bash with SKIP_SETUP (0fec840)

  • 096: Hoist setup into functional.bash; pass SKIP_SETUP=1 to leaf scripts (8c09c47)

  • ci: Trigger (0fa49b4)

Documentation

  • 096: Add design spec for hoisting test setup [skip ci] (2b80e11)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 096: Add implementation plan for hoisting test setup [skip ci] (e8663a7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 096: Clarify plan constraint scope; note pre-existing typo [skip ci] (2d4253d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 100 for CLI command classification discussion [skip ci] (d8027be)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 096 and 097 to done [skip ci] (579d19a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add dark mode implementation plan [skip ci] (35eb4d4)

  • specs: Add dark mode design for issue 070 [skip ci] (1b27077)

Features

  • docs: Add dark mode with system-preference detection and toggle (669d763)

v0.46.1 (2026-06-18)

Bug Fixes

  • 097: Use PIPESTATUS to eliminate exit-code race in run_cached (0c15039)

Replaced the temp-file approach to capture exit codes with PIPESTATUS, which is more reliable and eliminates the race condition where the temp file write in a subshell might not be visible to the parent before reading. The fix:

  • Removed mktemp and rm of _exit_tmp temp file - Removed trap on EXIT (no longer needed) - Added set -o pipefail inside run_cached to enable PIPESTATUS[0] access - Changed pattern from '{ "$@" 2>&1; echo "$?" > file }' to '"$@" 2>&1 | tee output || exit_code=PIPESTATUS[0]'

This is safe because callers source this file into scripts with set -euo pipefail active, but the function itself now explicitly sets pipefail to handle both cases correctly.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Continuous Integration

  • 097: Disable test output cache in CI with PLCC_NO_TEST_CACHE (207f5d7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • 097: Add test output cache design spec [skip ci] (af42838)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 097: Add test output cache implementation plan [skip ci] (cfa749a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 097: Update spec — rename env var, add CI update [skip ci] (e078749)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 098 for ^D on non-empty line in plcc-rep [skip ci] (a85aeae)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 099 for link from docs to source repository [skip ci] (3b4de2f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 093 to done [skip ci] (6a537a7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • 097: Wrap composite test scripts with run_cached (7282014)

  • 097: Wrap simple test scripts with run_cached (e864274)

Testing

  • 097: Add _cache.bash with run_cached helper (b3dfea6)

  • 097: Add cache management scripts and document test output cache (16349fa)

  • 097: Add cache/stats.bash summary script (ac5f79d)

  • 097: Fix fallback test; sync docs to final file layout [skip ci] (d498f3e)

  • Shadow git with a failing stub so the fallback path is deterministically exercised and assert no cache files are written - Update spec and plan docs to reference bin/test/cache/stats.bash (moved from bin/test/cache-stats.bash) and correct script count from six to seven

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.46.0 (2026-06-18)

Bug Fixes

  • 093: Add same-line split e2e test and tighten plcc-rep assertion (ab6ca5d)

  • Add test case for same-line split: multiple sentences on one line should produce multiple parse trees - Tighten plcc-rep two-sentence test to assert exact output lines (3 and 4) instead of weak substring match

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Gate hold-marker emission on --hold-markers flag (52e7484)

plcc-trees now only emits hold markers when called with --hold-markers. TreePipeline passes this flag so orchestrators keep incremental behavior. Direct plcc-trees consumers (e.g. standalone test harnesses) see the old byte-identical output without the extra hold record.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Plcc-trees forwards --hold-markers to parser plugin (57c5100)

TreePipeline passes --hold-markers to plcc-trees, but plcc-trees was not accepting or forwarding the flag to plcc-parser-table. Add the flag to plcc-trees and forward it, restoring normal pipeline output.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Scanhandler.feed returns bytes remainder not bool (3f828f0)

SourceRunner._incremental concatenates the returned remainder with the next line as bytes. Returning True caused TypeError on the next input.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

Documentation

  • 093: Design for incremental parsing in interactive mode [skip ci] (27d4dfe)

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Document incremental interactive mode and ^D [skip ci] (96e8922)

Add Interactive mode paragraphs to both plcc-parse and plcc-rep sections describing line-by-line evaluation, the >>> and ... prompts, and the single-press ^D behavior (exit at empty buffer; force-submit at continuation).

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Implementation plan for incremental parsing [skip ci] (82daa00)

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Note docs responsibility for orchestrators.md [skip ci] (b28f9d3)

  • 094: Add design spec for docs follow-up [skip ci] (f0d348a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 094: Add implementation plan [skip ci] (7e18670)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 094: Document plcc-ll1 and fix plcc-trees example [skip ci] (d454699)

  • 094: Fix plcc-trees pipeline example (plcc-tokens needs file, not stdin) [skip ci] (6606ce2)

  • 094: Remove --tool from plcc-rep (095) [skip ci] (814a889)

  • 094: Remove < /dev/null workaround; files-only means no interactive mode [skip ci] (73d3ae6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 094: Update examples for 089+095, verify all output [skip ci] (da9d373)

  • 094: Update semantic.md for 095 section format [skip ci] (10c5f08)

  • issues: Move 094 to done [skip ci] (511c1cf)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 095 to done [skip ci] (94254cc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • 093: Add commit/hold split helper (41019ba)

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: E2e tests for multi-sentence pipe parsing; fix scan SubmitOn import (fdeeaee)

Add bats tests verifying that piping multiple newline-separated sentences to plcc-parse and plcc-rep produces one result per sentence (incremental split_committed with eof=True). Also fix scan.py and scan_test.py which still imported the removed SubmitOn enum from source_runner after task 5 refactored it away.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Emit hold marker and incomplete-fragment start (4708cb9)

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Handlers return remainder bytes (21acf94)

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Incremental SourceRunner with single-press ^D (6cb3fe4)

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Parser reports sentence extensibility (7169672)

The parse() function now returns a third value, extensible, indicating whether the parser stopped at eof where real terminals could have continued the sentence. This enables incremental parsing and completion. Tests added for extensibility detection in nullable tails and arbno.

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

  • 093: Wire orchestrators to incremental runner (4cd24c4)

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

v0.45.1 (2026-06-17)

Bug Fixes

  • cd: Update smoke test from --grammar to --spec (d85e841)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.45.0 (2026-06-17)

Bug Fixes

  • 095: Add language name path-traversal guard; clean stale tool key in fixture (221a77c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 095: Update inline spec in plcc-parse-errors.bats to new format [skip ci] (1a799e9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 095: Update test fixtures and bats tests to new semantic section format (ba0fd1a)

All fixture .plcc files used the old '% tool Language' divider syntax. The new format uses a bare '%' divider with the language name as the first line of the section body. Also removes '--tool=' flags from plcc-rep bats tests and updates output dir assertions from 'build/calculate' to 'build/Python'.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • 089: Add design spec for phases 3 & 4 of grammar-to-spec rename [skip ci] (b3ac48f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Add implementation plan for phases 3 & 4 [skip ci] (e107235)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Fix --no-banner → -b/--banner in CLI docs and plan [skip ci] (c0d3b25)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Update docs grammar-file references to spec-file [skip ci] (271ee10)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 095: Add semantic section redesign implementation plan [skip ci] (f81cc44)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 095: Add semantic section redesign spec [skip ci] (99eeb7f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 096 and 097 for test infrastructure improvements [skip ci] (3b79d97)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 085, 086, and 089 to done [skip ci] (95ff879)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • 095: Enforce single semantic section; Spec.semantics is now SemanticSpec | None (5d8725e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 095: Plcc-make uses language name as output dir, removes validate_tool_name (f1d35fe)

  • 095: Plcc-rep removes --tool flag, reads language from spec semantics (312360f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 095: Simplify Divider and extract language from semantic section body (e79bddf)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 095: Update spec/model schemas and build_model — semantics is nullable object, no tool (91d986f)

Refactoring

  • 089: Rename build/grammar → build/spec, .grammar → .spec (1517e3e)

  • 089: Rename cmd/grammar → cmd/spec and its symbols (21ebbd9)

  • 089: Update consumer test files to use build/spec and cmd/spec (ed242bc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Update make.py to use build/spec and cmd/spec (3064f4b)

  • 089: Update scan, parse, rep, diagram to use build/spec and cmd/spec (b9b9b35)

  • 095: Add error messages and tighten type annotation per code review (8f25c89)

  • UnexpectedTokensOnDividerError: add message explaining bare-% rule - MissingLanguageDeclarationError: add message explaining language-name placement - MultipleSemanticsError: add message stating only one section is allowed - parse_semantic_spec: narrow parameter type from list to list[Divider|Line|Block] - parse_semantic_spec_test: remove unused LanguageDeclaration import

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • 089: Rename stale grammar→spec in make_test.py function names (5f9aa9c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Update bats tests to use .spec instead of .grammar (354e10c)

Replace all references to build/.grammar with build/.spec in the plcc-make bats test file, including test names, assertions, and the seeded file used by the stored-spec-missing test.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.44.0 (2026-06-16)

Documentation

  • 089: Add design spec for phases 1 & 2 of grammar-to-spec rename [skip ci] (a60a8a4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Add grammar CLI refactor design spec [skip ci] (e8c607e)

  • 089: Add grammar CLI refactor implementation plan [skip ci] (b24486e)

  • 089: Add implementation plan for phases 1 & 2 [skip ci] (0604913)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Correct design spec per code review [skip ci] (12e81e8)

  • issues: Move 084 and 088 to done [skip ci] (8978a7d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • 089: Fix stale 'grammar banner' in make --help text (a46c2a0)

  • 089: Rename CLI flag --grammar/-g → --spec/-s (8216e72)

  • 089: Rename default spec file grammar.plcc → spec.plcc (92b5e5a)

  • 089: Update banner test assertions grammar: → spec: (ebe21e7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Update help text in scan, parse, rep, diagram docstrings (4e7c133)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Update make error messages, banner, and default spec filename (2cb1fa1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Update rep error message and remaining stale test assertions (b6fba4c)

Refactoring

  • build: Add DEFAULT_GRAMMAR_FILE and resolve_grammar_path (580a078)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • build: Fix import placement in grammar_test.py (13307d4)

  • cmd: Add shared grammar CLI helpers (d265700)

  • diagram: Use shared grammar CLI helpers (3a7f7cc)

  • make: Use resolve_grammar_path and GRAMMAR_OPTION (4cddb25)

  • parse: Use shared grammar CLI helpers (bc92046)

  • rep: Use shared grammar CLI helpers (f76d598)

  • scan: Use shared grammar CLI helpers (4d30896)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • 089: Update bats and pytest assertions for grammar-to-spec rename (b9823e2)

Replace all --grammar/-g flags with --spec/-s, grammar.plcc with spec.plcc, and "grammar file not found" with "spec file not found" across all bats and pytest test files.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 089: Update packaging smoke test to use spec.plcc (02d07bc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.43.0 (2026-06-16)

Bug Fixes

  • ci: Trigger (2345b45)

  • lexical: Reject keyword-prefix words like tokenize with KeywordExpected (927e8f5)

Chores

  • bin: Add close-worktree.bash utility script (eb05296)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • 088: Add design spec for required token/skip keyword [skip ci] (e85f3fa)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 088: Add implementation plan for required lexical keyword [skip ci] (eb41547)

Features

  • lexical: Add KeywordExpected error class [skip ci] (af6a03d)

  • Create KeywordExpected class following the established pattern of other error classes (NameExpected, PatternExpected, etc.) - Export from init.py and Parser.py for use in parser and tests - Add test_keyword_is_required test (currently failing as parser enforcement is not yet implemented in Task 2)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lexical: Require token or skip keyword in lexical rules [skip ci] (69046aa)

Testing

  • lexical: Fix pattern compile test and rename implicit token test [skip ci] (25938c0)

  • Fix test_pattern_must_compile to test the actual PatternCompilationError instead of relying on the side effect of missing keyword - Rename test_implicit_token_rule to test_keyword_missing_produces_error to accurately reflect what the test validates - Add PatternCompilationError to imports

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lexical: Fix stale comment in cli test [skip ci] (e6ae3da)

  • lexical: Update tests for required token/skip keyword (5431d92)

  • Repurpose test_implicit_token_rule to verify bare syntax now produces KeywordExpected error - Remove test_implicit_token_produces_TokenRule (behavior no longer exists) - Add 'token' keyword to tests whose purpose was testing other behaviors (name validation, pattern errors, duplicates, etc.) - Updates cover all affected tests in parse_lexical_test.py and plcc_spec_cli_test.py

All 984 unit tests pass.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.42.0 (2026-06-15)

Documentation

  • 084: Design spec for opt-in banner via --banner/-b [skip ci] (34be57d)

  • 084: Implementation plan for --banner/-b opt-in [skip ci] (aa3d84f)

Features

  • 084: Add print_banner() writing version+grammar to stderr (2a29435)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 084: Replace --no-banner with --banner/-b in plcc-diagram (97246e3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 084: Replace --no-banner with --banner/-b in plcc-make (64ce31a)

Banner is now opt-in via --banner/-b and prints to stderr instead of defaulting to stdout.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 084: Replace --no-banner with --banner/-b in plcc-parse (ced110b)

  • 084: Replace --no-banner with --banner/-b in plcc-rep (2e696c1)

Banner is now opt-in via -b/--banner (stderr), matching plcc-make/scan/parse.

  • 084: Replace --no-banner with --banner/-b in plcc-scan (3dd7e69)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • 084: Consolidate print_banner import at top of output_test.py (027ea69)

  • 084: Remove dead print_version_line and print_grammar_line (a3f115f)

v0.41.0 (2026-06-15)

Documentation

  • 086: Design spec for Token str and repr [skip ci] (c53f671)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 086: Implementation plan for Token str and repr [skip ci] (964b8d1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • 086: Token.repr returns lexeme (2b4d2e8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 086: Token.str returns lexeme (885d8a7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.40.1 (2026-06-15)

Bug Fixes

  • rep: Flush message and harden SIGINT test (3a23635)

Add flush=True to the KeyboardInterrupt print to match all other protocol writes. Replace stderr==b'' assertion with 'Traceback' not in stderr and add TimeoutExpired cleanup to the SIGINT test.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • rep: Suppress KeyboardInterrupt stack trace in generated main.py (18cd3b5)

On ^C, generated Python interpreters now print 'User interrupted execution by ^C.' and exit 130 instead of crashing with a traceback.

Strip COV_CORE_* env vars from the test subprocess so pytest-cov's .pth injection does not interfere with SIGINT exit-code assertions.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • rep: Suppress KeyboardInterrupt stack trace in generated main.py (d7aecdd)

On ^C, generated Python interpreters now print 'User interrupted execution by ^C.' and exit 130 instead of crashing with a traceback.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Continuous Integration

  • docs: Set mike default version so site root doesn't 404 (49d80f2)

Only set the default to dev if latest doesn't exist yet, so a release-promoted latest isn't overwritten on the next push to main.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Fix typos and remove resolved TODOs [skip ci] (4f1a111)

  • Update examples.md to new semantic section format [skip ci] (6cd2e59)

  • 085: Add design spec for KeyboardInterrupt fix in generated main.py [skip ci] (8eb3ab9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 085: Add implementation plan for KeyboardInterrupt fix [skip ci] (e47ad19)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Consolidate semantic section issues 087/090/091/092 into 095 [skip ci] (0c24145)

Issues 087, 090, 091, and 092 approached the semantic section redesign piecemeal and partially contradicted each other. Replace them with a single authoritative issue describing the final design: bare % divider, language declared as first non-blank line of the semantics body, case-sensitive, no tool naming.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.40.0 (2026-06-15)

Bug Fixes

  • docs: Set fence_prefix and tag_format on kroki plugin [skip ci] (6e60c26)

fence_prefix: '' — use plain ```plantuml blocks (default is kroki-plantuml)

tag_format: svg — embed SVG inline at build time, not img tags pointing to kroki.io

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Chores

  • docs: Add bin/docs/serve.bash to start the MkDocs dev server [skip ci] (a6b497f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • docs: Add project venv to PATH in serve.bash [skip ci] (6256eb3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • docs: Fix serve.bash to find .venv in main repo root [skip ci] (ffc17f3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 084 make no-banner the default [skip ci] (11e8bb3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 085 plcc-rep KeyboardInterrupt on ^C [skip ci] (0814d3e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 086 Token string conversion method [skip ci] (ca19fe2)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 075 and 082 to done [skip ci] (931e632)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add What's New section to home page [skip ci] (39ea3dd)

Closes #075

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Draft getting started page [skip ci] (cf8296e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Draft home page [skip ci] (c0471ed)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Expand test drive section and refine home page copy [skip ci] (9e84eab)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Fix quickstart output with real verified output [skip ci] (36cdaaa)

Closes #074

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Fix typos and broken link on home page [skip ci] (fee522b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Remove --no-banner from quickstart examples [skip ci] (9ba4666)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Revise getting started (rename section, update grammar, clean output) [skip ci] (c761cf1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Revise home page description and simplify licenses section [skip ci] (963dd1f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Rewrite home page with project description and features [skip ci] (8b000df)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update docs to reflect new spec file syntax and terminology [skip ci] (0aaae1c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update home page navigation link descriptions [skip ci] (e0f9270)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update quickstart to sum-integers example with semantics [skip ci] (ec7b1c3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update quickstart with verified command output [skip ci] (7854d76)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Draft CLI overview page [skip ci] (9f97321)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Draft orchestrators page [skip ci] (0353f93)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Draft primitives page [skip ci] (46e9422)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cli: Show Level 2 orchestrators before Level 0 primitives [skip ci] (747b5c6)

Closes #082

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 093 incremental parsing in plcc-rep interactive mode [skip ci] (feafd76)

  • issues: Add documentation issues 070-083 and move 065 to done [skip ci] (c743ac4)

  • issues: Add issue 087 — swap semantic divider to % Language tool [skip ci] (b2e62f4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 088 — require token or skip keyword in lexical rules [skip ci] (a472902)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 089 — rename grammar file to specification file [skip ci] (b1255ab)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 090 — case-sensitive language name in separator [skip ci] (63db460)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 091 — remove multiple semantic sections and tool name [skip ci] (6c66f3c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 092 — move language specifier to first line of semantics section [skip ci] (3f2be08)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Add filename comment to overview example [skip ci] (a0ae70d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Add pipeline diagram to overview [skip ci] (b8d69fe)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Draft code generation page [skip ci] (8d8c0a1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Draft examples page [skip ci] (6c3b7a8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Draft grammar rules page [skip ci] (f136d66)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Draft language guide overview [skip ci] (42e2c01)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Draft token rules page [skip ci] (66d6b18)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Expand lexical rules and scanning algorithm [skip ci] (36ef2fc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Expand semantic section with field access, entry point, and packaging [skip ci] (ae90d63)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Expand syntactic and semantic section docs [skip ci] (c0951c4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Fix samples line numbers to match scanner output [skip ci] (140f295)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Improve repetition rule example with xList/yList values [skip ci] (a95fe0f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Minor wording fixes in syntactic section [skip ci] (6befdfd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Refine lexical section content and examples [skip ci] (916f544)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Rename tokens.md to lexical.md [skip ci] (74a1d5d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Restructure sections as lexical/syntactic/semantic [skip ci] (aafc966)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Simplify hooks example [skip ci] (4de477c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • language-guide: Simplify pipeline diagram, remove duplicate prose [skip ci] (46e5d91)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add initial user docs implementation plan [skip ci] (2a76d36)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add initial user docs mapping plan [skip ci] (812e0db)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add PlantUML docs diagrams design [skip ci] (0589a4d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add PlantUML docs diagrams implementation plan [skip ci] (d7fda69)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • docs: Add mkdocs-kroki-plugin for PlantUML diagram support [skip ci] (336fc97)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.39.2 (2026-06-07)

Bug Fixes

  • docs: Fix empty changelog page (8122c2e)

PSR replaced CHANGELOG.md entirely, removing the marker that docs/changelog.md used as a start anchor. Without the marker include-markdown included nothing. Remove the start filter to include the full file, and suppress MD041 since the linter cannot see past the include directive to the # CHANGELOG heading PSR generates.

Build System

  • release: Add [skip ci] to PSR release commit message (951fc04)

PSR pushes a version bump commit to main using the GitHub App token, which triggers the release workflow again. Since the App token is not subject to GitHub's re-trigger suppression (unlike GITHUB_TOKEN), the second run would be a no-op but wastes CI minutes. Adding [skip ci] prevents the re-trigger. The docs site still updates via the release: published trigger that fires moments later.

v0.39.1 (2026-06-07)

Bug Fixes

  • ci: Fix dev docs deployment to gh-pages subdirectory (502c367)

mkdocs gh-deploy has no --dest-dir option, and it replaces the entire gh-pages branch (wiping mike-managed user docs). Switch to building with mkdocs build then deploying with peaceiris/actions-gh-pages, which supports destination_dir and keep_files to update only dev-docs/ without touching the rest of the branch.

  • docs: Correct changelog insertion flag and add mike plugin [skip ci] (6d24523)

  • docs: Revert version_toml and serialize gh-pages deploys (f6a54a0)

version_toml was incorrectly set to pyproject.toml:project.version — the version is SCM-derived (no project.version field exists). Reverted to [].

deploy-dev-docs now waits on deploy-user-docs so both jobs don't push to gh-pages concurrently, which could cause non-fast-forward push failures.

Build System

  • docs: Add mkdocs, material, mike, include-markdown-plugin [skip ci] (7e574fc)

  • release: Enable CHANGELOG.md auto-generation [skip ci] (644f681)

Continuous Integration

  • docs: Add GitHub Actions workflow for user and developer docs [skip ci] (b35ab03)

  • docs: Add token and concurrency group to docs workflow [skip ci] (48254b5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • release: Use GitHub App token to bypass branch protection on push (6a55af3)

Replaces the RELEASE_TOKEN PAT with a short-lived installation token from the ourPLCC Release Bot GitHub App. The app is installed on plcc-ng with Contents read/write permission and listed as a bypass actor in the main branch ruleset. Tokens expire after 1 hour — nothing long-lived is stored beyond the app's private key.

  • release: Use RELEASE_TOKEN to bypass branch protection on push (508e11a)

GITHUB_TOKEN cannot push to main when branch protection requires PRs. RELEASE_TOKEN is a fine-grained PAT scoped to this repo with contents read/write, owned by an org admin who has bypass rights.

Documentation

  • Add mkdocs config and user docs stub pages [skip ci] (617bf53)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add mkdocs-dev config and developer docs stub pages [skip ci] (aefef67)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 065: Add documentation design spec [skip ci] (1f691fd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 065: Add documentation implementation plan [skip ci] (bd89cfb)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • contributing: Clarify when to use skip-ci tag (c3bf5ca)

  • issues: Move 010 to done — flakiness not observed in a long time [skip ci] (00cef9c)

  • issues: Move 053 to done — need stronger justification before pursuing [skip ci] (e2db8b6)

  • issues: Move completed issues 054 and 069 to done [skip ci] (d51b960)

Both were merged to main via PRs #186 and #187.

  • readme: Slim README and add docs site link [skip ci] (4127ad2)

Refactoring

  • docs: Move docs/superpowers/reviews to dev-docs/reviews [skip ci] (e42bd01)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • docs: Move internal docs to dev-docs/ [skip ci] (f92b054)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.39.0 (2026-06-06)

Bug Fixes

  • 069: Emit complete events for ARBNO iterations in tracer (d7d92f0)

_parse_arbno emitted predict but never complete, leaving dangling frames on _render_trace's stack that corrupted subsequent complete pops for enclosing rules.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 069: Unconditional _render_trace import; add ARBNO render test (6f8e9c6)

Remove try/except ImportError guard — _render_trace is always present now. Drop skipif decorators that depended on it. Add test for balanced ARBNO events rendering correctly.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.38.0 (2026-06-06)

Bug Fixes

  • syntax: Address code review findings (f54259e)

  • _matchLeft raises MalformedBNFError on no-match instead of returning None - Fix stale line string in _TRIVIAL_SPEC to use - Correct _getNames return type to tuple[str, str | None]

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • syntax: Update MalformedBNFError examples for new BNF syntax (c1a571f)

  • Update example strings to show annotations inside angle brackets: - Adjust regex pattern in _compute_column() to match new syntax: <[^>]+> instead of <\S+>(?::\S+)? - All 11 tests pass including test_str_includes_all_five_example_forms

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tests: Update remaining integration bats and scan-verbosity fixture for PascalCase (76621d2)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • 069: Add parse trace design spec [skip ci] (a2dd1f8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 069: Add parse trace implementation plan [skip ci] (ec2e63f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 042 and 057 to done [skip ci] (8c0b2fd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 042 and 057 to done [skip ci] (d16d29c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add implementation plan for 054 reconsider BNF syntax [skip ci] (7bfc7a4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add design for 054 reconsider BNF syntax [skip ci] (6e75c31)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • 069: Add _render_trace for Style B parse trace output (a62f004)

  • 069: Buffer parse-step records and render trace before errors (da620e8)

  • 069: Remove --trace flag and dead trace code (fa4a270)

Removes the --trace/-t flag from plcc-parse since parse-step records are now emitted unconditionally on ParseError. Cleans up the _print_parse_step function and trees_flags logic that are no longer needed.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • fixtures: Update all .plcc fixtures to new BNF syntax (2cf32a7)

Update fixture files and bats tests to use PascalCase nonterminal names and inside-bracket :name annotations (e.g. instead of :num).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • syntax: Add shared is_valid_class_name utility (cf45768)

  • syntax: Move :name annotation inside angle brackets (9f983b6)

  • syntax: Require PascalCase for LHS nonterminal names and altNames (18bb31a)

  • syntax: Require PascalCase for RHS nonterminal names (86af11a)

Use is_valid_class_name to validate RHS nonterminals, and allow single-character altNames by relaxing the altName regex to [a-z][a-zA-Z0-9_]*. Update tests to use PascalCase nonterminals and inside-bracket syntax.

Refactoring

  • model: Drop redundant capitalize transforms now that names are PascalCase (5f6cadc)

  • syntax: Use #nil for synthetic altName and new line syntax in repeating rule expansion (e4f477d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • 069: Add failing feed() trace buffering tests [skip ci] (8e0e2a3)

  • 069: Add failing tests for _render_trace [skip ci] (fddf3e3)

  • 069: Add shift and complete step record helpers (d1f3492)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 069: Replace --trace bats tests with Style B trace tests (5424a1a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • syntax: Update validate_syntactic_spec test for PascalCase names (ab2113f)

v0.37.1 (2026-06-06)

Bug Fixes

Documentation

  • plans: Add implementation plan for 042 diagram stderr forwarding [skip ci] (ec3ed66)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add design for 042 diagram stderr forwarding [skip ci] (ec7d322)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Fix design doc inaccuracies flagged in code review [skip ci] (5017c7d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • diagram: Use VerboseContext parse/reformat for child stderr (71b5554)

Testing

  • diagram: Add failing test for plain-text stderr forwarding (b912776)

  • diagram: Verify empty child stderr produces no output (5c2871d)

Confirm that parse_child_events('') is a no-op and produces no output on stderr when a child process produces no output.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Verify JSONL child events are reformatted as text (d45c63e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.37.0 (2026-06-05)

Documentation

  • issues: Move 067 to done [skip ci] (08b69c4)

  • issues: Move 068 to done [skip ci] (ffa6a10)

  • plans: Add implementation plan for issue 057 java emitter underscore prefix [skip ci] (18288cf)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add design doc for issue 057 java emitter underscore prefix [skip ci] (1b41669)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs,plans: Fix inaccuracies flagged in code review [skip ci] (4582af4)

  • Clarify $run→_run is a breaking change for existing grammars - Narrow "done when" criterion to avoid false-positive on negative assertion - Fix grep command in plan to match entry-point patterns only

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • java-emitter: Rename \$run to _run to match Python convention (c5c02dd)

Testing

  • java-emitter: Update fixture and bats test name for _run rename (5017ac6)

v0.36.0 (2026-06-05)

Bug Fixes

  • lexical: Remove dead PatternCompilationError import from parse_lexical_test (9bc3e27)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • plans: Implementation plan for issue 068 — remove lexical second pattern [skip ci] (fd945c8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Design for issue 068 — remove lexical second pattern [skip ci] (17c0477)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • lexical: Remove close_pattern and make_block_result from LexicalRule protocol (589e07b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lexical: Remove close_pattern from TokenRule and SkipRule (fbd51e4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lexical: Remove optional second pattern from Parser (4f497b9)

Removes the block-scanning feature by: - Deleting _parseOptionalPattern method - Updating _processLine to no longer pass close_pattern to rule constructors - Removing five block-related test functions - Updating test_junk_at_the_end_of_a_line to expect UnexpectedContent instead of PatternDelimiterExpected

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Remove block scanning; delete BlockOpened and UnclosedBlockError (b95b568)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • schema: Remove close_pattern; remove block bats test (1e3f733)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tokens: Remove UnclosedBlockError handling and close_pattern from spec_loader (702f263)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.35.0 (2026-06-05)

Bug Fixes

  • banner: Limit --no-banner pre-docopt check to option portion of argv (5c3be05)

Prevents a file literally named --no-banner passed as a positional SOURCE argument from incorrectly suppressing the version line.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • issues: Add issue 065 design end user documentation [skip ci] (de52263)

  • issues: Add issue 066 extend to another language [skip ci] (ae220d9)

  • issues: Add issue 067 version header prints first [skip ci] (44e29c6)

  • issues: Add issue 068 remove lexical second pattern [skip ci] (5f8e123)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 069 improve plcc-parse --trace output [skip ci] (fa24534)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 055 to done — keeping %%% as block delimiter [skip ci] (dcd329a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 056 to done [skip ci] (0f1f8ac)

  • issues: Move 063 to done [skip ci] (787007b)

  • issues: Move 064 to done [skip ci] (07073e5)

  • issues: Update 054 BNF syntax to Type:name order [skip ci] (d3e2bcb)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add implementation plan for issue 067 version header prints first [skip ci] (c791bf5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add design for issue 067 version header prints first [skip ci] (2837325)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • diagram: Add version banner and --no-banner flag (08903da)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Add version banner and --no-banner flag (59990c3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parse: Print version first, add --no-banner, split banner output (45b056f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • rep: Print version first, add --no-banner, split banner output (20a2f64)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Print version first, add --no-banner, split banner output (af65289)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.34.1 (2026-06-05)

Bug Fixes

  • scan: Block rules now include opening and closing delimiters in lexeme (1e3b378)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • plans: Implementation plan for issue 064 — block rules discard delimiters [skip ci] (9975673)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Design for issue 064 — block rules discard delimiters [skip ci] (ab7dc00)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.34.0 (2026-06-05)

Bug Fixes

  • scan: Remove stale plcc-parse annotation from SubmitOn.EOF comment [skip ci] (b75383d)

EOF mode is now used by plcc-scan, plcc-parse, and plcc-rep.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • issues: Add 063 — plcc-scan must run in multi-line mode for block tokens/skips [skip ci] (15fc1e6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 064 — block rules discard opening/closing delimiters [skip ci] (a7c18d4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add implementation plan for issue 063 — plcc-scan multi-line mode [skip ci] (aa76f79)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Rescue orphaned 062 plan from issue-059-060-design worktree [skip ci] (65032de)

The plan was never committed before the branch was merged via PR #174. The implementation it describes (fix 062) is already in main.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add design for issue 063 — plcc-scan multi-line mode [skip ci] (a9215aa)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • scan: Switch to EOF submit mode for multi-line block token support (ef945c2)

Fixes issue 063. plcc-scan now accumulates interactive input until ^D before submitting to plcc-tokens, matching plcc-parse and plcc-rep. Block tokens/skips that span multiple lines now work end-to-end.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.33.0 (2026-06-05)

Bug Fixes

  • 062: Handle UnclosedBlockError in tokens_cli — emit error record (b99d7c1)

Wires UnclosedBlockError dispatch into the CLI's scanner output loop, emitting properly formatted error records when EOF is reached inside a block token (closing pattern not found).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lexical: Annotate line as Line | None; move block imports to top of scanner_test (2fb1aa6)

  • lines: Normalize CRLF and bare CR line endings to LF in parse_from_strings (64a69f3)

  • lines: Preserve trailing newline in parse_from_string via splitlines(keepends=True) (1d1c82c)

  • scan: Remove manual newline injection from _scanBlock; newlines come from Line.string (65a9128)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Update downstream code for Line.string keepends invariant (dca0ec7)

Fixes FileNotFoundError in parse_includes (newline captured in path), double-newline output in SpecError.str, and stale Line literals in parseRough_test and parse_includes_test that didn't include trailing \n.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • 062: Add design spec for UnclosedBlockError handling in tokens_cli (d893a81)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Spec for issue-061 Line.string newline normalization (1bdbcd8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 061 double-newline in block scanner, 062 UnclosedBlockError crash in tokens-cli (025cb4d)

  • issues: Move 059, 060, 061, 062 to done (99ef19d)

  • plan: Implementation plan for block lexical rule (issue 060) (21b7728)

  • plan: Implementation plan for issue-061 Line.string newline normalization [skip ci] (b825e19)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Design for block lexical rule (issue 060) (195ff75)

  • spec: Fix circular import note and index arithmetic in block rule design [skip ci] (61a04c9)

Features

  • 062: Add format_unclosed_block_error_record to jsonl_formatter (573ffe3)

Implement formatter function to handle UnclosedBlockError records, which occur when EOF is reached inside a block token with no closing delimiter. This allows the plcc-tokens CLI to properly emit error records instead of crashing.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lexical: Parse optional second pattern for block token/skip rules (737a615)

Extend Parser._processLine to extract _parsePattern and add _parseOptionalPattern, enabling block rules like token BODY '<<<' '>>>'. Update test for junk-after-pattern to reflect new PatternDelimiterExpected behavior (junk is now treated as a malformed second pattern).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Add BlockOpened sentinel and UnclosedBlockError (35dff98)

Adds BlockOpened (returned by Matcher when a rule's close_pattern is set and the opening pattern matches) and UnclosedBlockError (yielded by Scanner at EOF while in block mode) as pure data-carrier dataclasses, with instantiation tests and exports from scan/init.py.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Scanner block mode for token/skip rules with close_pattern (9c9bd8a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Export TokenRule and SkipRule from spec package (b896901)

  • tokens: Spec_loader emits TokenRule/SkipRule; schema adds close_pattern (394926a)

Update spec_loader to directly import TokenRule and SkipRule, and pass the optional close_pattern parameter when instantiating rules from spec JSON. Add close_pattern as an optional property in the spec schema.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • lexical: Replace LexicalRule dataclass with TokenRule/SkipRule + Protocol (c8659a0)

Splits the single LexicalRule dataclass into concrete TokenRule and SkipRule types, introducing a LexicalRule Protocol for type annotations. Updates all callsites (Parser, spec_loader, test helpers) to use the concrete types.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Inline rule.make_match; remove _makeSkipOrToken wrapper (c479010)

The _makeSkipOrToken method was a one-line wrapper that added no value. Inlined the call to rule.make_match() at the call site and deleted the method.

Also strengthened the skip block test to assert result.rule and result.column, matching the assertions in the token block test for consistency.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Matcher delegates result construction to rule.make_match (6657459)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • lexical: Add unit tests for TokenRule/SkipRule; type match param (3eb2648)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Update scanner tests for Line.string keepends invariant (c004a12)

Now that Line.string includes the trailing \n, adjust slice indices (0:11, 11:), token counts (8, 7), expected block-content lexeme, and filter-vs-count assertions to match the new per-line string shape.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Verify token NEWLINE rule matches line endings via Line.string invariant (d34dd46)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.32.0 (2026-06-04)

Bug Fixes

Documentation

  • issues: Add 060 block lexical rule type [skip ci] (6883e88)

  • issues: Close 058, add 059 plcc-generated-spec-parser [skip ci] (2273089)

Issue 058 (collocate lexical patterns) is superseded by the larger architectural goal of parsing PLCC grammar files with a PLCC-generated parser. Issue 059 captures that goal with its prerequisites and decomposition.

  • issues: Move issue 049 to done [skip ci] (7b7a97f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Clarify max() tiebreaking; mark grammar audit done [skip ci] (bc019e6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Correct fixture audit claim to include \s* skip [skip ci] (6d55fdb)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Design spec for first-longest-match scanner algorithm [skip ci] (e7823ca)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Implementation plan for first-longest-match scanner [skip ci] (458d3ee)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • scan: Replace skip-priority algorithm with first-longest-match (a4d85b3)

The previous algorithm gave skips categorical priority: if any skip matched, the first-declared skip won immediately. This new algorithm treats all rules equally, with the longest match winning and declaration order breaking ties.

Changes: - Remove skip-priority short-circuit from match() - Delete _removeSkips() helper (no longer needed) - Pass all matches to _getLongestMatch() instead of filtering skips

This allows skips and tokens to compete fairly, enabling longer tokens to win even when skips are declared first. Tests updated in Task 1 now pass.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.31.0 (2026-06-02)

Bug Fixes

  • cmd: Guard against None from read_grammar in banner calls (1a1d6d9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • design: Add spec for issue 049 level-2 startup info (cfe563d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add alternatives to issue 055 block delimiters [skip ci] (aea92fb)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add analysis and decision to issue 054 bnf syntax [skip ci] (c75f754)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add analysis and flex/lex observation to issue 056 scanner algorithm [skip ci] (4c16ae2)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add before/after example to issue 054 [skip ci] (321a933)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 053 render ll1.json in human-readable format [skip ci] (d4bbbf7)

  • issues: Add issue 054 reconsider BNF section syntax [skip ci] (74511ec)

  • issues: Add issue 055 consider alternative block delimiters [skip ci] (c32e950)

  • issues: Add issue 056 reconsider scanner algorithm [skip ci] (ee6c201)

  • issues: Add issue 057 java emitter underscore prefix [skip ci] (40e37c6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 058 collocate lexical patterns [skip ci] (1e947d6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Fix before example to use lowercase non-terminals in 054 [skip ci] (13baf0f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move issue 031 to done [skip ci] (2a4a97a)

  • issues: Update issue 053 to consider diagrams via PlantUML [skip ci] (4353ed8)

  • plan: Add implementation plan for issue 049 level-2 startup info [skip ci] (02df955)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • cmd: Add print_startup_banner to output.py (92c0c0f)

  • parse: Print startup banner after make (450232f)

  • rep: Print startup banner after make (b25c56d)

  • scan: Print startup banner after make (265fa87)

Refactoring

  • cmd: Remove or '' fallback from read_grammar calls (85e3f19)

plcc-make always writes build/.grammar before returning 0, so the fallback is never reached in practice. Keeping it would silently produce os.path.abspath('') == as the grammar path, which is more misleading than the TypeError that surfaces the invariant violation.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • bats: Update output checks to account for startup banner (87b8ac5)

Commands now print a startup banner to stdout before results. Tests that matched the full output string exactly now check the last output line instead.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • e2e: Update plcc-rep output checks for startup banner (25481dd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.30.0 (2026-06-01)

Bug Fixes

  • fixtures: Remove entry_point token from arith.plcc (6a4acf1)

  • fixtures: Remove entry_point token from trivial-python and trivial-arbno (938d999)

  • rough: Use regex match span for extra-token column in error (3736ef9)

  • schemas: Remove entry_point from spec and model JSON schemas (35260f8)

Documentation

  • issues: Move 052 to done after merge [skip ci] (95dc157)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plan: Implementation plan for removing entry_point from grammar syntax [skip ci] (26a8b09)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Design doc for removing entry_point from grammar syntax (issue 031) [skip ci] (f17d8af)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • rough: Raise error for extra token on divider line; remove entry_point parsing (3282b8e)

Refactoring

  • java-emit: Use _DEFAULT_ENTRY_POINT directly; remove entry_point tests (5c75824)

  • model: Remove entry_point from semantic section model dict (185bcbd)

  • python-emit: Use _DEFAULT_ENTRY_POINT directly; remove entry_point tests (c90cc51)

  • spec: Remove entry_point from Divider and SemanticSpec (f40c2d9)

Testing

  • integration: Remove obsolete null entry_point bats test (2250d75)

v0.29.4 (2026-06-01)

Bug Fixes

  • fixtures: Update test grammars to use colon RHS alt name syntax (5f010f3)

Fixes command test failures introduced when issue 052 made the no-colon form a syntax error. All four fixtures used name; updated to :name.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • issues: Move completed issue 050 to done [skip ci] (a848966)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move completed issue 051 to done [skip ci] (4925551)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plan: Add implementation plan for issue 051 remove %%{ / %%} syntax [skip ci] (8f80449)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plan: Fix inaccurate expected failure for test_pprc_is_a_plain_line [skip ci] (bd3a2b3)

%%} alone is not a block opener so test_pprc_is_a_plain_line already passes before the implementation change. Clarify that only test_pplc_is_a_plain_line is the red step.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Add design doc for issue 051 remove %%{ / %%} syntax [skip ci] (5259ec8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Add design doc for issue 052 colon-required RHS alt name (e58b157)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • rough: Remove %%{ / %%} block delimiter syntax (issue 051) (75a2ba8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • syntax: Require colon in RHS <...>:name syntax (issue 052) (901f619)

hello now raises MalformedBNFError; only :hello is accepted, consistent with the LHS parser. Removes the silent strip(":") workaround.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • 052: Convert no-colon RHS named terminal test to error case (e6234b0)

Replace test_named_rhs_non_terminal with test_named_rhs_non_terminal_without_colon_is_an_error to assert that hello (without colon) is invalid BNF syntax.

The test currently fails because the implementation incorrectly accepts this syntax. Fix for this error case will come in the next task.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.29.3 (2026-05-31)

Bug Fixes

  • Update release workflow smoke test to use --grammar (issue 050) (22203a7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for issue 050 rename --grammar-file to --grammar (7dbaa8d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for issue 050 [skip ci] (c8333f8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move completed issues to done [skip ci] (331df48)

Move 047 and 048 to done/ — both merged to main.

Refactoring

  • Fix stale test name and add -g short-form smoke test (9f2fab3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Rename --grammar-file to --grammar / -g in all commands (issue 050) (67802fb)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.29.2 (2026-05-30)

Bug Fixes

  • ll1: Add count to LL1Error and pass it from check_parsing_table_for_ll1 (e64ba3d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • ll1: Use list in parsing table and _predictSet to detect identical predict set conflicts (d172ef0)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for issue 048 - LL(1) identical predict set conflict detection (315d690)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for issue 048 [skip ci] (434a3cf)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Revise 048 design to fix FIRST/FOLLOW overlap and epsilon leaking via _predictSet (3f86df0)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Revise 048 design to use list instead of parallel count dict (79ce129)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • ll1: Align check_parsing_table_for_ll1_test to list semantics and add count assertions (59cb297)

v0.29.1 (2026-05-30)

Bug Fixes

  • make: Write build/.grammar before build stages so sticky grammar survives syntax errors (82318b5)

Chores

  • Add bin/issues/new.bash and .next-id.txt to prevent duplicate issue numbers (ef60483)

Completed issues move to done/, so scanning the directory for the next number risks collisions. Store the next ID in .next-id.txt and always allocate through bin/issues/new.bash.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • design: Spec for fix-047 sticky grammar on syntax error (bec70c4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 047 - sticky grammar not persisted on syntax error [skip ci] (153b6ee)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 048 - LL(1) conflict detection misses identical predict sets [skip ci] (fc6f8d5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 049 - level-2 commands should print startup info [skip ci] (ed3ebba)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 050 - rename --grammar-file to --grammar [skip ci] (2342a6a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 051 - remove %%{ / %%} semantic block bracket syntax [skip ci] (6a583d9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 052 - require colon in <...>:name syntax; reject <...>name [skip ci] (1410e50)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move completed issues to done [skip ci] (f677199)

030 (parse trace), 038 (rep stale build), 039 (level-2 errors to stdout), 043 (ll1 message whitespace), 046 (sticky grammar) all landed via merged PRs.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plan: Implementation plan for fix-047 sticky grammar on syntax error [skip ci] (b4cc922)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • make: Add failing test - build/.grammar written before build stages run (23e1dca)

  • make: Cli test - build/.grammar written even on plcc-spec failure (015c51d)

v0.29.0 (2026-05-29)

Bug Fixes

  • Address five code review issues in sticky grammar implementation (b3638b8)

  • build/grammar.py: return None for empty/whitespace .grammar content - grammar_test.py: remove unused Path and pytest imports; add empty test - make.py: use is_dir() instead of exists() to avoid NotADirectoryError when build/ is a file or symlink - make.py: validate grammar file existence before wiping build/ on grammar switch, preventing build destruction on a misspelled path - make.py: write build/.grammar on the fast path (build is current) so sticky grammar works even when no rebuild is needed

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • test: Update parse and rep bats tests for sticky grammar error path (a381b6f)

Removing [default: grammar.plcc] means no-grammar errors now come from plcc-make (which says "grammar file not found") rather than from the command itself (which said "Run 'plcc-X --help'"). Update the tests to match the new behavior, consistent with the scan fix.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add implementation plan for sticky grammar (issue 046) (f1b16db)

  • Add issue 046 and design spec for sticky grammar (fc919b4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • Add plcc.build.grammar module for sticky grammar tracking (3e4c305)

  • diagram: Delegate grammar resolution to plcc-make (838e2c7)

  • make: Add grammar resolution rules and stored-grammar error path (3d93995)

When no --grammar-file flag is given, resolve the grammar from build/.grammar (stored by a previous run), falling back to grammar.plcc. When the stored grammar path is missing, emit a helpful error pointing to --grammar-file.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Wipe build/ when grammar file changes (dc1d069)

When --grammar-file is given explicitly and differs from the stored grammar, wipe build/ entirely before rebuilding. This prevents stale build artifacts from the previous grammar from confusing the user.

Two new tests verify: - test_explicit_grammar_differs_from_stored_wipes_build: build/ is wiped - test_explicit_grammar_same_as_stored_does_not_wipe: build/ is preserved when grammar hasn't changed

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Write build/.grammar after successful build; add bats tests (2117ed3)

  • parse: Delegate grammar resolution to plcc-make (40058e2)

  • rep: Delegate grammar resolution to plcc-make (da6b793)

  • scan: Delegate grammar resolution to plcc-make (b06a149)

  • Remove default grammar.plcc check from scan - Only pass --grammar-file to plcc-make if user explicitly provided it - Let plcc-make own grammar resolution logic - Update test to expect error from plcc-make, not plcc-scan

v0.28.1 (2026-05-29)

Bug Fixes

  • parse: Handle list-valued arbno children in _print_tree (2369545)

v0.28.0 (2026-05-29)

Documentation

  • design: Add 030 parse trace spec [skip ci] (7139693)

  • plan: Add 030 parse trace implementation plan [skip ci] (edcb1bd)

  • schema: Add parse-step.schema.json for parse-step JSONL records (8b33c7e)

Features

  • parse: Add --trace flag and parse-step rendering (798a00f)

Adds -t/--trace option to plcc-parse that passes --trace through to plcc-trees and renders parse-step records as indented plain text output.

  • parser: Add --trace flag to plcc-parser-table (2a17d13)

Adds -t/--trace option that emits parse-step JSONL records (predict, shift, complete) before each tree on success, and always on ParseError.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add Tracer class to predictive_parser (399ba07)

  • parser: Instrument parse() with optional Tracer (4d9ca64)

Adds tracer=None parameter to parse(); calls tracer.predict/push/shift/pop/complete at the appropriate points in _parse_regular and _parse_arbno. Adds 13 new tests covering predict, shift, complete events, depth tracking, error partial traces, and arbno iteration counts.

  • trees: Forward --trace flag to parser plugin (0e00298)

Testing

  • bats: Add --trace tests for plcc-parser-table and plcc-parse (31cf1ac)

Wire TreePipeline.trees_flags so --trace reaches plcc-trees without leaking into verbose child flags; add bats tests for predict/shift/complete output, -t shorthand, trace-before-tree ordering, and auto-trace on failure.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.27.0 (2026-05-28)

Bug Fixes

  • parse: Route parse/scan errors to stdout via print_user_error (c6e2dc8)

Updates print_parse_error() to use print_user_error() instead of printing directly to stderr, routing parse/scan errors from both plcc-parse and plcc-rep commands to stdout as intended.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • rep: Route interpreter/semantic errors to stdout via print_user_error (baab2af)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • design: Add 039 level-2 errors to stdout design [skip ci] (d94c13f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Fix 039 spec - note test rename for stderr→stdout [skip ci] (ddfaacf)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 039 - level-2 errors should go to stdout (742e959)

  • plan: Add 039 level-2 errors to stdout implementation plan [skip ci] (da50d53)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • cmd: Add print_user_error helper to encode stdout intent (56c2f76)

User-facing language errors (scan errors, parse errors, semantic/interpreter errors) should go to stdout. This helper makes that distinction explicit at every call site, replacing direct calls to print(..., file=sys.stderr).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • scan: Use print_user_error for scan errors (intent, no behaviour change) (2db75c5)

Testing

  • Fix parse_test.py and plcc-parse-errors.bats for stdout errors (1ef3dd0)

parse_test.py (ParseHandler) and tests/bats/integration/plcc-parse-errors.bats were asserting parse/scan errors on stderr. Update to assert on stdout to match the behaviour change from print_parse_error() using print_user_error().

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.26.2 (2026-05-27)

Bug Fixes

  • verbose: Preserve indentation and blank lines in plain-text stderr passthrough (ad158d1)

parse_child_events stripped leading whitespace and dropped blank lines before forwarding non-JSON stderr lines. This broke LL(1) conflict message formatting when plcc-parse or plcc-rep captured plcc-make's stderr and re-emitted it.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.26.1 (2026-05-27)

Bug Fixes

  • make: Blank line before each LL(1) conflict block (d368f88)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Drop 'see ll1.json' from LL(1) error header (07e8627)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • issues: Add 043 - improve LL(1) conflict message whitespace (ebb4a20)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Close issue 036 (LL(1) conflict error messages) [skip ci] (5c54e82)

Completed in PR #149.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Update 043 - drop 'see build/ll1.json' from error line (609e970)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Implementation plan for issue 043 - LL(1) message formatting [skip ci] (2df1fba)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Design for issue 043 - LL(1) conflict message formatting [skip ci] (9c83aef)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.26.0 (2026-05-27)

Bug Fixes

  • ll1: Handle underscore terminals and empty LCP in conflict formatter (6aca6ca)

  • TERMINAL_RE: add underscore prefix support ([A-Z][A-Z0-9_]*) to correctly render terminals like _SKIP as non-bracketed symbols - _first_first_lines: guard against empty LCP (arises when FIRST/FIRST conflict occurs via nullable leading symbols); show a restructuring tip instead of a malformed left-factoring example - design spec: correct JSON examples to use bare nonterminal names (e.g. "elsePart") matching actual ll1.json output, not ""

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for LL(1) conflict error messages (issue 036) [skip ci] (84efea1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for LL(1) conflict messages (issue 036) [skip ci] (a6ac385)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Close issues 043, 044, 045 [skip ci] (cbf2d7d)

  • 043 (parseSpec drops rough-parse errors): fixed in PR #144 - 044 (syntax error caret wrong column): fixed in PR #144 - 045 (altname lost in ll1 pipeline): fixed in PR #147

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • Field-aware symbol rendering in conflict messages (b81ef72)

Capturing symbols in FIRST/FIRST left-factoring suggestions now render as valid PLCC grammar syntax students can copy-paste:

  • Non-capturing (field=None): terminal → TOKEN, nonterminal → - Capturing, default alt (field == sym.lower()): → - Capturing, explicit alt (field != sym.lower()): → field

Updated _render_symbol signature to accept field parameter. Updated _render_production and _first_first_lines to pass s["field"]. Added _render_symbol to test imports; added 9 new field-aware tests.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • ll1: Add _longest_common_prefix helper for left-factoring suggestion (71d9136)

  • ll1: Add conflict_type field to ll1.json conflict entries (c20afe6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • ll1: Add format_conflict_message module with production rendering (4c3024e)

Implements the message formatter skeleton with production rendering logic: - format_conflict_message() creates LL(1) conflict messages - _render_production() formats individual productions with proper nonterminal/terminal symbols - Stubs for conflict-type-specific message lines (first_follow, first_first)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • ll1: Implement FIRST/FIRST message body with left-factoring suggestion (b1fcfb4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • ll1: Implement FIRST/FOLLOW conflict message body (40d80a9)

  • make: Use format_conflict_message for human-readable LL(1) conflict output (415585d)

Refactoring

  • ll1: Remove unused pytest import; document LCP invariant (3d12c0d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.25.0 (2026-05-27)

Bug Fixes

  • Concrete alt-name subclasses use own name as rule_name (987cb37)

  • Strengthen conflict-production schema; correct design doc for _handle_arbno (11ac0dc)

  • Update ll1.schema.json parse_table cell shape to {alt, production} (3588a25)

Documentation

  • Add design spec for issue 045 (altname lost in ll1 pipeline) (5be969f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for issue 045 (altname ll1 pipeline) (ca39138)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add issue 045 (altname lost in ll1 pipeline) [skip ci] (5120bd1)

  • Close issue 039 (prefix semantics) [skip ci] (b160481)

  • Restore _arbno_grammar_and_rules docstring in ll1_result_builder_test (911a0c8)

  • Restore docstrings and WHY-comment in spec_json_decoder (9c4e43a)

Features

  • Add Rule dataclass to spec_json_decoder (c65b99d)

  • Decode() reads altName into Rule.alt; productions replaces field_map (15c4106)

  • Updated decode() to build productions dict mapping (nt, rhs_tuple) to Rule objects - Rule objects now capture both alt name from LHS and fields list - Updated tests to assert Rule objects instead of field lists - All 20 decoder tests pass

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Ll1_result_builder emits new cell shape {alt, production} (2c0a45f)

Update ll1_result_builder to consume Rule objects from productions dict and emit parse table cells with {alt, production} structure instead of bare lists. This preserves alternative names from the spec through the LL(1) pipeline.

  • Rename parameter field_map → productions throughout - Update _prod_entry to return {alt, production} dict cell structure - Update tests to use Rule dataclass and assert new cell format - Update ll1_cli to use new parameter name

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Predictive_parser uses cell alt name for tree node rule (069f017)

Testing

  • Update table_cli fixtures to new cell shape {alt, production} (8c5ba3b)

v0.24.0 (2026-05-26)

Bug Fixes

Documentation

  • Add design spec for plcc-version command (034) [skip ci] (0ed61c1)

  • Add implementation plan for plcc-version (034) [skip ci] (ab5757b)

  • Close issue 034 (plcc-version) [skip ci] (024b62d)

Features

  • version: Add get_version and main to plcc.version (effbee3)

  • version: Register plcc-version entry point (68d37e7)

Testing

  • version: Add bats CLI contract tests for plcc-version (25f7533)

  • version: Remove unused sys import (db115da)

v0.23.0 (2026-05-26)

Bug Fixes

  • Drop rough-parse errors in parseSpec (043) and fix caret alignment in plcc-spec errors (044) #144 (40f6641)

parseSpec now surfaces rough-phase errors (circular includes, unclosed blocks) alongside lexical and syntactic errors plcc-spec error output now routes through verbose.emit_error, producing a properly aligned caret and examples hint in both text and JSON verbose modes VerboseContext.emit_error and reformat_child_events now render source_line and hint fields when present

  • Route plcc-spec errors through verbose.emit_error with source line and caret (closes 044) (10160dd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Stop dropping rough-parse errors in parseSpec (closes 043) (9fafa0e)

Documentation

  • Add design spec for issues 043 and 044 (ca0332f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for issues 043 and 044 (79d3141)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add issue 044 (syntax error caret points to wrong column) (20e121f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • Add kind and hint properties to MalformedBNFError (0f20a74)

  • Add kind and hint properties to SpecError (fa9b89c)

  • Render source_line and hint in emit_error and reformat_child_events text mode (83179ac)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • Add bats test for plcc-spec caret alignment in error output (8cfa461)

v0.22.0 (2026-05-26)

Bug Fixes

  • Surface MalformedBNFError as human-readable message in plcc-spec output (c88be47)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for issue 037 spec parser syntax error messages (8e8d0b4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for issue 037 spec parser syntax error messages (85b75f1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add issue 043 (parseSpec drops rough errors); close issue 037 (fa6a008)

  • Move issue 040 to done (b3019e9)

Fixed in PR #141 (fix/semantics-comments-empty-files).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • Give MalformedBNFError a readable str with column and examples (5a12c58)

  • Syntacticparser collects MalformedBNFError instead of raising (e00faf2)

parse_syntactic_spec now returns (SyntacticSpec, list[MalformedBNFError]) so callers can handle parse errors gracefully while parsing continues.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • Return self._errors in early-return branch for consistency (d7e9b9a)

  • Use _ for unused errors in valid-input syntactic spec tests (a80aedf)

v0.21.4 (2026-05-25)

Bug Fixes

  • Treat # comment lines in semantics section as empty (01523f8)

Closes issue 040.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for issue 040 (semantics comments create empty files) (bea4086)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for issue 040 (0cd6a3a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • Remove # comment guard from java emitter (dead code after 040 fix) (e96e540)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • Cover indented # comment lines in parse_code_fragments (bc508e8)

Pins the lstrip() behavior so future refactors cannot silently drop it.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.21.3 (2026-05-25)

Bug Fixes

  • diagram: Handle missing file viewer gracefully (a97ac97)

When xdg-open (Linux) or another viewer is not installed, the run commands crashed with a Python traceback. Wrap _open_file in main() with try/except and print a clean error message, matching the error-handling pattern established in build.py.

Affects both plcc-plantuml-diagram-run and plcc-mermaid-diagram-run.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Mermaid run prints path instead of opening viewer (c20ddec)

  • diagram: Orchestrate emit, build, run directly; drop --through=diagram from make (adff700)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Plantuml run prints path instead of opening viewer (96cd124)

  • make: Remove diagram operations; rename --through=diagram to --through=model (7030d45)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Cross-link superseded diagram specs; track stderr-forwarding concern (23cdeae)

  • plan: Diagram decouple from make implementation plan (cca578a)

  • spec: Decouple diagram operations from plcc-make (2688128)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • diagram: Hoist _SOURCE_EXT to module scope (1cb43db)

Testing

  • diagram: Assert --format propagated to emit, build, run (1c12867)

v0.21.2 (2026-05-25)

Bug Fixes

  • diagram: Add User-Agent header to plantuml.com requests (70d1c3b)

Cloudflare Bot Fight Mode on plantuml.com returns 403 (error 1010) when requests carry no User-Agent. Python's urllib sends none by default. Set User-Agent: plcc-ng/1.0 on every request.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.21.1 (2026-05-25)

Bug Fixes

  • diagram: Replace plantuml PyPI dep with stdlib implementation (bc75d35)

plantuml 0.3.0 imports six which is not declared as a dependency, causing import plantuml to fail with ModuleNotFoundError in any fresh install. Replace with a stdlib-only implementation (zlib, base64, urllib.request) that encodes PlantUML source and calls plantuml.com directly, removing the need for any optional dependency.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Strip base64 padding from plantuml URL encoding (ea7eb01)

= padding chars are not part of the PlantUML alphabet and pass through the alphabet translation unchanged, producing invalid plantuml.com URLs. Strip them before translating.

Strengthen encode tests with a known-good fixture, a no-padding assertion, and an alphabet-only assertion.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • issues: Add issue 041 — diagram-build should not run during make-all (4956b87)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.21.0 (2026-05-25)

Bug Fixes

  • diagram: Address Copilot review: package name, file ext, duplicate test (d9e1043)

  • Use plcc-ng[diagram] (not plcc[diagram]) in error message and docs - Choose diagram source file extension based on format (.puml for plantuml, .mmd for mermaid) - Remove test_configures_timeout_on_server (duplicate of test_calls_plantuml_server_and_writes_png) - Update spec doc URL from http:// to https://

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Use HTTPS and add 30s timeout for plantuml.com requests (f0a673a)

  • diagram: Widen error handler and strengthen build tests (348e0a9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Build System

  • diagram: Register plantuml build/run entry points and plantuml optional dep (cac7b40)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Capture ideas for improved LL(1) conflict error messages [skip ci] (afa6cc4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Capture ideas for spec parser syntax error messages [skip ci] (351b8fc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Implementation plan for plantuml pip default [skip ci] (98296a6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Spec for plantuml pip install as default diagram backend (80884a9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issues 038, 039, 040 from stakeholder reports [skip ci] (239989c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move resolved issues 033 and 035 to done [skip ci] (f189a1c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • diagram: Add plcc-plantuml-diagram-build plugin using plantuml PyPI (1aeb6a3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Add plcc-plantuml-diagram-run plugin (d73402b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Change default diagram format from mermaid to plantuml (abb0025)

v0.20.1 (2026-05-25)

Bug Fixes

  • diagram: Remove unused call import from build_test (6a5ee13)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Replace Python mmdc wrapper with npm mmdc CLI subprocess (4d2cbaf)

The Python mmdc package required PhantomJS (EOL) and wasn't reliably available on PyPI. Switch plcc-mermaid-diagram-build to shell out to the mmdc npm CLI (@mermaid-js/mermaid-cli) instead. Error message now points to the correct install command.

Also removes mmdc from pyproject.toml optional-dependencies and dev deps.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.20.0 (2026-05-24)

Bug Fixes

  • diagram: Apply Copilot suggestions and fix test isolation (6fc5baf)

  • Add best-effort diagram steps to --through=all (warn and skip if PhantomJS/mmdc unavailable; 'diagram' stage added to sentinel only on success so caching works without optional deps) - Fix _required['all'] docstring: diagram not required for caching - Fix list.py docstrings to reference plcc-*-diagram-emit pattern - Replace Windows subprocess start with os.startfile in mermaid/run.py

  • Add Windows os.startfile test to mermaid/run_test.py - Catch RuntimeError in mermaid/build.py to suppress Python traceback - Use --separate-stderr in plcc-rep bats tests so diagram warnings on stderr don't contaminate $output assertions - Add mmdc>=0.4.1 to dev dependencies

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Close file handle in mermaid-diagram-build (cedd859)

  • diagram: Decouple diagram build from --through=all and fix test names (fe217f9)

  • Remove 'diagram' from _REQUIRED['all'] and change execution guard from through in ('diagram', 'all') to through == 'diagram' so that plcc-make --through=all (and plcc-rep) do not require mmdc (optional dep) - Rename plcc-plantuml-diagram.bats → plcc-plantuml-diagram-emit.bats and update command references to the new plcc-plantuml-diagram-emit name - Update e2e happy-path tests to use plcc-plantuml-diagram-emit instead of the retired plcc-diagram --output=DIR interface

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Fix plantuml emit interface, forward stderr, and update docstring (0d8ac75)

  • Make --output=DIR optional in plcc-plantuml-diagram-emit; writes to stdout when omitted - Fix VerboseContext name from 'plcc-plantuml-diagram' to 'plcc-plantuml-diagram-emit' - Forward captured stderr from child processes in diagram.py so errors reach the user - Update --diagram-format docstring in make.py to remove misleading --through=all reference - Update emit_test.py: replace no-args-exits-nonzero test with stdout-write test

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Init model_json to None and simplify write_sentinel call (771ca58)

  • packaging: Update packaging test for diagram redesign entry points (d030401)

Build System

  • Update entry points for diagram redesign (215321b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Code Style

  • diagram: Remove redundant default in emit.py (c5e04f4)

Documentation

  • issues: Add design spec for issue 035 plcc-diagram redesign [skip ci] (0ca4723)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add implementation plan for issue 035 diagram redesign [skip ci] (26ee4f6)

Features

  • diagram: Add plcc-diagram Level 2 command (043e42f)

Implements the user-facing plcc-diagram command that validates the grammar file, calls plcc-make --through=diagram, then calls plcc-diagram-run to display the resulting image.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Add plcc-diagram-build dispatcher (5c7b6f8)

  • diagram: Add plcc-diagram-emit dispatcher (replaces plcc-diagram) (f4a97c6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Add plcc-diagram-run dispatcher (355c892)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Add plcc-mermaid-diagram-build plugin (d07ed59)

  • diagram: Add plcc-mermaid-diagram-emit plugin (60e7912)

  • diagram: Add plcc-mermaid-diagram-run plugin (4707895)

  • diagram: Update plcc-diagram-list to discover plcc-*-diagram-emit plugins (ba8cd70)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Add --through=diagram, --diagram-format, and set-based staleness (f9be706)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • build: Replace linear staleness levels with set-based sentinel (2b59816)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • diagram: Update and add bats command tests for diagram redesign (f6af6c0)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.19.3 (2026-05-24)

Bug Fixes

  • java-emit: Match language case-insensitively in section lookup (ab7c7f7)

  • model: Normalize language field to lowercase in build_model (8bb86ad)

  • python-emit: Match language case-insensitively in section lookup (88c02b3)

Documentation

  • Add implementation plan for language case normalization (ec8c91c)

  • Add issue 035 and design spec for language case normalization (d71a7e6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update design spec to reflect lowercase normalization and emitter changes (e77cac4)

  • issues: Add issue 035 for plcc-diagram --output=build hang [skip ci] (cabe5d8)

v0.19.2 (2026-05-24)

Bug Fixes

  • parse: Stop at first error in ParseHandler.feed() (d00f226)

Multiple error records (e.g. from several lex errors) are now truncated to the first — students see one clear error to fix.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Pass all lex errors through plcc-parser-table (f55f58d)

Previously only the last lex error record was retained and emitted; earlier errors were silently overwritten. Now all lex error records are emitted immediately as they arrive.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • rep: Stop at first error in RepHandler.feed() (8866456)

Mirrors the ParseHandler change: multiple error records are truncated to the first so the interactive prompt shows one clear error to fix.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add first-error-wins design spec for plcc-parse and plcc-rep (031f7fb)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add first-error-wins implementation plan [skip ci] (56de598)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • parser: Rename flag and skip token accumulation after error (bce70f5)

  • Rename has_lex_error → has_error_record (the flag tracks any error record, not specifically lex errors) - Skip appending to tokens[] once an error record has been seen, avoiding unnecessary memory use on large inputs - Fix verification command in spec doc (bin/test-unit → bin/test/units.bash)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • parser: Update bats test for multi-error lex passthrough (3d64eee)

plcc-parser-table now emits all lex error records (not just the last), so the command-level test must parse JSONL and assert all records are errors.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.19.1 (2026-05-23)

Bug Fixes

  • source-runner: Increase read1 buffer to 65536 to avoid MAX_CANON truncation (69a9fee)

Linux's canonical-mode limit (MAX_CANON) is 4096 bytes. read1(4096) can return a full line split at exactly that boundary — no trailing \n — which _is_partial_eof() misidentifies as a ^D press and force-submits with eof=True. read1(65536) fits any canonical line in one call, so only a genuine ^D (where the terminal flushes content without \n) triggers the partial-EOF path.

Also updates _read1_tty to honor the n argument so tests can exercise the boundary, and adds a regression test that would fail with read1(4096) and passes with read1(65536).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • source-runner: Use read1() in EOF mode so one ^D submits typed content (3dcc43a)

In Unix canonical mode, ^D flushes typed bytes to the OS read buffer without a newline. readline() sees a partial read and blocks, waiting for \n or a zero-length read (second ^D). read1() makes at most one OS read call and returns immediately with whatever is available, so the first ^D submits as expected.

Also removes two incorrect tests added during earlier mis-diagnosis and adds a correct failing test (using a read1-based mock) that the fix makes pass.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.19.0 (2026-05-23)

Documentation

  • plan: Add 033 rep-submit-on-eof implementation plan [skip ci] (9707f48)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Add 033 rep-submit-on-eof design (d11176a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • rep: Switch to SubmitOn.EOF — ^D submits, Enter accumulates (5509d43)

Refactoring

  • rep: Tidy test imports — move SubmitOn import to module level (596b6a6)

v0.18.0 (2026-05-23)

Bug Fixes

Documentation

  • issues: Add 033 rep EOF mode, 034 plcc-version; move 032 to done [skip ci] (e6caeaa)

  • rep: Add ^D handling design spec [skip ci] (f5b48db)

  • rep: Fix spec — plcc-rep uses EOL mode, not EOF; align test strategy note [skip ci] (62fba0a)

  • source-runner: Add ^D handling implementation plan [skip ci] (35471be)

Features

  • source-runner: Add pending_exit field to _InteractiveState (11021c1)

  • source-runner: Eof mode accumulates on Enter, only ^D submits (43abec0)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • source-runner: Warn on first ^D on empty prompt, exit on second (2e1d977)

Refactoring

  • source-runner: Remove dead code and duplicate test (895db63)

Testing

  • source-runner: Rename eof mode test to reflect new accumulate behavior (a6a02f9)

v0.17.1 (2026-05-23)

Bug Fixes

  • scan: Discard zero-length matches in Matcher to prevent scanner hang (650e624)

Closes #032

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • issues: Document scanner hang on zero-length skip match (#032, 9a73f5c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Add design spec for fix 032 scanner zero-length skip hang [skip ci] (7fcb295)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Add implementation plan for fix 032 scanner zero-length skip hang [skip ci] (4347e21)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • scan: Add regression fixture and bats test for issue 032 zero-length skip hang (1da7c3d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Add scanner integration test for zero-length skip pattern (dd5523b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.17.0 (2026-05-23)

Bug Fixes

  • test: Add whitespace skip to remaining fixture grammars (9c90165)

trivial-python.plcc, lexical-only.plcc, and trivial-full.plcc also lacked skip WS, causing trailing newlines from echo to produce LexErrors after the scanner newline preservation change.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • test: Add whitespace skip to trivial.plcc fixture (fe67caf)

After preserving newlines in scanner input, grammars without a whitespace skip now produce LexErrors for trailing newlines. The trivial fixture needs skip WS to match realistic grammar behavior and keep integration/command tests passing.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • scan: Add design spec for scanner newline support [skip ci] (f6ef3a7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Add implementation plan for scanner newline support [skip ci] (cc0f986)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • scan: Preserve newlines in scanner input, matching original PLCC behavior (1e0e094)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.16.0 (2026-05-22)

Bug Fixes

Documentation

  • 015: Add design spec for _Start default generated code (7f10b28)

[skip ci]

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • 015: Add implementation plan for _Start default generated code (050405b)

[skip ci]

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 031 — custom entry point with no default implementation (2910bfb)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move issue 015 to done [skip ci] (fdfa4f5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • java-emit: Generate _Start.java and wire start class to extend it (42a09e1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • python-emit: Generate _Start.py and wire start class to extend it (8d77b3b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • integration: Verify no-semantics grammar emits and runs for Java (fe7c076)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • integration: Verify no-semantics grammar emits and runs for Python (204eaab)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.15.3 (2026-05-22)

Bug Fixes

  • parser: Stop error cascade in plcc-parser-table (0f4e3cd)

Remove conditional break/cursor-advance logic from the except ParseError block so any parse error immediately breaks the loop instead of continuing to parse subsequent tokens.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • design: Spec for stopping error cascade in plcc-parser-table (3e9b72f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plan: Implementation plan for stop-error-cascade [skip ci] (ea128e6)

  • spec: Narrow requirement and fix plan accuracy per review feedback (858fa7d)

  • Requirement 1: scoped to ParseError path; note epsilon-advance is separate - Design: 'No other files change' -> 'No other runtime code paths change' - Plan architecture: 'three new tests' -> 'one renamed + two new'; same wording fix

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • parser: Add red test for non-eof error stopping the loop (d269fb3)

Rename test_skip_and_retry_emits_error_then_tree to test_non_eof_error_stops_loop and rewrite it to assert the new behaviour: a non-eof parse error breaks the loop immediately, emitting exactly one error record and zero trees.

This is the TDD red phase — the test fails until the cascade is removed.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add red test for three-bad-token cascade scenario (e487cdb)

Adds test_three_invalid_tokens_emit_one_error to cover the 3 2 1 spec scenario: grammar program → NUM PLUS NUM given [NUM, NUM, NUM, eof] should emit exactly one error, not three cascaded errors.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add red test — error after success stops further parsing (66a0417)

Covers the batch-file scenario: after one successful tree parse, a bad token should produce exactly one error and stop — not cascade to recover a second tree.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.15.2 (2026-05-21)

Bug Fixes

  • ci: Trigger (a3665c9)

  • cmd: Capture child stderr in TreePipeline and reformat verbose events (a77c0d4)

Add verbose parameter to TreePipeline, capture stderr from both child processes (plcc-tokens and plcc-trees), and reformat any verbose JSON events through VerboseContext when verbose is set.

  • cmd: Only pipe child stderr when VerboseContext is set (c8a4152)

  • cmd: Thread VerboseContext through ParseHandler to TreePipeline (2c46ba7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cmd: Thread VerboseContext through RepHandler to TreePipeline (9c07bd6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • design: Spec for fixing verbose child events uncaptured in plcc-parse and plcc-rep (9666756)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move completed issues 017, 023, 029 to done [skip ci] (909e904)

All three were resolved in PR #120 (docs/issues-029-023-017).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move issue 011 to done [skip ci] (96e55ad)

  • plan: Implementation plan for issue 011 verbose child events [skip ci] (62f7255)

Testing

  • cmd: Extend _proc() helper with stderr support (0c108a7)

  • cmd: Pin eof-probe suppression and no-verbose default in TreePipeline (25c137e)

v0.15.1 (2026-05-20)

Bug Fixes

  • lang: Exit 130 cleanly on ^C in plcc-lang-run, plcc-java-run, plcc-python-run (3b57b16)

Chores

  • test: Remove unused Path import in java run_test.py (cbdd1d7)

v0.15.0 (2026-05-20)

Bug Fixes

  • bats: Use escaped single quotes to avoid bash string termination in e2e test (dd44191)

  • parse: Always include stage in error output, even when location is known (66dbf48)

  • rep: Exit 130 cleanly on ^C instead of printing unexpected-exit error (#029, 4994316)

When a user presses ^C in plcc-rep, the interpreter is killed by SIGINT (returncode -2 on Unix) or exits with code 130. Instead of printing "interpreter exited unexpectedly" and exiting with code 1, now exits silently with code 130 to properly propagate the signal exit code.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tokens: Include character and position in unrecognized-character error (#017, 650bfe6)

  • tokens: Update remaining pos consumers to use source (#017, 94e240f)

Documentation

  • design: Add design spec for issues 017, 023, and 029 (e19309b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add --trace/-t flag to plcc-parse (#030) [skip ci] (28497bf)

  • issues: Plcc-rep ^C shows error instead of exiting silently (#029) [skip ci] (0345577)

  • plan: Add implementation plan for issues 017, 023, and 029 (9598126)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • parse: Annotate empty productions with '(empty)' in tree output (#023, bc11c5f)

When plcc-parse prints a parse tree, productions with no children (empty productions) are now annotated with '(empty)' to make them visually distinct in the output.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.14.4 (2026-05-19)

Bug Fixes

  • rep: Align with plcc-parse — EOF errors, submit mode, child_flags, location format (24c62b6)

  • Add EOF-error detection (only_eof_errors gate): incomplete expressions now show '...' continuation instead of an immediate error message - Switch SubmitOn.EOL → SubmitOn.EOF, matching plcc-parse's proven pattern - Forward child_flags to plcc-tokens and plcc-trees subprocesses - Adopt _location_str and stage-name fallback for error formatting - Rebuild rep.py from parse.py baseline so alignment is structural, not patched

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • rep: Use SubmitOn.EOL for REPL-style multi-line evaluation (a087d72)

SubmitOn.EOF only trials the first line; subsequent lines accumulate without re-evaluation until ^D. SubmitOn.EOL calls _accumulate_and_evaluate on every line, which is the correct REPL behavior: the user types 1+ (sees ...), then 2 and gets a result automatically.

The EOF-error detection added to TreePipeline makes EOL mode safe: incomplete input (EOF errors with eof=False) suppresses the error and shows ... instead of an immediate parse error.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • specs: Rep-pipeline alignment and TreePipeline extraction design [skip ci] (b83aa74)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • cmd: Apply code-review fixes — rename location_str, extract test helpers (c451e76)

  • Rename _location_str → location_str (was exported but underscore-named) - Rename raw_lines → raws in TreePipeline.run() to match bytes framing in docstring - Add comment on stderr=None in Popen calls to clarify intent - Extract _proc, _tree_record, _error_record, _error_record_with_source, _eof_error_record into _test_helpers.py; remove duplicates from three test files

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cmd: Extract TreePipeline shared pipeline logic from parse and rep (2cbd8c7)

Move the plcc-tokens | plcc-trees subprocess pipeline, record collection, and EOF-error gate into a single TreePipeline class in pipeline.py. Move _location_str and print_parse_error alongside it.

ParseHandler.feed() and RepHandler.feed() now delegate to TreePipeline.run(), which returns None (need more input) or a list of (record, raw_bytes) pairs. Each handler only contains what is genuinely specific to it: tree rendering for parse, interpreter dispatch for rep.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.14.3 (2026-05-19)

Bug Fixes

  • rep: Handle non-dict JSON values from interpreter (e08eed9)

Bare JSON numbers (and other non-dict values) caused a TypeError because 'in' requires an iterable. Guard with isinstance(record, dict) before checking for the 'kind' key.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.14.2 (2026-05-19)

Bug Fixes

  • ci: Trigger (7d65f73)

  • java-emit: Inject body fragments into abstract baseclass files (573faf6)

Documentation

  • design: Add spec for issue 028 baseclass body injection [skip ci] (366cb19)

  • issues: Add 028 - plcc-rep baseclass semantics block injection [skip ci] (7725fdf)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 028 to done [skip ci] (c6a18c8)

  • plan: Add implementation plan for issue 028 baseclass body injection [skip ci] (b004900)

Testing

  • java-emit: Add failing tests for fragment injection into abstract classes (2b5eb29)

v0.14.1 (2026-05-18)

Bug Fixes

  • ci: Trigger (9bdfa63)

  • parse: Pass eof=True for non-interactive reads in SourceRunner (a878616)

Non-interactive stdin and file reads have reached actual EOF. Without eof=True, ParseHandler.feed's only_eof_errors guard silently discards eof parse errors instead of printing them, causing plcc-parse to exit nonzero with no diagnostic.

Also update issue 026 notes to describe the actual fix (removal, not guarding).

  • parser: Break on found=eof to prevent cascade errors (fixes #027) (638039f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Remove verbose.emit_error for parse result errors (fixes #026) (f37734f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for issues 026 and 027 (fbf7457)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for issues 026 and 027 (624548d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 026 - parse error JSONL suppressed without verbose [skip ci] (e8cb9f6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 027 - incomplete input errors instead of continuation prompt [skip ci] (ed4dfc9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Move 026 and 027 to done [skip ci] (45412bf)

v0.14.0 (2026-05-18)

Bug Fixes

  • ci: Trigger (1b79d81)

  • ll1: Rename EOF sentinel from '$' to 'eof' in parse table and follow sets (8ac86cd)

Update ll1_result_builder.py to emit 'eof' instead of '$' as the parse table and follow-set key for the EOF terminal, matching the renamed scanner sentinel. Update unit tests and bats test accordingly.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parse,scan: Feed() gains eof flag; ParseHandler returns False for eof-only errors on trial [skip ci] (b9adf33)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add found field to parse error records in table_cli [skip ci] (45dd071)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add found field to ParseError; remove \$ special cases [skip ci] (5c030f0)

  • parser: Update docstring sentinel reference from '$' to 'eof' [skip ci] (793a7bf)

  • parser,scan: Update sentinel guard and filter from '$' to 'eof' (10f59c1)

Updates the loop guard in table_cli.py and the sentinel filter in scan.py to recognize the new 'eof' token name instead of the old '$' sentinel.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • rep: Add eof=False to RepHandler.feed to match ScanHandler and ParseHandler (369623f)

  • source-runner: Whitespace-only lines are not blank; _accumulate_only always accumulates (016) [skip ci] (23bacca)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tests: Update e2e bats sentinel filter from '$' to 'eof' [skip ci] (b2fd4d0)

  • tokens: Update tokens_cli_test sentinel filter from '$' to 'eof' [skip ci] (8d00116)

Documentation

  • contributing: Note [skip ci] for documentation-only commits [skip ci] (0cf6226)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add 025 - interactive first-line attempt before continuation [skip ci] (cfb56c3)

  • issues: Move 008, 012, 019, 022 to done after PR #112 [skip ci] (d2588e8)

  • issues: Move 016, 024, 025 to done after implementation [skip ci] (9282f1c)

  • plans: Add implementation plan for issues 016, 024, 025 [skip ci] (4ea29bd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • spec: Design for issues 016, 024, 025 - interactive session improvements (f9307d1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • source-runner: Trial first line before entering continuation mode (025) [skip ci] (899ce2d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tokens: Emit 'eof' sentinel instead of '$' [skip ci] (fd4fb15)

v0.13.0 (2026-05-16)

Bug Fixes

  • cmd: Pass submit_on to SourceRunner in scan, parse, rep (35f59ba)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parse: Show stage name in error when no source location (c3ab33f)

  • parse: Update stale plcc-tree comment to plcc-trees (0590c0f)

  • parser-table: Guard against zero-consumed infinite loop on epsilon productions (f5a6531)

  • parser-table,tests: Handle empty input epsilon parse; skip $ sentinel in bats loops (9e61961)

  • scan: Skip $ sentinel from plcc-tokens in human-readable output (a08ad4b)

  • tokens: Update bats tests for $ sentinel in JSONL output (8d6f12d)

  • tokens,parser-table: Sentinel gets file:line:col for empty input; zero-consumed emits error record (eba82ff)

  • tree: Complete plcc-tree → plcc-trees rename in rep, verbose_test, e2e tests (133e7fb)

Update remaining references to 'plcc-tree' command name that were missed in the rename to 'plcc-trees', including: - subprocess call in rep.py - stage names in verbose_test.py fixtures - invocations in e2e test files

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tree,rep: Complete plcc-trees rename in packaging test; update rep for JSONL stream (77cfec5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • contributing: Update plcc-tree example to plcc-trees (adf6a4f)

  • design: Plcc-trees error handling and streaming design (7f81947)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issue 024 — parser-table silent on premature EOF (ade8f3c)

  • plan: Implementation plan for plcc-trees error handling (ba0f586)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • parse: Uniform record iteration, file:line:col error format (8f5b6e5)

Rewrote ParseHandler.feed() to iterate all JSONL records from the plcc-tree pipeline output, handling both tree and error records. Updated _location_str to emit file:line:col (or -:line:col for stdin). Added tests for the new error rendering and mixed tree+error output.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser-table: Skip-and-retry loop, JSONL stream output, exit 0 always (a537d2d)

Replace single-parse-or-die with a skip-and-retry loop: on ParseError emit an error record and advance one token; on success emit the tree. Stop at the '$' sentinel. Always exit 0. Update tests to reflect new behavior.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • source-runner: Add SubmitOn enum, required submit_on param, EOF accumulation mode (d1d7995)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tokens: Emit $ sentinel token at EOF (a36babc)

Adds a {"kind": "token", "name": "$", "lexeme": "", "source": ...} record as the final JSONL line so downstream tools can detect end-of-tokens without relying on Python EOF detection.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tree: Rename plcc-tree → plcc-trees (7b76450)

Refactoring

  • parser: Parseerror carries source, parse() returns (tree, consumed), remove IncompleteInputError (352ec57)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tokens: Extract last_source from domain object, avoid JSON round-trip (f7f378c)

Replace json.loads(format_record(...)) round-trips with direct attribute access on Token/Skip objects (obj.line.file, obj.line.number, obj.column), and eliminate the double format_record call in the Skip branch.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.12.3 (2026-05-15)

Bug Fixes

  • source-runner: ^d after partial text force-submits buffer (020) (0d756fd)

  • source-runner: ^d exit prints newline before returning to shell (018) (486bd9a)

  • source-runner: ^d in continuation submits buffer instead of exiting (020a) (6b136fe)

When user presses ^D in continuation mode (buffer has content), the loop now resets state and continues instead of breaking. This allows further input to be processed after the buffered content is submitted.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • source-runner: Exit with error when force-submit is rejected by handler (021) (daac3da)

  • source-runner: Wrap prompt print in KeyboardInterrupt try block (7a19511)

Code Style

  • source-runner: Remove docstring and redundant comment (892628e)

Documentation

  • design: Spec for interactive ^D and blank-line fixes (018, 020, 021) (2caf17d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design,plan: Fix line-type count (four→five) and remove 'pure' from _process_line (f350539)

  • design,plan: Update 021 description to reflect eof=True error-and-exit fix (7c2da27)

  • issues: Add issues 016-023 from interactive plcc-parse testing (63b6c06)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Close 018, 020, 021 — interactive ^D and blank-line fixes (d07dcd5)

  • plan: Implementation plan for interactive ^D and blank-line fixes (018, 020, 021) (f5c0bdd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • source-runner: Restore run() return contract docstring (82be1c8)

Refactoring

  • source-runner: Add _InteractiveState and predicate methods (f4aa1bc)

  • source-runner: Extract _process_line and handler methods; make 021 force-submit explicit (bb70ccc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.12.2 (2026-05-14)

Bug Fixes

  • source-runner: ^c exits or clears buffer; blank line submits continuation (d7345ad)

Documentation

  • design: Add interactive shell UX spec for issues 013 and 014 (8a02bb2)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Blank line appends EOF to buffer before feeding (ca9e347)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Blank-line feed resets unconditionally — EOF always produces output (68bd5ff)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Replace evaluating flag with split try/except and _evaluate helper (9e1d2c9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issues 013, 014, 015 for interactive shell and default codegen (75d4d09)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Close 013 and 014 interactive shell ^C and blank-line fixes (06c08c5)

  • plan: Add implementation plan for issues 013 and 014 (b816373)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • source-runner: Add failing tests for issues 013 and 014 (1a3b43c)

v0.12.1 (2026-05-14)

Bug Fixes

  • parse-syntactic-spec: Align token name regex with lexical grammar (dda3cc3)

Regex was [A-Z][A-Z_] — excluded digits and leading underscores. Lexical parser uses [A-Z_][A-Z0-9_], so names like NUM1 were misclassified as non-terminals. Fix aligns the syntactic regex with the authoritative lexical name grammar and adds a regression test.

  • parse-syntactic-spec: Single-char token names now classified as terminals (b7a4315)

Documentation

  • issues: Close 009 model generator token type wrong (1e42742)

  • plans: Add implementation plan for fix 009 token type wrong (be7abd6)

  • specs: Add design for fix 009 token type wrong (5cae813)

Testing

  • Add regression tests for single-char capturing terminals (86e988f)

Add two new tests to verify that single-character token names like and :b are properly recognized as CapturingTerminal instead of falling back to RhsNonTerminal. These tests currently fail due to bug in parse_syntactic_spec.py line 92, where the regex requires 2+ chars.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.12.0 (2026-05-13)

Bug Fixes

  • parse: Exit non-zero and include stage name when error record received (1de38a0)

  • review: Apply copilot review items 1-4 (2baceb8)

  • runner.run() return value now checked in parse.py and rep.py main(); non-interactive incomplete input exits nonzero - table_cli.py: remove spurious verbose.emit_error on IncompleteInputError - table_cli.py: add "stage":"plcc-parser-table" to parse error record - table_cli_test.py: remove duplicate incomplete-input test - source_runner_test.py: add four return-value tests

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Remove redundant proc.wait() after communicate() (73d5b0b)

  • source-runner: Return completed boolean from run() (7eda6dd)

Non-interactive feeds that signal incomplete input (handler returns False) now cause run() to return False; interactive mode always returns True.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for shared SourceRunner (scan/parse/rep IO unification) (082887a)

  • Add implementation plan for SourceRunner (03c9121)

  • Clarify RepHandler interpreter-state guarantee in source-runner spec (24b20b0)

  • issues: Add issue 010 for intermittent bats flakiness in full commands suite (78e31cf)

  • issues: Track missing source position in parser-table error record (012) (bc25fd3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Track verbose child event capture bug in plcc-parse/plcc-rep (011) (abd18de)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • cmd: Add SourceRunner with source routing and interactive loop (8e319e4)

SourceRunner orchestrates reading content from files or stdin, routing it to a handler for processing. Interactive stdin mode supports multi-line input with continuation prompts and Ctrl+C handling.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parse: Add ParseHandler; route IO through SourceRunner (9f63b45)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add IncompleteInputError for EOF-mid-parse detection (afad167)

IncompleteInputError is a ParseError subclass that distinguishes "ran out of tokens mid-parse" from "wrong token present". It's raised when lookahead is $ (end-of-stream sentinel) in parsing contexts where a production was expected.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser-table: Emit error record to stdout on parse error; silent on incomplete (4cfdc32)

Implement Task 3 from the source-runner plan: - Real parse errors (wrong token): emit {"kind": "error", "message": "..."} to stdout AND to stderr (via verbose); exit 1 - Incomplete input (IncompleteInputError): emit nothing to stdout; exit 1

This distinguishes between parse failure (caller should see the error) and incomplete input (caller can detect "need more input" by checking for empty stdout).

Updates test_nothing_written_to_stdout_on_error to use incomplete input and adds two new tests: - test_parse_error_emits_error_record_to_stdout: verifies real errors emit - test_incomplete_input_produces_no_stdout: verifies incomplete input is silent

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • rep: Add RepHandler; route IO through SourceRunner (4258147)

  • scan: Add ScanHandler; route IO through SourceRunner (f8763b5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tokens: Add --source-name flag to override stdin label (45c20da)

v0.11.0 (2026-05-12)

Bug Fixes

  • scan: Close proc.stdout after read loop; update test mock and docs (aa492a1)

  • Add proc.stdout.close() before proc.wait() to release the file descriptor promptly when scanning multiple sources - Update scan_test.py mock to use io.BytesIO (supports close()) instead of iter([]) - Correct spec: the TTY-hint-absent bats test also requires --separate-stderr - Correct plan Task 1 snippet to show the full updated test block with --separate-stderr and $stderr check

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for plcc-scan TTY hint (issue 005) (6ca4d19)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for plcc-scan TTY hint (issue 005) (a9c05a5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Mark 005-007 as done (0de5fb5)

Features

  • scan: Print TTY hint each time interactive stdin read begins (56ef53a)

Testing

  • scan: Add failing unit tests for TTY hint (41554be)

  • scan: Check stderr (not combined output) for TTY hint absence (64f04cc)

  • scan: Update bats hint checks to match new message casing (d355619)

v0.10.0 (2026-05-12)

Bug Fixes

  • scan: Improve --trace output format (17e054e)

  • Add Candidates: heading before match attempts - Mark winning candidate with -> instead of * - Exclude zero-match candidates from Candidates list - Use location: disposition: details format for token and skip lines - Remove regex from token/skip lines (still present in Candidates) - Add blank line after each match block

  • scan: Remove --show-skips, --show-line, --show-regex, --show-attempts flags (9828cc8)

BREAKING CHANGE: the four --show-* flags are removed. Use --trace, which already implied all four, to enable detailed output.

Documentation

  • Add design spec for plcc-scan trace cleanup (issues 006, 007) (8924cb5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for plcc-scan trace cleanup (0b3d9c4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Fix stale _render_record signature in spec and plan (d963496)

show_regex was removed from the signature during implementation. Update both documents to reflect the final three-parameter API and correct the file-map note about new files.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Add issues 005-009 from review session, retire 002-004 (cb2533d)

  • 005: plcc-scan missing ^D hint for interactive sessions - 006: plcc-scan --trace output format improvements - 007: remove --show-* flags from plcc-scan - 008: plcc-parse multi-program input, streaming output, error recovery - 009: model generator emits token name as field type instead of Token - move resolved issues 002, 003, 004 to docs/issues/done/

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.9.1 (2026-05-11)

Bug Fixes

  • Release smoke test uses --grammar-file flag explicitly (f60221b)

  • Update release smoke test to use --grammar-file interface (6ee4c75)

v0.9.0 (2026-05-11)

Bug Fixes

  • Atomic temp file in build/, validate --through value in plcc-make (4164663)

  • Remove shutil.rmtree from slow path; build/ is managed incrementally (a86fa5a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update packaging smoke test to use --grammar-file interface (f5e9ab5)

Documentation

  • Add unified-build design spec (99b0367)

Captures the design for making build/ the single source of truth across all Level 2 commands, with hash-based staleness detection, --through=scan|parse|all for incremental builds, and defaulting the grammar file to ./grammar.plcc.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add unified-build implementation plan (de53f05)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • Add staleness algorithm, --grammar-file, --through to plcc-make (e12c97f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add staleness module for build sentinel management (2090313)

  • Plcc-parse uses build/ via plcc-make, drops positional GRAMMAR arg (932b525)

Replace positional GRAMMAR argument with --grammar-file= option (default: grammar.plcc). Delegate build steps to plcc-make --through=parse and read spec.json/ll1.json from build/ instead of temp files.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Plcc-rep uses build/ via plcc-make, drops positional GRAMMAR arg (a875996)

Remove the silent-ignore bug where the positional GRAMMAR arg was accepted but never used. Now uses --grammar-file= (default: grammar.plcc) and calls plcc-make as its first step to guarantee artifact presence.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Plcc-scan uses build/ via plcc-make, drops positional GRAMMAR arg (1d6ad01)

Replace plcc-spec temp-file block with plcc-make --through=scan call; add --grammar-file= option (default: grammar.plcc); use build/spec.json instead of a temp file; add rebuild/no-rebuild and lexical-only tests.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • Add type hint and document unknown-level behavior in staleness (98f0dda)

  • Clean up make.py — remove unused verbose param, redundant sentinel delete (c62e44f)

  • Remove unused verbose parameter from _report_ll1_failure function signature and all call sites - Remove redundant delete_sentinel(build_dir) in LL(1) failure branch (already called in slow path)

  • Drop or 'grammar.plcc' and or 'all' fallbacks since docopt provides defaults

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • Add lexical-only fixture for partial-grammar tests (ae7a6db)

  • Rewrite plcc-make bats for staleness, --through, --grammar-file (7e319c0)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update e2e and integration tests for new --grammar-file interface (2d5d054)

  • fix e2e/happy-path.bats: replace positional grammar arg with --grammar-file= in plcc-make calls; update "cleans build/ on rebuild" test to use a modified grammar copy to trigger staleness - fix e2e/plcc-rep.bats: replace positional grammar arg with --grammar-file= in all plcc-rep calls; replace "exits non-zero without build/" test (now invalid since plcc-make auto-builds) with "exits non-zero when grammar file does not exist" - fix integration/plcc-parse-errors.bats: replace positional grammar arg with --grammar-file= in plcc-parse call - feat(make): clean build/ directory on rebuild (shutil.rmtree) so stale artifacts from previous builds are removed when grammar hash changes

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.8.1 (2026-05-11)

Bug Fixes

  • Remove dead TokenOrSkipProperties definition; isolate plcc-scan verbose lines in regression tests (991da44)

TokenOrSkipProperties was defined but never referenced in the schema.

The -vv/-vvv regression tests now grep for ^plcc-scan: before counting lines, isolating scan-emitted events from child-process stderr so the tests remain correct if plcc-spec or plcc-tokens add output at higher verbosity levels in future.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Remove trailing comma from definitions in token.schema.json (091c654)

Trailing comma after AttemptEntry's closing brace caused JSONDecodeError in check-jsonschema (Python 3.14's strict JSON parser).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.8.0 (2026-05-11)

Bug Fixes

  • scan: Add flush=True to contextual prints; guard unlink with existence check (81489d0)

Documentation

  • Add design spec for scan verbosity redesign and output richness flags (d073875)

Splits --verbose (stderr diagnostics) from new --show-skips/--show-attempts flags (stdout richness). Per-token detail travels in the JSONL stream; plcc-scan stops capturing/reformatting child stderr.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for scan verbosity redesign (a059224)

  • Correct Split the knob table — enrichment controlled by --show-*, not -v (659bbe0)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Fix -v counting flag syntax in scan verbosity design spec (125c4f5)

Replace -v=N notation with docopt-ng counting style: -v (level 1), -vv (level 2), -vvv (level 3).

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Move TTY ^D hint to plcc-scan stdout, independent of -v (b129473)

Hint is always printed to stdout as the first line when stdin is a TTY. Removes it from -v stderr diagnostics and from plcc-tokens responsibility.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Rename --show-all to --trace/-t in design and plan (c626038)

Stakeholders identified --show-all as trace output, aligning with the original PLCC --trace flag for parse. Both plcc-scan and plcc-tokens use --trace consistently; the note explaining the "identical name, different meanings" tension is removed since the flags now share the same clear intent.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Resolve findings 2 and 3 from spec quality review (f7f2b8f)

Finding 2: source_line comes from obj.line.string — no new dataclass field. Finding 3: attempts contains all matching rules (tokens and skips) in definition order, regardless of which type wins; winner is whatever match() returns.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Resolve remaining spec quality review findings (36daee8)

  • Finding 1: note pattern field emitted as "regex" JSON key - Finding 4: fix column numbers in --show-skips and --show-all examples - Finding 5: clarify --show-attempts ordering relative to cursor line - Finding 6: note --show-regex applies to skip lines too - Finding 7: char_count == len(lexeme), included as renderer convenience - Finding 8: is_skip carried for downstream consumers, not used by renderer - Finding 9: explicitly call out oneOf third branch and attempts item schema - Finding 11: grammar file does not emit per-file event (not a source file) - Finding 12: add TTY hint text string - Finding 13: TTY hint test is bats only (remove "or bats" pytest hedge) - Finding 14: add attempts item field list with types - Finding 15: acknowledge --show-all name is intentional on both commands

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update scan verbosity design spec with revised output flags (3986f51)

Simplifies default output (no regex), replaces individual tokens flags with --show-all on plcc-tokens, adds --show-line/--show-regex/--show-all on plcc-scan, and updates -v references to match merged main branch.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • scan: Add pattern and attempts fields to Token and Skip (7a802b6)

Add two new fields to Token and Skip data carriers with compare=False to enable downstream formatting and diagnostics while keeping existing equality assertions backward-compatible.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Populate pattern always; build attempts list when record_attempts=True (b756caa)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Replace stderr capture with pass-through; add --show-* enrichment flags and TTY hint (1f3e266)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • schema: Add SkipRecord branch and optional enrichment fields (5aae9a5)

  • tokens: Add --trace flag, SCANNING_FILE event, emit skips and enriched records (aaa3fe4)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tokens: Formatter handles Skip and emits enriched fields when show_all=True (b40bbd2)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • scan: Add --show-* flags, --trace, verbose levels, and TTY hint bats tests (ea4f98b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Fix test_record_attempts_skip_win_includes_token_candidates to cover skip-beats-token scenario (1597b13)

  • tokens: Add --trace enrichment and -v per-file event bats tests (eb0008a)

  • tokens: Add skip enrichment test and use constructor kwargs in fixtures (02c18c0)

v0.7.0 (2026-05-08)

Bug Fixes

  • Update module docstring to reference -v flag (d47cf35)

Documentation

  • Add design spec for -v counting flag replacement (83af049)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for -v counting flag (e1296cd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • Add [-v ...] to all CLI usage lines for docopt-ng counting (19b04db)

Also fix ll1_cli_test.py to use -v/-vv instead of the removed --verbose=LEVEL flag.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Replace --verbose=LEVEL with -v counting flag in verbose.py (9a035e2)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • Add -vv bundled-flag acceptance test for plcc-scan (efc13d0)

  • Update bats command tests to use -v flag (7d80a2a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Update java emit test to use -v flag (368f8ad)

v0.6.0 (2026-05-07)

Bug Fixes

  • scan: Exit nonzero when plcc-tokens fails (9a9ee36)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for scan token file provenance (653cf22)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for scan token file provenance (65130f1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Correct design spec — custom helpers, not Source, for line reading (bdfe469)

Source.strip() corrupts column numbers; document the actual approach.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • scan: Pass SOURCE args to plcc-tokens; always include file in location (9cdb107)

  • tokens: Accept SOURCE file args; label stdin lines with file='-' (78eab7d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • parse: Update location format in token leaf assertion (9585add)

  • scan,tokens: Update and add file-provenance bats tests (8667753)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.5.0 (2026-05-07)

Bug Fixes

  • parse: Detect upstream error records and report to stderr, exit nonzero (070d16b)

  • scan: Handle error records inline, drop --continue-on-error from plcc-tokens call (4e1807a)

  • tokens,scan: Update schema for error records; use message from record in scan output (111acb5)

  • token.schema.json extended to oneOf[TokenRecord, ErrorRecord] to cover the full plcc-tokens stdout stream - plcc-scan now reads message from the error record instead of hard-coding the wording

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • issues: Add plcc-scan review issues 001-004 (79bad29)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • issues: Delete done issues (7f1e9f1)

  • plans: Add implementation plan for scan errors inline (issue 001) (5220538)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add design for scan errors inline (issue 001) (9a3fd0d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Features

  • tokens: Add format_error_record to jsonl_formatter (9fdaf9e)

  • tokens: Emit lex errors as stdout records, exit 0, drop --continue-on-error (c2b5cb6)

Refactoring

  • tokens: Add type guard to format_error_record (b2ea457)

Testing

  • bats: Update lex error tests for new stdout-record protocol (6ed919a)

  • bats: Update plcc-parser-table lex error test for stdout-record protocol (d9a305c)

  • tokens: Assert exit 0 explicitly in lex error test (0c56226)

v0.4.0 (2026-05-07)

Bug Fixes

  • scan: Handle BrokenPipeError in feeder, flush token output, drop feed join (5469144)

Features

  • scan: Stream tokens line by line using Popen (39ed0bf)

Replace subprocess.run with Popen + two background threads so input is fed and output is consumed concurrently, enabling line-by-line streaming instead of buffering all input before starting.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.3.0 (2026-05-07)

Bug Fixes

  • scan: Print tokens before and after lex errors (3699e8f)

Pass --continue-on-error to plcc-tokens and always process stdout regardless of exit code, so tokens emitted before a lex error are not silently discarded.

Features

  • tokens: Add --continue-on-error flag (d4d402d)

Refactoring

  • scan: Remove unreachable error branch from token loop (3fe33d6)

v0.2.0 (2026-05-06)

Features

  • parse: Accept '-' as stdin (5ee2b73)

  • scan: Accept '-' as stdin (a0f314b)

Performance Improvements

  • parse: Avoid quadratic copy when building input (ae7c4cb)

v0.1.3 (2026-05-06)

Bug Fixes

  • make: Brief usage mentions --help (d8138b8)

  • parse: Brief usage mentions --help (fbb383a)

  • rep: Brief usage mentions --help (950f7cc)

  • scan: Brief usage mentions --help (e93ea70)

Chores

  • Pin devcontainer feature versions in lock file (e361107)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add design spec for plcc-scan issues 001–004 (4cd258e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add file-based issue tracker design (25f440b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add implementation plan for plcc-scan issues 001–004 (4c52065)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add issue tracker implementation plan (4111885)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add plcc-scan issues 001-004 (bc5f121)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Scaffold file-based issue tracker (64d1701)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Refactoring

  • Add line before help hint (29aa064)

  • Print newline using a separate print statement (5604310)

Co-authored-by: Copilot Autofix powered by AI 175728472+Copilot@users.noreply.github.com

  • Print newline using a separate print statement (511fccc)

Co-authored-by: Copilot Autofix powered by AI 175728472+Copilot@users.noreply.github.com

  • Print newline using a separate print statement (4b90167)

Co-authored-by: Copilot Autofix powered by AI 175728472+Copilot@users.noreply.github.com

  • Print newline using a separate print statement (15f7a51)

Co-authored-by: Copilot Autofix powered by AI 175728472+Copilot@users.noreply.github.com

v0.1.2 (2026-05-05)

Bug Fixes

  • ci: Skip attestations on TestPyPI to avoid duplicate-attestation error on PyPI (935058a)

The pypa/gh-action-pypi-publish action generates .publish.attestation files alongside the wheel during publish. When the same dist/ is published to two indexes (TestPyPI then PyPI) within one workflow run, the second call sees the leftover attestation files from the first and errors out. Disabling attestations on the TestPyPI step lets the PyPI step generate them fresh — TestPyPI doesn't need attestations anyway.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.1.1 (2026-05-05)

Bug Fixes

  • ci: Skip existing files on TestPyPI to allow workflow retries (5849700)

TestPyPI rejects re-uploading any filename that has been deleted (filename-reuse policy), which makes failed workflow runs unrecoverable without bumping the version. skip-existing: true makes TestPyPI publish tolerant of both already-uploaded and tombstoned filenames.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

v0.1.0 (2026-05-05)

Bug Fixes

fix: update CI/CD pipeline

  • On pushes to PR: * Run automated tests. * Build multi-arch images tagged with PR for manual testing. * On merge to main, release by: * Use Conventional Commits to determine next release number. * Tag commit with next release number. * Build multi-arch images tagged with new release number (3.2.1, 3.2, 3, and latest) * Create release entry in GitHub with release notes (commit messages).

refactor: determine --version from git tag, then VERSION file, otherwise "Unknown"

We now ask users to place a callback into .bashrc or .zshrc. That way upgrades that need a change in the environment do not need to ask the user to update their .bashrc or .zshrc.

  • Print error messages to stderr in ProcessFiles.java (ea099d2)

Co-authored-by: Timothy Fossum fossum@halsum.org

Fixes #22

  • Print messages to stdout instead of stderr (05c0908)

Co-authored-by: Timothy Fossum fossum@halsum.org

Tim wrote the code and the above comments. I'm just the committer.

  • Remove BASH_SOURCE, not POSIX (#85, 5f05e44)

  • Remove use of new Java switch statements/expressions (#62, 7de5505)

Fixes #61, allowing PLCC to work with Java 11 or higher.


Co-authored-by: Timothy Fossum fossum@halsum.org

  • Renormalize line endings in bat files (c37f559)

  • Restore missing plcc bash script (#17, 1c0e35c)

  • Restore VERSION file (7747836)

  • Small fix regarding handling of EOF on input (7edba11)

PL/PLCC/Std/Scan.java taken from https://drive.google.com/drive/folders/1x8aM6Xi6RMRuJZHVnzdSJZlS-8U_buaa?usp=sharing at 20200711T235651Z-001.


Related to https://github.com/ourPLCC/course/issues/8

  • Token propagation when using a custom scanner (#51, fa28f15)

Hi.

I just noticed that the Token.template file in the Std directory uses an old representation of how token names get propagated into a Token.java file when using plcc.py with the '!pattern=' flag in the input file.

The '!pattern=' flag is typically used when writing a compiler and not a PLCC-generated interpreter. In this case, the user must supply a stand-alone scanner (Scan.java) instead of using the Scan.java found in the Std library directory. Such a Scan.java file must still implement the IScan interface, so its 'cur' method must still return a Token object.

Token.template (instead of Token.pattern) in the Std library is used to generate Token.java when PLCC is flagged to use a hand-crafted scanner other than the Scan.java in the Std directory. Note that this only applies in the case where PLCC is used to create a compiler instead of an interpreter.

I have uploaded Token.template into the plcc.pithon.net directory. This will not have any effect on any of the examples in the Code directory, since none of these examples use the '!pattern=' flag.

Tim

Co-authored-by: Timothy Fossum fossum@halsum.org

Closes #66

Closes #69

  • Version bump (89bfc62)

  • Version bump (b4ae438)

  • bats/commands: Fix test isolation, JSONL handling, and fragile interpolation (01d493c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • bin: Improve shell script safety and clarity (8dec94e)

  • bin/build: Self-install pdm in package.bash if not present (a3178e3)

  • bin/test: Add venv to PATH before running bats (16e88b2)

  • bin/test: Put installed venv on PATH before running plcc-make (f96dac6)

  • bin/test: Use plantuml_only fixture in packaging test (trivial has Java section) (a6e0011)

  • build_model: Strip trailing whitespace from %%% block delimiters (3c9a531)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cd: Remove username from test image (46548c0)

  • cd: Use working parts of ci.yaml (c1c5a03)

  • ci: Define version component variables (371a597)

  • ci: Only create full version tags (f03b0ba)

  • ci: Smoke test uses real plcc-make CLI (no --output, build/ relative to CWD) (f2b22b5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • ci: Trigger (1809c7b)

  • ci: Try again (e809fc9)

  • ci: Try again (5d523c6)

  • e2e: Prevent languages-java.bats from running twice in e2e.bash (1960721)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Grammar: Any set-compatible object is a valid nonterminal (7e4d798)

  • Grammar: When terminal found to be nonterminal remove it from terminals) (8268841)

  • java-emit: Remove bare imports and add runtime.Token import in generated Java (00101d2)

  • java-emit: Remove stub runtime/Main.java that conflicts with generated Main.java (b813dd0)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lang: Add Python plugin unit tests, fix quoting style and BATS assertion (fa4400b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lang: Fix Java stub JSON parsing, add unit tests, fix quoting and BATS coverage (624704e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lang: Remove unused shutil import and add main() test coverage for list (19897ce)

  • lexical: Use re.error instead of re.PatternError (added in 3.13, not 3.12) (6a6d8f7)

  • ll1: Remove speculative --format option and wire input loading in stub (864150d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Fix left-recursion cycle reporting in _report_ll1_failure (6b12d9a)

  • model: Strip trailing newline before %%% delimiter comparison (ab7e752)

  • packaging: Use project venv Python to satisfy >=3.12 requirement (2ec9d62)

System python (3.11.2) fails to install the wheel because pyproject.toml requires Python >=3.12. Use the PDM-managed .venv/bin/python (3.14.2) instead.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parse-blocks: Treat %%% with trailing whitespace as block delimiter (bd6a16b)

The regex for block markers required %%% to be followed by either nothing or a # comment, rejecting %%% with trailing spaces. Some legacy grammar include files (e.g. RANDSCONT/cont) end blocks with '%%% ' (trailing space), causing each subsequent Java code line to be parsed as a separate fragment with the line content as its class_name. Widening the regex to allow optional trailing whitespace (before any optional # comment) fixes the misparse without changing behavior for valid inputs.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Pass error records through in plcc-parser-table (dc76921)

  • parser: Simplify dead branch and add --verbose-format test (464b5be)

  • plcc-python-run: Add -u flag to prevent buffering deadlock in plcc-rep (880aba5)

  • plcc-rep: Fix GRAMMAR docstring, drain stderr pipes, remove duplicate --verbose-format option (b037f35)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plcc-rep: Handle empty semantic sections and BrokenPipeError on interpreter write (5e3f665)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plcc.py: Enforce uppercase token names (1be4531)

Co-authored-by: fosler fossum@halsum.org

  • pypi.yaml: New version (4f8860c)

  • scan: Close spec file handle, remove stale skeleton test (aa55af2)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan.matcher: Skips ignored if a token matches before any skips (d8a4630)

  • shell: Use bash in shebang (973da7f)

  • test: Fix temp-file leaks and shell injection in bats integration tests (64c5214)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • test: Pass spec JSON (not .plcc path) to plcc-tokens in pipeline integration test (73c1a53)

  • test: Update plcc-rep and plcc-lang-run tests for new REPL implementation (0f7001a)

  • plcc-rep tests now set up build/ artifacts in setup() using plcc-spec, plcc-ll1, and plcc-python-emit - Output assertion updated from "evaluated" to "42" (actual REPL output) - plcc-lang-run dispatch test fixed: use valid tree JSONL with proper children pairs format and check for "result" instead of old "evaluated" string

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Build System

  • Add release-image.yml file (3be8ecb)

  • Cleanup (#14, e487714)

  • delete .trash - delete .gitpod/workflows - delete .github stuff - remove version tags - move .vscode/settings.json into .devcontainer/devcontainer.json - simplify PR template. - update .devcontainer - remove dockerfile - ignore .pdm-build/ - delete containers/ - delete installers - delete unused tests - delete .releaserc - delete .versionrc

  • Extensions (#40, 6b653e6)

  • Prepare to unit test (fe08748)

Adopt Technologies:

  • PDM - "A modern Python package and dependency manager supporting the latest PEP standards." * pyproject.toml - Used by PDM to manage project dependencies and metadata. * pytest - A nice modern unit testing framework for python.

Reorganized tests, and removed local-min-max test. They were breaking and are VERY slow. They were intended to mimic those that run in CI. But those are passing.

Added bin/test/units.bash to run unit tests. Place unit tests in tests/unit/.

No longer supporting python < 3.9.


Related to #119 Closes #131

Thanks to Co-authored-by: Akshar Patel aksharpatel1233@gmail.com He performed the initial research for pyproject.toml

  • Raise minimum Python version to 3.12 (23ba4ce)

  • Release and publish (#21, 7b09fe1)

  • Update license (#16, e765712)

  • bin: Add developer scripts for build, install, and test (fe11f00)

  • bin: Add package build script and scope build/ gitignore to root (b628d22)

  • bin: Self-install pdm in units.bash if not present (a74f8f8)

  • devcontainer: Install pdm on start (507b12c)

  • mypy: Remove dependency (a602e02)

We do not use annotated types or check them.

  • shell: Move COPY later to improve caching (b1ed014)

Currently any change to any file in the repository invalidates the entire cache. By moving the COPY . /plcc command to later in the Dockerfile, the cache for the commands above can be reused, improving build performance.

  • shell: Remove build args to enable caching (538ea8d)

ARG lines in Dockerfile invalidates build caches from that point on. The existing ARG lines were used as constants so that version numbers could be specified at the top of the file. But their adverse effect on build performance does not outweigh their benefit in design. So this commit inlines them.

  • shell/run: Don't cd to project root (b42c5d2)

shell/run no longer changes to the root of the project before running the shell environment. This means the current working directory from which you run shell/run will be mounted into the environment rather than the root of the project. This makes it more flexible in manual tests.

Chores

  • Add .worktrees/ to .gitignore (c6b1ca7)

  • Add Claude Code to devcontaner (f656eaa)

  • Bump version to 1.0.1 in VERSION file (233f85e)

  • Delete empty src/plcc/lang/ext/plantuml stub (425e87f)

  • Move .claude config and memory from plcc (99bee81)

Bringing over Claude Code settings and project memory as development moves to plcc-ng. Also ignores settings.local.json.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

alpine: 3.12 -> 3.14

python3: 3.8 -> 3.9

bash: 5.0 -> 5.1

bats: 1.2 -> 1.3

  • bump: 3.1.1-dev.0 (7c70965)

  • ci: Add languages-pin.txt for reproducible corpus tests (c8be85a)

  • ci: Bump python to 3.14 (4f1fd7a)

  • ci: Fix release mechanism (f0984ff)

  • ci: Remove commit: "false" (a913b06)

  • ci: Use 'pypi' environment for trusted publishing (d895a78)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • cicd: Upgrade semantic-release action (9cf29d9)

Hoping this fixes the release issue.

  • claude: Add bash permission allowlist to settings.json (f8d887d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • claude: Update permissions allowlist for Phase 1 tooling (a792f96)

  • install: Add java install script and auto-install in e2e.bash (6ba8124)

bin/install/java.bash installs default-jdk via apt if javac is not already present, following the same idempotent pattern as bats.bash and pdm.bash. e2e.bash calls it when LANGUAGES_REPO_PATH is set so the Java corpus tests run in any environment without manual JDK setup.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • packaging: Rename to plcc-ng, fix license, add PyPI metadata and semantic-release config (c10aa07)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

This commit only applies to the shell that is used to manually test PLCC (in ./shell).

Alpine does not keep old package versions. So if you pin to a specific package version, your build will break if Alpine updates to a new version of the package.

To allow package versions to varry, but maintain some level of consistency in builds, we're pinning to approximate versions instead. For example, instead of

openjdk=11.0.7-rc0

We now pin to

openjdk~=11.0

This allows the rest of the version number to spin as needed. In theory, allowing patch updates should not break our build.

  • spec: Confirm LL(1) separation with comment (2c3a894)

  • test: Display versions of test dependencies (98e0454)

  • versions: Allow for non-existant commands (b67b394)

Code Style

  • Remove trailing whitespace (0bc5d90)

  • bats: Use python3 consistently and add bats version guards (bee549e)

  • pyproject: Normalize entry point spacing in [project.scripts] (c42e766)

  • Std: Clean up whitespace (b03798a)

  • verbose: Consolidate imports in verbose_test.py (eef2cbf)

Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com

Continuous Integration

  • Add GitHub Actions workflow for multi-lang branch (39162ff)

  • Add release.yml with semantic-release and Trusted Publishing (5354817)

  • Avoid duplicate runs by limiting push trigger to main (3274bd8)

  • Checkout tags too (7dcdab9)

  • Combine pypi and release (2ab18e6)

  • Debug pdm (7a94be3)

  • Exclamation triggers major version bump (#83, 7557a96)

Closes #60

Release is now performed by a GitHub action. The manual release mechanism should no longer be necessary.


Closes #71

  • Replace ci.yml with three-job workflow (unit-integration, corpus, packaging) (4537397)

  • Run CI on all branches and pull requests (7310f78)

  • Run on pull_request to test merged version (758b3d7)

According to https://github.com/actions/checkout/issues/15#issuecomment-524093065 if we run on pull_requests instead of on push, we'll get the merged version of the repo rather than the pull request branch.

  • Upgrade to Node.js 24 compatible action versions (dedac2e)

Bump actions/checkout v4→v5 and actions/setup-python v5→v6. Both new versions target Node.js 24, eliminating the deprecation warning ahead of the June 2026 forced cutover.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Documentation

  • Add CONTRIBUTING.md and CLAUDE.md for developer workflow (e098105)

Address Phase 1 retro finding that agents repeatedly wrote ad-hoc scripts instead of using pre-built commands in bin/. CONTRIBUTING.md describes bin/ scripts, test tiers, the TDD inner loop, and workflow conventions. CLAUDE.md is a short pointer auto-loaded by Claude Code at session start, directing readers to CONTRIBUTING.md and forbidding ad-hoc scripts.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • Add initial CONTRIBUTING.md (f415422)

  • Add intro on which contribution process to use (d239629)

  • Add link to new Discord server (4a14c22)

  • Add location of install and test install (f8c710e)

  • Add more links to Discord (aece35c)

  • Add multi-language architecture and implementation roadmap (5cf2d3e)

Moving design documents from plcc to plcc-ng to develop and demonstrate the implementation here first before merging upstream.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add pointers to issue tracker and CONTRIBUTING.md (a6dde8e)

  • Add uid:gid to docker run (#88, 17d596e)

Closes #87

  • Add updating a pull-request and generalize (e6db9bb)

  • Adjust project name (01d5371)

  • Credit co-authors for 41b8e97 [skip-ci] (b8e2341)

Co-authored-by: James Heliotis jeh@cs.rit.edu

Co-authored-by: Timothy Fossum fossum@halsum.org

  • Fix based on Jim's feedback [skip-ci] (db394cf)

Co-authored-by: James Heliotis jeh@cs.rit.edu


  • Closes #127

  • Improve pseudo-code of scan algorithm [skip-ci] (41b8e97)

  • Move CHANGELOG.md to docs (814d379)

  • Move common contributing documentation to wiki (73cdc78)

  • Move wiki into repo (#77, dd6883a)

Closes #73

The goal is to consolidate and minimize the end-user documentation to make it easier to navigate, and faster to get started.

  • Reduce the number of Discord links (a0810b6)

  • Reorganize designs and plans (3d54d87)

  • Simplify (75cc1c0)

  • Update add Use.md (c512a12)

  • Update docs (#18, e63517b)

  • design: Add Phase 2 Part 2 model and diagram system design (e731cb8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Add Phase 2 Part 3 design — Python emitter and interactive REPL (ce49eed)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Add §17.8 pipeline-wide --verbose diagnostics (29f5a7b)

Every stage accepts --verbose/-v as a level dial (0–3) and writes human-readable narrative to stderr. Walking-skeleton discipline: accept-and-forward is mandatory from day one in every stage; content fills in as stages mature. Output standards include stage-name prefix, GNU-style source positions, present-tense active voice, and line-atomic writes.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • design: Address review findings in phase 2 part 1 ll1 parser design (f104bcf)

  • Specify algorithm end-of-input handling (synthetic $ sentinel), success condition, and stack-empty-with-remaining-tokens error case - Clarify lookahead key is token name field (or "$")

  • Fix span computation: add explicit formula for endColumn (1-indexed inclusive) - Fix "conflicting cells omitted or arbitrary" -> cells are omitted - Fix level-0 verbose wording: silent regardless of is_ll1 value, not "on success" - Add JSONL payload shapes for all verbose events in both plcc-ll1 and plcc-parser-table - Add Python enum note for hyphenated event names (predict-lookup, first-set, etc.) - State tree is assembled in memory and written atomically only on exit 0 - Make plcc-spec deliverable concrete (code comment confirming separation) - Make plcc-parser-list verbose flag acceptance an explicit deliverable - Note tree.schema.json and ll1.schema.json as schema file deliverables - Justify plcc-ll1 stdin-only decision explicitly - Note arch spec field name discrepancy (first vs first_sets)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Address review findings on skeleton update design (40b18a3)

Fixes from independent review: - F1: Mark --ll1 as required on plcc-parser-table - F2: Document dispatcher asymmetry (parser vs lang no-op semantics) - F3/F4: Clarify intermediate artifact plumbing for Level 2 commands - F6: Confirm spec.json carries tool→language mapping - F7: Confirm plcc-make does not invoke plcc-lang-run - F8: Resolve docopt -v vs count-style -vv ambiguity (use --verbose=N) - F9: Draft §17.9 amendment text for plcc--run - F10: Note --parser on Level 2 commands is deferred - F11: Document _cli suffix naming convention - F12: Add ll1.schema.json to scope - O7: Note JDK requirement for Java plugin tests

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • design: Amend multi-lang pipeline spec with §17.3–§17.7 (e3a7159)

Phase 2 Part 1 brainstorm amendments to the architectural spec:

  • §17.3 plcc-tree is one-shot, not long-running - §17.4 introduce plcc-ll1 primitive; plcc-spec stops doing LL(1) - §17.5 generated components are pipeline stages - §17.6 parsers are pluggable via PATH-based plcc-parser- - §17.7 interpreters long-lived; plcc-tokens/plcc-tree per chunk

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • design: Append Phase 1 retro to walking skeleton design doc (95979ef)

Captures surprises, architectural review (no amendments needed), what worked, cross-phase gaps (developer docs, aggregated coverage), and feed-forward items for the Phase 2 brainstorm. Per roadmap §9.4.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • design: Apply language plugin command contract to existing specs (da2eaa8)

Updates pipeline spec and implementation plan to reflect the decisions captured in the language-plugin-command-contract design doc: retire plcc-emit, introduce plcc-lang-emit/build/list dispatchers, rename plugin commands to plcc--emit/build, drop the plcc.emitters entry-point group, and switch to PATH-based discovery throughout.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Draft Phase 2 Part 1 LL(1) parser design (2b2c818)

DRAFT status — captures brainstorm decisions (A' parse tree schema, unified token/tree schemas, error node shape, verbose protocol) but implementation scope needs revisiting after the walking skeleton is updated to reflect §17.3–§17.8 amendments.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • design: Extend §17.9 to supersede §17.6.2 parser-plugin error bullets (d9c8c92)

  • design: Finalize phase 2 part 1 ll1 parser design (e086d26)

Promotes the draft to APPROVED status, incorporating decisions from the brainstorm session: labeled children, source-field positions with endLine/ endColumn on internal nodes, stdin-only plcc-ll1, parse table with field-annotated symbols for AST elision, predict_sets as ordered list of predict sets per alternative, conflicts array as self-contained diagnostic, start_symbol in ll1.json, and expand/shift/complete verbose events at -vv.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Fix spec self-review issues in Phase 2 Part 3 design (b37c0b2)

  • Add Expr.eval() fragment to arith.plcc fixture (Program._run needed it) - Add auto-generated parent class import to class_file.py.jinja template

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Fix §17.3 framing — plcc-tree emits single JSON document (714e340)

Under the one-shot posture, the multi-program-per-invocation JSONL framing was dead justification carried over from the long-running design. plcc-tree now parses one program per invocation and emits a single newline-terminated JSON document, which is also a valid one-line JSONL stream so it composes with the §17.7 interpreter without an adapter.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • design: Language plugin command contract spec (dcf11ee)

Captures the decision to replace Python callable-based emitter plugins with CLI command-based plugins (plcc--emit, plcc--build), PATH-based discovery, and the plcc-lang-* dispatcher commands.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Merge amendments into multi-lang pipeline architecture doc (dc4dcfa)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Phase 1 walking skeleton design doc (f704467)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • design: Retire §8 in-band errors; add §17.9 stderr+exit-code model; simplify Part 1 parse-tree schema (42a075f)

  • design: Rewrite §17.8 as dual-form verbose diagnostics (892e1ff)

--verbose/-v level dial (0-3) controls how much; --verbose-format= text|json controls how. Default is text (human-readable narrative). Level 2 orchestrators override children to --verbose-format=json and may request higher verbosity than the user asked for (asymmetric propagation). Addresses independent review findings: interpreter lifecycle (flags immutable for session), Level 2 nesting (out of scope), timestamp scope (intra-stage only), PIPE_BUF caveat, -vv flag-counting clarification, and §17.6.3 cross-reference.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • design: Skeleton update design for architectural amendments §17.3–§17.8 (59da9a6)

Captures the design for updating the Phase 1 walking skeleton to reflect the architectural amendments from the Phase 2 brainstorm. Covers new commands (plcc-ll1, plcc-parser-table, plcc-parser-list, plcc-lang-run), Python and Java language plugin stubs, verbose infrastructure (plcc.verbose), Level 2 command promotion, and test/fixture updates.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

  • plans: Add phase 2 part 1 implementation plans for ll1 analysis and parser table (c50b174)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add Phase 2 Part 2 implementation plan (edf2e67)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Add Phase 2 Part 3 implementation plan (python-emit + plcc-rep) (2694dda)

  • plans: Add Phase 2 Part 4 arbno implementation plan (f7553f7)

  • plans: Add Phase 3 Java emitter implementation plan (fcf173d)

  • plans: Add Phase 4 packaging and release implementation plan (c0b0118)

  • plans: Error handling redesign in three model-tiered parts (b949c31)

Part 1 (Opus) retires §8 in-band errors, adds §17.9 stderr+exit-code model, and simplifies the Phase 2 Part 1 parse-tree schema. Part 2 (Sonnet) applies the mechanical code changes across Level 0 stages. Part 3 (Opus) wires pipefail attribution and cascade suppression into the Level 2 orchestrators.

Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com

  • plans: Phase 1 walking skeleton implementation plan (77d40ca)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Resolve all review findings before phase 1 execution (e5f8191)

Addresses all 6 blockers and 10 concerns from the independent review (docs/reviews/2026-04-13-phase-1-plan-review.md).

B1: fix _extract_fields to use isCapturing/isTerminal flags (not kind); add discovery step to confirm actual plcc-spec JSON shape first B2: fix tree_cli_test --spec to pass spec JSON, not a grammar file

B3: remove dead with open(model_json) as model_f: block in plcc-make

B4: add sed step to update --cov=plccng → --cov=plcc in pyproject.toml

B5: new Task 7a — retire scan_cli.py, json_formatter.py, text_formatter.py

B6: new Task 7b — delete plcc_cli.py and spec_cli.py (decision: remove)

C1: fix trivial grammar in design doc §3 (plantuml → diagram)

C2: fix capitalize() → [:1].upper()+[1:] to preserve camelCase names

C3: add discovery step for spec_loader LexicalRule duplication decision

C4: add Phase 1 comment to tree_cli.py explaining --spec is unused

C5: document one-file-per-class design choice in plantuml emit.py

C6: add try/except ValueError around validate_tool_name in plcc-make

C7: resolved by B6 decision (plcc_cli.py removed in Task 7b)

C8: add explicit test inventory step to Task 4

C9: add --semantics deferral comment in lang-emit and plcc-make

C10: simplify packaging.bash entry-point check to test -x

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plans: Skeleton update implementation plan (19 tasks, 7 parts) (6a85c9a)

  • plans: Update smoke test to use trivial-plantuml.plcc fixture (1eabee9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • readme: Fix typo, add install section and 'what this is' note (e0e1eaf)

  • reviews: Phase 1 plan independent review (a24ac49)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • shell: Fix bats version number (894aa32)

  • specs: Add Phase 2 Part 4 arbno support design (dee5c5b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add Phase 3 Java emitter design (d43f286)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • specs: Add phase 4 packaging and release design (809401f)

Phase 4 design: visualizer polish (location-aware, human-first errors), package rename to plcc-ng, license fix to AGPL-3.0-or-later, PR-triggered CI with full test suite (incl. languages corpus pinned via tests/fixtures/languages-pin.txt and twine check), and a release workflow built around python-semantic-release in tag-only mode plus Trusted Publishing to TestPyPI then PyPI.

Versioning starts at 0.0.0 — plcc-ng is a separate, experimental identity from the original plcc; the 9.0.0a* prerelease scheme is abandoned. Release decisions about whether plcc-ng becomes the successor to PLCC are deferred to Phase 5 and beyond.

  • specs: Append Phase 3 retro to phase-3-java-emitter-design (1fff1f1)

  • testing: Add testing documentation (ca08e75)

Features

  • Add %include (1c74d39)

  • Add %include, which is a synonym for #include. * Deprecate #include, use %include instead. * Deprecate include, use %include instead.

In a PLCC grammar file, #`` starts a comment. So#includelooks like a comment, but it's not. To avoid this confusion, we are adding%includeand plan to remove#include` in the next release.


Related to #99 Related to #115

Print version number and exit without error.

Related issue: https://github.com/ourPLCC/plcc/issues/10

Validates a given LexicalSpec object and returns an errorList


  • Closes #13

Co-authored-by: Kyle Almeida almeidakyle03@gmail.com

Co-authored-by: Akshar Patel aksharpatel1233@gmail.com

Add check_ll1 method to verify ll1ness, and add helper Grammar and Wrapper classes.


  • Closes #18 * Closes #48

  • Add parse_semantic_spec (cad5c53)

Parses a given semantic spec into a SemanticSpec object. Updated a Divider object to include tool and language.


  • Closes #7

Co-authored-by: Michael Banerjee michaelbanerjee10@gmail.com

Co-authored-by: Akshar Patel aksharpatel1233@gmail.com

Co-authored-by: Kyle Almeida almeidakyle03@gmail.com

  • Add parseSpec (#58, e862b6a)

  • Add plccng.spec.parseSpec, that returns (spec, errors). * Remove access to plccng.spec.parse_from_string; use plccng.spec.parseSpec * Remove access to plccng.spec.parse_lexical_from_string; use plccng.spec.parseSpec * Move plccng.spec.lines to plccng.lines

  • Add parsing table checker (bc35f9a)


  • Closes #36

  • Build plccng/scanner/source (#32, 8cbea2b)

  • Build src/plcc/scanner/sink.py (#61, b01024c)

Co-authored-by: Stoney Jackson dr.stoney@gmail.com

Co-authored-by: Stoney Jackson dr.stoney@gmail.com

  • Last merge merged a feature (b815e10)

  • Optional colon in RHS of rule to pass name (0a4cf1c)

This version allows for optional ":" in annotated class and field names. I know this may be controversial, but I honestly don't think it's a big deal: I always wondered why I made the "decision" to use ":' in LHS and not in the RHS -- to do so was NOT a rational decision on my part, and I am perfectly happy with making them optional in both situations. This does not break class notes or even the languages in the Code directory, so it's not a big deal. I suppose the plcc documentation should say something about this...

fix: conflicting dummy constructor generation

ONE '1' % ::= ONE

With the current version of plcc.py, the dummy constructor conflicts with the automatically-generated constructor for the One.java class. Removing the dummy constructor fixes this.

refactor: consolidate to one defang procedure

While taking care of the dummy constructor, I also re-factored the 'defang[g]' procedures, so there is only one general 'defang' procedure. [The term 'defang' refers to removing the angle brackets (fangs) in <...> grammar rules. I invented the term, so blame me for the usage.] The 'defangLHS' procedure handles LHS items in BNF rules, and the 'defangRHS' procedure handles RHS items: the LHS and RHS versions are slightly different. This refactoring makes the python Java class generation code a bit tighter, but the Java code that gets generated is exactly the same as before.


Co-authored-by: Timothy Fossum fossum@halsum.org

Tim wrote the code and the above comments. I'm just the committer.

Parses a given syntactic spec and tokenizes the input into SyntacticRule objects that contain Symbols on the left and right hand sides.


  • Closes #6

Co-authored-by: Akshar Patel aksharpatel1233@gmail.com

In "The PLCC Tool Set" section of the plcc.pithon.net repository, I have uploaded the latest versions of plcc.py (in the src directory) and Scan.java and Token.pattern (in the src/Std directory). These incorporate the changes we discussed:

  1. Dropping the PP preprocessor option in plcc.py 2. Implementing scanner "line mode" toggling using '^^...' tokens 3. Implementing #include directives anywhere in the specification text

Tim

---------------------- "line mode" in scanner ----------------------

On a related issue, do you want me to implement the "lineMode" feature as I proposed earlier? That is, if a token definition looks like this:

token PCT3$$ '^%%%'

then the scanner will enter line mode whenever it sees the PCT3$$ token on input, and will exit line mode when it sees another matching PCT3$$ token. The "$$" at the end of the token name is what I used to toggle line mode. There are other ways we could use token names to trigger line mode -- my choice of "$$" is only a suggestion.

In line mode, the appearance of <> on the RHS matches an entire LINE of input, and it returns a token with the special token name of $LINE (which cannot conflict with user-defined token names) whose lexeme contains the entire line of input. This only works when the scanner is in line mode.

Here's an example of a PLCC language specification file whose implementation can process a PLCC specification file (but with no semantics)

skip WHITESPACE '\s' token PCT3$$ '^%%%' # toggles line mode token ANYTHING_ELSE '\S' % ::= :NoLineMode ::= :LineMode ::= PCT3$$ PCT3$$ **= <> % # no semantics

The RHS element <> behaves as if it were <$LINE>, where $LINE is the special reserved token name for a line (which cannot be a user-defined token name). The scanner cannot return a $LINE "token" unless it's in line mode, which is toggled as described above.

In the above, once the scanner encounters the line mode toggle token (PCT3$$ in the above), it consumes the rest of the line containing the token and starts line mode processing beginning with the next input line. It then continues reading the input, line-by-line, until it encounters another instance of the same line mode toggle token, whereupon it returns to normal token processing.

Making these changes to the PLCC tool set requires modifications to plcc.py, Std/Scan.java, and Std/Token.java. These changes do not alter the behavior of the Java implementation produced by the PLCC tool set using the language examples in the Code repository, but of course the resulting Java files Scan.java and Token.java will not look quite the same. All of the other generated Java files -- namely, those generated from the BNF grammar specification -- are unchanged.

Incidentally, the Scan, Parse, and Rep programs don't know anything about 'include' in the files they are reading. So if you wanted to run Scan on, say, the V6 language source files using the above language definition, you would need to do something like this:

(cd ~/PL/Code/V6 ; cat grammar code envVal prim val) |\ java -cp Java Scan

where the Java directory has the PLCC code generated by the above language. The 'cat ...' command will grab all of the code pieces (codpieces?) and present them to the scanner as a single file. Just running Scan on the 'grammar' file will not process the named include files, because the language described above doesn't know how.

---------- #include ----------

Bowing to unrelenting pressure, I have succeeded in implementing an 'include' feature for input files to plcc.py. First, so as not to break any existing code, the use of 'include ...' at the end (normally) of the semantics section stays exactly the same: file names are simply added to the argv array and processed as if they were parameters given on the command line.

My proposed 'include' feature allows for lines of the form

include filename

just like C/C++. When such a line appears anywhere in the input file (after any command-line switches), input lines switch to the file with the given filename, and returns to the previous file once the new file contents have been read. These #include directives can be nested -- that is, an #include file can itself have an #include part, and everything gets stacked up.

But BEWARE: if a file has an include like this:

include fff

and if the file 'fff' itself has the same include line

the include mechanism could blow up with a stack overflow. I have made it so that you can't have nested includes more than 4 levels deep, which avoids this problem. I can't imagine nesting even this much, but I'm open to suggestions.

The tricky part about this is that there might possibly be a situation where code in the semantics section between the %%% ... %%% markers has #include lines. This could happen, for example, if the target language were C/C++ -- an unlikely situation, but oddly possible given the insatiable desire of both of you to target any implementation language that is Turing complete. In order to side-step this possibility, I have TURNED OFF the processing of #include directives for code between %%% ... %%% markers. I think this makes sense, and basically treats this code as being entirely language independent (except for lines themselves starting with %%% -- ouch!).

----------------------------- Remove PP option from plcc.py -----------------------------

This option allowed a specified preprocessor command to be ran on the generated code. The implementation relied on Python's now deprecated pipes library. Unaware of any uses of the PP options, we have chosen to simplify plcc.py by removing the PP option and also the deprecated dependency.

BREAKING CHANGE:

Removal of the PP option will break code that relies on this option. There are no alternatives to this option.


Co-authored-by: Timothy Fossum fossum@halsum.org

Closes #49 Closes #55 Closes #58

To print an AST for a program in JSON format, do the following.

plccmk --json_ast GRAMMAR_FILE parse --json_ast < PROGRAM_FILE

Adds a new dependency: the Jackson JSON library for java. We distribute jars (in src/lib) from the following projects under the Apache 2.0 license:

  • https://github.com/FasterXML/jackson-core * https://github.com/FasterXML/jackson-databind * https://github.com/FasterXML/jackson-annotations

If manually compiling and running the generated Java code, you'll need to add these jars to your classpath.

If you don't use the new --json_ast option, these jars do not need to be in your classpath.


Closes #53 - Add option to print parsejava to print ast in json

Co-authored-by: Madison Mason madison.nm1213@gmail.com

Co-authored-by: Rarity Van Lone rarity.vanlone@gmail.com

Co-authored-by: Stoney Jackson dr.stoney@gmail.com

  • Replace repeating with standard rules (4e2d182)

  • Top-level spec (#41, c35cc58)

  • parse_from_lines - parse_lexical_from_string - parse_lines_from_string

  • Trigger release (1ce9cd5)

BREAKING CHANGE: This commit is to coerce semantic-release into releasing a major release.

  • Updates for next release (1d29683)

Breaking changes:

  • The standalone parser is now called 'Parse' instead of 'Parser'. If the parse is successful, it prints 'OK'.

  • Both 'Rep' and 'Parse' process command-line arguments and standard input in exactly the same way, using a support program called 'ProcessFiles'. This reduces code duplication and makes for a common user interface.

  • Printing PLCCExceptions now default to printing a leading "%%% " instead of ">>> ". This makes exception output stand out better.

New and improved features:

  • Each PLCC-generated parser class file has a ":init" hook as the first line of its constructor. This can be used to incorporate Java code into the Class constructor that can carry out simple semantics that would otherwise not be possible using the parser alone.

For example, the Formals class in Language V4 parses the list of formal parameter variables to get a 'varList' of Tokens. In the 'grammar' file (actually, in the 'code' file that the 'grammar' file includes), the lines

Formals:init %%% Env.checkDuplicates(varList, " in proc formals") %%%

would include this call to 'checkDuplicates' as the first line of the Formals constructor. This method will throw an exception if the 'varList' of Tokens has any duplicate identifiers. Including this method in the Formals constructor means that the semantic action of checking for duplicate variable names will be done during parsing instead of at runtime. This hook is just a comment unless defined otherwise in the 'grammar' file.

  • Each PLCC-generated parser class file has a ":top" hook at the top of the file. This can be used to incorporate documentation regarding the file, such as copyright or whatever. This hook is just a comment unless defined otherwise in the 'grammar' file. I haven't used this, but someone might find it convenient.

Other changes, including bug fixes:

  • Instead of printing the 'toString()' value of the root of the parse tree to "evaluate" it using the 'Rep' loop, I have the default behavior call a '$run()' method on the root of the parse tree. Whatever this method does is the 'behavior' of the program. It defaults to printing the 'toString()' value as before. The '$run()' method is void, so whatever visible behavior a program should have can be undertaken in this method.

Co-authored-by: Timothy Fossum fossum@halsum.org

Co-authored-by: Stoney Jackson dr.stoney@gmail.com

Features

  • Upgrade Java to 17 in Docker, allowing language authors to use its features when implementing languages.

Fixes

  • Test for plcc --version now accepts leading v in version numbers.

  • Validate each repetition rule separator is a terminal (#64, 8c0718c)

  • Validate every RHS non-terminal must appear on the LHS of at least one rule (#84, cd4832c)

closes #51


Co-authored-by: Stoney Jackson dr.stoney@gmail.com

  • Validate lhs of syntactic section (05f17a0)

Validates the LHS of a given Syntactic Spec, as well as laying foundation for RHS to be validated.


  • Closes #22

  • Validate SemanticSpec CodeFragments have attributes defined (#59, 43ece85)

Co-authored-by: Stoney Jackson dr.stoney@gmail.com

  • Validate that terminals in syntactic spec are defined in lexical spec (#57, fed798d)

Check that terminals in syntactic spec are defined as tokens in the lexical spec.


Co-authored-by: Stoney Jackson dr.stoney@gmail.com

Closes #52

  • cmd: Add plcc-scan, plcc-parse, plcc-rep skeleton entry points (5d73fbc)

  • diagram: Add plcc-diagram dispatcher (db45a78)

  • diagram: Add plcc-diagram-list command (86d8755)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • diagram: Add plcc-plantuml-diagram command (156250a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • fixtures: Add entry_point and Program/Expr eval fragments to arith.plcc (24a31a1)

  • fixtures: Update trivial-python.plcc to capture NUM and declare _run (8406388)

  • java-build: Add org.json classpath and runtime/*.java compilation (49b9ac4)

  • java-emit: Add class_file.java.jinja template (cc488fc)

  • java-emit: Add Main.java.jinja template (7a2c573)

  • java-emit: Replace stub with full Jinja2-based emitter (2f2b059)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • java-run: Add org.json classpath (729b231)

  • java-runtime: Add bundled org.json-20250107.jar (f9b9087)

  • java-runtime: Add Deserializer class (bbaaaf1)

  • java-runtime: Add Node and Token base classes (21144bd)

  • java-runtime: Add Registry class (9638231)

  • lang: Add Java language plugin stubs (emit + build + run) (aba4cc8)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lang: Add plcc-lang-build dispatcher (5371141)

  • lang: Add plcc-lang-emit dispatcher (4fa082a)

  • lang: Add plcc-lang-list PATH scanner (6a8f76f)

  • lang: Add plcc-lang-run dispatcher (no-op for missing runners) (47c1bd1)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • lang: Add Python language plugin stubs (emit + run) (1047b4d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • ll1: Add ll1_result_builder — compute ll1.json dict from Grammar (c9bc2cf)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • ll1: Add plcc-ll1 stub with empty LL(1) analysis output (d51c9b0)

  • ll1: Add spec_json_decoder — build Grammar from spec JSON (2d5a25a)

  • ll1: Add start_symbol to ll1.schema.json and tighten types (739e03f)

  • ll1: Decode() expands arbno rules, returns 3-tuple with arbno_rules (fe1a54b)

  • ll1: Emit arbno section in ll1.json, filter internal expansion nts (3852bef)

build_ll1_result gains an arbno_rules parameter that filters arbno nonterminals and their continuation nts from first/follow/predict/parse_table/conflicts and emits them under a new "arbno" key with computed lookahead sets.

  • ll1: Emit is_ll1 field; keep exit 0 on non-LL(1) per §17.9 (stub) (ae71cc1)

  • ll1: Implement plcc-ll1 with real LL(1) analysis; stdin only (9094792)

Wire spec_json_decoder and ll1_result_builder into the plcc-ll1 CLI, switching from file-path argument to stdin-only interface; update all callers (make, parse, rep) and bats test suites accordingly.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Abort on is_ll1:false with human-readable conflict summary per §17.9 (952cc81)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Add plcc-ll1 step and Level 2 verbose propagation (1a80e23)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • make: Add plcc-make orchestrator (23a013a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • model: Add plcc-model initial implementation for trivial grammar (75de9c8)

Implements Task 10: plcc-model CLI that reads spec JSON and outputs a language-neutral code model JSON with classes, fields, and semantic sections.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • model: Detect arbno rules, emit is_list fields with List-suffix names (e7b2780)

  • model: Implement class inheritance derivation in build_model (56dd709)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • model: Retire plcc-plantuml-emit language plugin (6f55a39)

Remove emit.py, its test, the bats command test, and plantuml fixtures. Update all tests that referenced PlantUML targets or plantuml_only.plcc to use Python/trivial-python.plcc equivalents instead.

  • parse: Add location-aware tree output and compiler-style error format (50b4d48)

  • parse: Promote plcc-parse to connected skeleton with Level 2 verbose (a70c713)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parse: Use reap_pipeline for upstream-first attribution + cascade suppression per §17.9 (b263433)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add plcc-parser-list (PATH scan for parser plugins) (ec3f119)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add plcc-parser-table stub (relocated pass-through logic) (bf2255f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add predictive_parser — iterative LL(1) table-driven parser (907d1cd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add verbose support to plcc-parser-list (ee22496)

  • parser: Implement plcc-parser-table — real LL(1) predictive parser (700d825)

Wire predictive_parser.parse() into table_cli.main; add unit tests covering valid input, tree structure, source spans, capturing fields, non-LL(1) grammar rejection, syntax error exit codes, and stdout cleanliness on error.

  • parser: Rewrite predictive_parser as recursive descent with arbno loop support (9641871)

Replaces the stack-based implementation with a recursive descent parser that dispatches to _parse_regular or _parse_arbno, enabling iteration over arbno (repeating) grammar rules with optional separators.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Update tree.schema.json for [field,node] children and source span (022ac09)

  • plantuml: Add plcc-plantuml-emit minimal plugin (ddb73ed)

  • plcc-model: Add entry_point pass-through and rule_name to class dicts (b8d61cb)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plcc-python-emit: Full Jinja2-based code generation, one file per class (7e1f737)

Replace stub emit with full implementation: reads model JSON, renders class_file.py.jinja per class, handles file-kind fragments verbatim, renders main.py.jinja with entry_point, and copies runtime/ directory. Deletes the old runtime/main.py stub that was incorrectly being used.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plcc-rep: Rewrite as interactive REPL using pre-built build/ artifacts (4857e8b)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • plcc-spec: Capture optional entry_point in semantic section header (6cfb106)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • rep: Promote plcc-rep to connected skeleton with --tool and Level 2 verbose (9155be5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • runtime: Add Node/Token base classes and jinja2 dependency (2c1a4a3)

  • runtime: Add recursive parse-tree deserializer (a765617)

Implements deserialize() function that reconstructs the object graph from plcc-tree JSON output. Tokens become Token(kind, lexeme) instances, and nonterminals are constructed via Registry lookup with recursive deserialization of children.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • runtime: Add Registry with field-based disambiguation (fc42fe3)

Implement Registry class for field-based class lookup. The Registry indexes classes by rule name and frozenset of field names, enabling disambiguation of parse-tree classes that share the same rule name but differ by fields.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • runtime: Deserialize list values for arbno fields (9b87482)

  • scan: Add --skip option (3bdb32c)

  • scan: Add default plain text formatter (cfca135)

  • scan: Add location-aware output and compiler-style error format (fb5bf40)

Tokens now print with {line}:{col} prefix; lex errors in source are treated as non-fatal (exit 0), reserving non-zero exit for grammar failures.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • scan: Promote plcc-scan to connected skeleton with Level 2 verbose (933d736)

Rewrote plcc-scan to orchestrate plcc-spec and plcc-tokens, printing tokens in human-readable format. Removed the old stub test and added a BATS test suite for plcc-scan. Deleted plcc-skeletons.bats.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Scan.java): fix(plcc.py): refactor(plcc.py: (#23) (2013bf2)

SJ: This is effectively three commits in one. I placed feat(Scan.java): first in the subject line as its change to the version number would mask the others.

fix(plcc.py): prevent capture of user-defined non-terminals

I changed the format of automatically generated nonterminal names for repeating rules for LL(1) checking. Originally, for a nonterminal name like 'nt', the automatically generated nonterminal name was 'nt_aux_' and, for ones with a separator, the separator nonterminal name was 'nt_sep_'. Since it is possible (though remotely so) for a user to have a grammar rule with a nonterminal name of these forms, I changed the separator nonterminal name to nt+'#', which cannot possibly be mistaken for a user-generated name.

refactor(plcc.py): reduce number of rules generated

I also simplified the generated rules for a repeating rule without a separator with two rules instead of three, and for ones with a separator, with four rules instead of five. The generated parser code remains exactly the same. The only difference, internal only to plcc.py, is how the repeating rules are converted to right-recursive non-repeating rules for the purposes of checking for LL(1).

feat(Scan.java): improve error messages

I modified Scan.java so that error tokens -- ones that do not match any token specification -- have a string representation of the form "!ERROR(...)' where '...' is the offending character instead of just $ERROR.

Except for better error reporting for "bad" tokens, these changes do not affect any of the generated code for a language.

Co-authored-by: fosler fossum@halsum.org

Co-authored-by: jeh jeh@cs.rit.edu

  • schema: Update model schema for abstract classes and semantic fragments (244fab9)

  • schemas: Add minimum viable JSON schemas for all Level 0 contracts (51e8113)

  • spec: Add plcc-spec standalone entry point (7e0a1cc)

Adds the plcc-spec command that parses and outputs a PLCC grammar file as JSON, wires it as an entry point in pyproject.toml, and fixes the trivial.plcc fixture to use valid parser format (% dividers instead of %% section headers).

  • spec: Make json output optional (ed0b753)

  • spec.schema: Add entry_point field to semantics items (d79c9bb)

  • templates: Add class_file.py.jinja and main.py.jinja (003d985)

  • tokens: Add plcc-tokens standalone entry point with JSONL output (8c642da)

Implements plcc-tokens CLI that reads a spec JSON file and tokenizes stdin, emitting token records as JSONL with lex errors in-band.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tokens: Route lex errors to stderr + exit nonzero per §17.9; drop in-band error schema (1dc681a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • tree: Add plcc-tree minimal pass-through for trivial grammar (ad0db91)

  • verbose: Add --verbose/--verbose-format to all existing Level 0 commands (ef282f1)

  • verbose: Add reap_pipeline for upstream-first attribution + cascade suppression per §17.9 (76a23bc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • verbose: Add shared VerboseContext infrastructure (e5666fc)

  • verbose: Add VerboseContext.emit_error for stderr + exit-code error path per §17.9 (241e186)

  • verbose: Render error events with GNU-style position per §17.9 (a7e82d7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Performance Improvements

  • shell: Reduce shell size (b31688f)

We were installing the the openjdk11 Alpine packcage. But this includes stuff like demos. By focusing this to openjdk11-jdk, we safe a few hundred MB.

Refactoring

Closes #66

I could not detect a clear pattern or practice of imports in init.py, and they do not look well maintained. So I've decided to delete all imports in init.py

This may lead to some ugly imports. I suggest these should be a "smell" that indicate that a refactor may be warranted.

  • Consolidate shared data structures (#78, 6acc71c)

We have many functions that operate on common data structures. The definition of these data structures are next to the functions that create them. For example, the Line structure is next to the function that parses a line and creates an instance of Line.

The challenge is that when you need to reference the implementation of a structure, you have to find where it first created in the system. It would be better if there was a single place to look for shared structures.

This commit creates a structs.py and errors.y in plcc.load_spec, and moves all data structures and errors into them. This changes the imports of MANY files.

There will likely need to be a couple of tuneups after this as we learn more about the design.

  • Convert plcc.py to python package plcc (231d139)

BREAKING CHANGE:

plcc is now a Python package, and plcc.py has been removed. So plcc.py can no longer be called directly like this

python3 path/to/plcc.py grammar

Instead, use plcc like this

plcc grammar


This commit restructures the PLCC codebase into that of a conventional Python project. This should make it easier to redesign the internal structure of PLCC, making it easier to maintain and add new functionality. It should also help us prepare to distribute PLCC through PyPI, making it easier to install. Here is a summary of changes.

  • Convert plcc.py into python package plcc - Remove environment variable LIBPLCC - Move src/Std/ under src/plcc (the PLCC Python package) - Move lib/jackson under src/plcc (the PLCC Python package) - Pull common functionality of scripts into common.bash

Related Issues

  • Related to #119 - Closes #121 - Closes #120

  • Convert type to isToken in LexRule (f2725c6)

  • Delete src/bin (#17, 90b6d58)

  • Enable Python when grammar has 4 sections (be3aa2e)

This is in anticipation of a new hybrid Java/Python mode in which the parser runs in Java and the semantics rep-loop runs in Python.

In this commit, when an optional 4th section is detected, plcc.py generates ParseJsonAst.json. Thus allowing the parser to to generate JSON ASTs when the --json_ast flag is passed. It also generates experimental Python files.


Closes #95

Co-authored-by: Reed Everis reednorrish@gmail.com

Co-authored-by: Akshar Patel aksharpatel1233@gmail.com

Co-authored-by: Stoney Jackson dr.stoney@gmail.com

This hierarchy better models reality.

Closes #77

  • Generalize visitor pattern (eb2f574)

  • Improve installing and related docs (c60a82f)

  • Add docs for installing and using PLCC in GitPod * Consolidate docs for installing and using PLCC in different environments. * Add installer/install.bash that automates installing PLCC in a bash environment.

  • Improve load_rough_spec coverage (8170cf5)

  • Improve parse_lexical_spec coverage (e131939)

  • Improve parse_syntactic_spec coverage (8bb6551)

  • Install ag and reuse on demand (3c68616)

  • Install jdk in same terminal (33f32a4)

  • Makeabstractstub (0d0238e)

  • Makestub (2b5f9c9)

  • Move build_parsing_table int LL1 (96a9391)

  • Move code gen for sem() into CodeGenerator (46441a5)

  • Move Examples to ourPLCC/languages (#75, a53559e)

  • Move into specparse (#38, 71a7ce4)

  • Move lineparse into specparse (#39, a698706)

  • Move parse_syntactic_spec under parse_spec (8ceb3f1)

  • Remove include and #include (f586fe2)

BREAKING CHANGE: remove include, use %include

BREAKING CHANGE: remove #include, use %include

  • Remove plcc_cli.py and spec_cli.py subcommand dispatcher (517b6be)

  • Remove rep-t and rep-t.bat (#84, cc95bd5)

BREAKING CHANGE: rep-t and rep-t.bat removed. Instead Use rep -t and rep.bat -t.

Closes #81

  • Remove superfluous EOF handling code (#19, b1817b7)

Remove three lines from the printTokens() method in Std/Scan.java relating to EOF since they would never be executed.

BREAKING CHANGE: removes .bat files. Windows users will need to get a Bash/Linux environment. We suggest installing WSL.

In the beginning, all functions that used a regex accepted a default parameter as the regex. I thought it would be nice to allow these to be passed by the caller in case the syntax ever changed. For example...

python def parseTerminal(pattern=r'[A-Z_]+'): ...

This overcomplicates the function, and makes you wonder if there are any call sites that are passing a different regex.

These should be rewriting to something like the following:

python def parseTerminal(): pattern = r'[A-Z_]+' ...

Closes #75

When I moved all errors to plcc/load_spec/errors.py I found 3 implementations of ValidationError. To allow the refactoring tool to work and make the move, I first renamed two of the implementations to ValidationError2 and ValidationError3. Once the move was made, I compared the implementations and found that the original and 2 were the same, so I renamed ValidationError2 (and all its references) to just ValidationError. Then I removed it leaving the original.

ValidationError3's implementation is different. It's constructor takes a different parameter. This commit removes ValidationError3 and has each of its subclass call the superclass constructor with the normal expected parameters. No changes are needed by client code except their import statements had to be adjusted to use ValidationError instead of ValidationError3.

Closes #79

  • Remove version (f7f4f6f)

  • Rename LL1 and sub units for consistency (ce3e762)

  • Rename plccng package to plcc (a282434)

Renames src/plccng → src/plcc, updates all internal imports, renames plccng_cli.py → plcc_cli.py and PlccngCli → PlccCli, updates pyproject.toml (project name, console scripts entry point, coverage module), and confirms 323 tests pass (stale .pyc cache cleared to resolve EOFError on collection).

Test file classification: - Keep as-is (import-only updates, already applied): 37 files lines/parse_from_string_test.py scan/json_formatter_test.py scan/matcher_test.py scan/scan_cli_test.py scan/scanner_test.py scan/sink_test.py scan/source_test.py scan/text_formatter_test.py spec/SpecError_test.py spec/lexical/parse_lexical_test.py spec/parseSpec_test.py spec/rough/parseRough_test.py spec/rough/parse_blocks_test.py spec/rough/parse_dividers_test.py spec/rough/parse_from_lines_test.py spec/rough/parse_includes_test.py spec/rough/resolve_includes_test.py spec/semantics/parse_code_fragments_test.py spec/semantics/parse_semantic_spec_test.py spec/semantics/parse_target_locator_test.py spec/semantics/validation_test.py spec/spec_cli_test.py spec/syntax/parse_syntactic_spec_test.py spec/syntax/validations/ll1/Grammar_test.py spec/syntax/validations/ll1/LL1Wrapper_test.py spec/syntax/validations/ll1/build_first_sets_test.py spec/syntax/validations/ll1/build_follow_sets_test.py spec/syntax/validations/ll1/build_parsing_table_test.py spec/syntax/validations/ll1/build_spec_grammar_test.py spec/syntax/validations/ll1/check_left_recursion_test.py spec/syntax/validations/ll1/check_ll1_test.py spec/syntax/validations/ll1/check_parsing_table_for_ll1_test.py spec/syntax/validations/replace_repeating_with_standard_rules_test.py spec/syntax/validations/validate_lhs_test.py spec/syntax/validations/validate_rhs_test.py spec/syntax/validations/validate_syntactic_spec_test.py spec/syntax/validations/validate_terminals_defined_test.py - Migrated (content changes beyond imports): 1 file plcc_cli_test.py (run() call arg updated plccng→plcc, PlccngCli→PlccCli) - Delete later (Task 7b): plcc_cli_test.py covers plcc_cli.py which is scheduled for deletion in Task 7b; tests still pass for now

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Rename project name plccng (#15, d1d063f)

  • Rename shell/ containers/ and consolidate containers (#76, 7d3e69c)

  • Rename stuff (1e356fb)

  • Rename top-level python package to plccng (#20, d45cb2f)

  • Rename ValidationError2 to SpecError (#44, 7e8c115)

  • Reorganize files (ad2f51f)

BREAKING CHANGE: Moves all source files into a subdirectory named src within the PLCC project. The path to this src directory is what the LIBPLCC environment variable must point to, and is also the path that must be added to the PATH environment variable. When upgrading, these environment variables must be manually adjusted to point to the new src directory.

  • Separate parsing from codegen for arbno (90f1a7d)

  • Split and validate rough_spec before parsing (f0dcb9a)

Split the rough_spec into a RoughSpec object that holds attributes for the three distinct sections: lexical, syntactic, and semantic. Add a validation method, which returns a list of ValidationErrors. This will make it easier to parse each individual part later on.


  • Closes #4 * Closes #12

Co-authored-by: Akshar Patel aksharpatel1233@gmail.com

Co-authored-by: Stoney Jackson dr.stoney@gmail.com

We had too many names for the same thing:

  • build * generate * create

Let's use the shorter: "build".

The new ValidationError2 contains a column, and a str() method that prints a standard message. Now we migrate each existing ValidationError to the new one. Once all errors are migrated, we'll collapse the two into a single class.

  • Wip buildStubs (1c4812b)

  • build_first_sets: Remove check for left recursion (11cdbe2)

This clutters the algorithm. We will add this as a separate module.

  • build_first_sets: Remove memoFirst (3c135f0)

memoFirst is an optimization. We don't know that we need it. So it's premature optimization. And Donald Knuth says, "premature optimization is the root of all evil." So it adds obvious complexity without a measurable, significant gain.

  • build_follow_sets: Clean (3d31ae3)

  • build_parsing_table: Clean (0b9c8b6)

  • check_ll1: Integrating (4c10525)

  • Unify types across components. * Remove dependencies and simplify when possible.

  • ci: Fix build failure (#98, 457a505)

Checks were added to prevent folks from breaking their system's Python installation by updating it or adding libraries to it.

Our Dockerfile was doing this. So now we don't. We still make sure that Python 3 is installed. But we don't try to upgrade it or pip.

In the future, we may want to figure out how to use something like venv to install a particular version of Python that PLCC will use, that is independent of the system's Python.

Closes #97

  • docker: Move PLCC-in-Docker to a separate project (#16, c24eb6f)

  • gitpod: Dev ready in first terminal (#100, 02c37f0)

  • gitpod: Testing (#102, 112fe81)

  • Setup GitPod to install dependencies necessary to run tests. - Add scripts in bin/test/ to run various tests. - bin/test/everything.bash runs all the tests.


Closes #101

  • Grammar: Any iterable is a valid form (2bdf42f)

The second parameter to addRule() must be an iterable. With this change, a str passed as a second parameter would result in each character being treated as a symbol. If this was not the intent of the programmer, then this is an error. However, this error should be detected by unit tests.

  • Grammar: Let set detect invalid symbols (d8e69ca)

If Grammar is passed an invalid symbol, Python's set will detect it and raise a TypeError. We don't need an extra layer of code to detect and translate these errors into a different exception.

Note, we would need this extra layer of code if this was a user error that we were trying to detect and report to the user. But this is an internal programmer error that should be detected and reported by unit tests.

  • Grammar: Let set detect invalid symbols (568d20c)

If Grammar is passed an invalid symbol, Python's set will detect it and raise a TypeError. We don't need an extra layer of code to detect and translate these errors into a different exception.

Note, we would need this extra layer of code if this was a user error that we were trying to detect and report to the user. But this is an internal programmer error that should be detected and reported by unit tests.

  • Grammar: Remove generate_grammar() (c530f44)

Grammer is a data structure (and not a functional unit), and generate_grammar does not provide any additional functionality. So delete generate_grammar().

  • Grammar: Simplify and clarify (ac60fc4)

  • Replace str with object in all public methods. * Remove nonterminals set and use keys from rules instead. * isTerminal(s) is true only if s has been seen and is not a nonterminal. * General cleanning and reorganizing.

  • load_rough_spec: Remove types, imports, and params (#24, 393e99e)

  • make: Use ExitStack in _run_or_die and document stderr passthrough (e3c85cd)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parse_rough: Removes the concept of a rough Spec. (f5f2311)

  • parse_spec: Massive reorganization (#37, 7ec7951)

  • Rename many components. * Colocate validators with related components. * Rewrite tests as needed.

  • Extract lineparse as a separate reusable module. * Store structures and errors in separate modules and colocate with code that constructs them. * Split validators making them more independent. * In lex spec, regex is delimited by any character the user chooses. But there are no escape sequences.

  • parser: Extract _path_dirs and _is_executable helpers to match lang/list.py style (8f2fa47)

  • scan: Retire old scan package and stale tests (29e18a3)

  • spec: Improve interface (#74, b160a8f)

  • spec.lexical: Clean imports (#52, d6090e6)

  • spec.lexical: Make single entry parse_lexical (#51, 2c4a4f3)

  • spec.lexical: Redesign (#54, 9d675d4)

  • parseLexicalSpec now returns a spec and a list of errors. * Parser performs validations. * All tests are performed on top-level parseLexicalSpec. * Errors now accept an index or column; if index given column=index+1.

  • spec.lexical: Remove type annotations (#53, 4cd0d90)

  • spec.lines: Single entry parseLines (#55, 43a12b0)

  • spec.rough: Add handler param to parse_blocks (#46, 6bb8204)

The default handler raises an exception (existing behavior).

If a handler is passed, and no closing %%% is found, then parse_blocks produces a Block containing all of the lines from the opening to the end of the file, plus an additional line that parse_blocks creates to represent the closing of the block.

  • spec.rough: Add handler param to parse_from_* (#47, c08b2bf)

This completes our refactor to add handler param to spec.rough. Callers can now pass a handler callback to parse_from_* functions. The handler is called for each error encountered during the processing. If the handler raises and exception, then processing is halted and the exception is raised. Otherwise the parser does its best to continue.

python from plccng.spec.rough import parse_from_string results = list(parse_from_string(..., handler=lambda e: print(e)))

There are currently two possible errors when parsing the rough. CircularIncludeError and UnclosedBlockError. When a CircularIncludeError is encountered, the handler is called, the Include is skipped, and processing continues. When an UnclosedBlockError is encountered, the handler is called, a closing is created to finish the Block, and processing continues.

In the future, when new errors are added, the creator must decide how processing can continue when that error is detected.

  • spec.rough: Add handler param to resolve_includes (#45, 52d7cca)

Currently rough raises exceptions when errors found. Instead we want to hand back a list of errors during processing, and to try to continue processing as much as possible.

But rough is implemented as a composable set of generator returning functions. It doesn't make sense for it to return a list of errors along with a generator, because the error list would always be initially empty; and the error list would fill as the generator is expanded. This would be confusing and would likely lead to complicated error prone code in clients.

Instead, we'll add an optional callback parameter to each parse function. This callback will be called and passed an error object each time an error is detected. Assuming the callback doesn't raise an exception, processing will continue after the callback returns. This will allow clients to choose how to handle errors.

This commit is the first step along this path. It adds a handler callback parameter to resolve_includes. For example, a client can collect errors during processing but allow processing to continue as follows.

```python errors = [] generator = resolve_includes(..., handler=lambda e: errors.append(e)) ````

If a handler is not provided, resolve_includes raises the first error it encounters (the current behavior).

  • spec.rough: Migrate CircularIncludeError to SpecError (#48, 8ae43f5)

  • spec.rough: Migrate UnclosedBlockError to SpecError (#49, 9230b07)

  • spec.rough: Rename entry parseRough (#56, b7ed88d)

  • spec.rough: Simplify interface (#50, 2354224)

Now there's just parse_rough. parse_rough takes a string or a list of Lines and returns a rough and a list of errors.

rough, errors = parse_rough([])

You can also pass a file path (str) and a startingLineNumber (int).

  • tests: Split tests into multiple files (3bbdd57)

  • tree: Drop 'error' from children kind enum; errors go to stderr per §17.9 (7e30963)

  • tree: Rewrite plcc-tree as parser dispatcher (--ll1, --parser) (7fca6ce)

Replaces the old pass-through stub (--spec) with a dispatcher that invokes plcc-parser-{kind} plugins, defaulting to plcc-parser-table. Updates all affected BATS tests to use the new --ll1 interface.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Testing

  • Add -c option to plccmk (bc2f715)

  • Add -n to parse and update expected output (b47b390)

  • Add initial tests (884ea96)

tests.sh needs plcc and bats installed to run.

If you have Docker installed you can run theme as follows:

./shell/build ./shell/run ./tests.sh exit

  • Add null entry_point and session-continuation acceptance tests (1aad646)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • Add script to run ourPLCC/languages' tests (9329cdf)

  • Allow local run of min-max test (#67, cd8b9fe)

We got min-max test working in CI/CD. But developers should not have to push code just to run this important test. This commit allows developers run an equivalent test locally.


Closes #103

Run tests on minimum and maximum versions of Python and Java. Maximum versions are the latest, stable releases of each. Minimum versions are currently:

  • Python: 3.5.10 (as identified with pyenv) * Java: 11.0.21-tem (as identified with sdkman)

Closes #64 Closes #63

  • Print headers (56b9a49)

  • arbno: Add trivial-arbno.plcc fixture (3415618)

  • bats/commands: Add black-box CLI tests for all Level 0 commands (1f88d90)

Creates 10 BATS test files covering plcc-spec, plcc-tokens, plcc-model, plcc-tree, plcc-lang-list, plcc-lang-emit, plcc-lang-build, plcc-plantuml-emit, plcc-make, and plcc-skeletons. Also adds a plantuml_only.plcc fixture to enable plcc-make tests without requiring the Java emitter.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • bats/e2e: Add end-to-end happy path and error propagation tests (43113b6)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • bats/integration: Add adjacent pipeline pair integration tests (338c15d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • build_bollow_sets: Up coverage, add acceptance tests (a3e939f)

  • Add a test to cover case when follows of subsequent symbols all contain epsilon, and so follows then includes parent's follows.

  • In code, removed a test for symbol being epsilon. This shouldn't be possible because Grammar rules do not contian a symbol for epsilon; epsilon is represented by an empty production. However, a symbol IS still used for first sets, and Grammar does hold a symbol for use in first sets.

  • corpus: Add ARRAY grammar to Java corpus (6b20d1c)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add BF grammar to Java corpus (435ea0f)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add GINGER grammar to Java corpus (d39fd31)

  • corpus: Add HANDLER grammar to Java corpus (8e34492)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add INFIX grammar to Java corpus (79aca54)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add LAMBDA grammar to Java corpus (9d50505)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add LAMBDAQ grammar to Java corpus (755e80e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add languages-java e2e corpus infrastructure (6f8c10a)

  • corpus: Add LIST grammar to Java corpus (1365f4a)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add LON grammar to Java corpus (0ca5b19)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add LON2 grammar to Java corpus (7b7820e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add LONN grammar to Java corpus (28f3f25)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add NAME grammar to Java corpus (935a0af)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add NEED grammar to Java corpus (d61f4b7)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add OBJ grammar to Java corpus (3171ee5)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add PROP grammar to Java corpus (60418fc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add RANDSCONT grammar to Java corpus (8383c59)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add REF grammar to Java corpus (2521b9e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add REFCONT grammar to Java corpus (737cbf9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add SET grammar to Java corpus (d4af882)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add THREADCONT grammar to Java corpus (7d425ac)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add TYPE0 grammar to Java corpus (e3993b9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add TYPE1 grammar to Java corpus (6e97e43)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add V0 grammar to Java corpus (a60f034)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • corpus: Add V1 grammar to Java corpus (44adbf9)

  • corpus: Add V2 grammar to Java corpus (427f9fb)

  • corpus: Add V3 grammar to Java corpus (6ab5a04)

  • corpus: Add V4 grammar to Java corpus (486fd66)

  • corpus: Add V5 grammar to Java corpus (fb39780)

  • corpus: Add V6 grammar to Java corpus (8b88089)

  • e2e: Add debug statements (d12e47b)

  • e2e: Add plcc-rep.bats end-to-end REPL acceptance tests (f265e7e)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • e2e: Add trivial-arbno.plcc end-to-end tests for plcc-rep (3026b60)

Also fix two pipeline bugs found while driving the tests: _count_rules in table_cli.py crashed on list-valued arbno children, and rep.py skipped evaluation when stdin was empty/whitespace-only, preventing arbno grammars from returning [] for zero-item input.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • e2e: Fix test isolation in trivial-full e2e test (b3203f3)

  • e2e: Improve portability of mktemp (a86261f)

  • e2e: Update smoke test for diagram pipeline and plcc-plantuml-emit retirement (c68e4ea)

  • Replace plantuml-emit-based happy-path.bats with diagram-pipeline tests - Fix trivial.plcc: remove trailing bare % that caused spurious Java semantics section - Update packaging.bash to verify plcc-diagram/plcc-diagram-list entry points instead of retired plcc-plantuml-emit

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • e2e: Verify plcc-make produces output for all three language plugins (adca7fd)

  • fixtures: Add arith.plcc arithmetic evaluator grammar (f15de11)

  • fixtures: Add input file, Java, Python, and full trivial grammars for skeleton update (387a541)

  • fixtures: Add trivial grammar and input (f7502c7)

  • fixtures: Add trivial-plantuml.plcc for Phase 1 smoke test (c8bf7b9)

trivial.plcc has an implicit Java semantics section (bare % defaults to Java) which causes plcc-make to fail in Phase 1 where plcc-java-emit is not installed. The new fixture uses only % diagram PlantUML so the smoke test exercises the full plcc-make pipeline without requiring Java.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • integration: Add python-emit.bats integration tests (bd2d4dc)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • integration: Add spec|ll1 and ll1|tree pipeline pair tests (0b601e9)

  • java: Update trivial-java fixture and command tests for real emitter (444950d)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • java-emit: Add integration tests for full emit→build→run pipeline (c8f7ded)

  • model: Add failing test for _extract_body trailing newline bug (851aa11)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • model: Add fragment pass-through tests for build_model (4cc4279)

Covers _compute_kind (body/file/modifier kinds), _extract_body (%%% stripping, indentation preservation), and _build_fragment integration via build_model.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • OBJ: Add OBJ compilation test (1ae4eb4)

  • packaging: Add plcc-lang-list and plcc-diagram-list smoke checks (8c38364)

  • parse_blocks: Add regression test for trailing-space %%% delimiter (17155b9)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add tree-shape assertions for plcc-parser-table and ll1-tree integration (56bb4d3)

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

  • parser: Add unit test for error record passthrough in plcc-parser-table (5b0f611)

  • validate_rhs: Valid alternate name (a19def3)