Skip to content

feat: port the ISC grammar to the parsanol .parg portable DSL (WO13) - #829

Merged
ronaldtse merged 3 commits into
mainfrom
worktree-agent-a2b35cbe6fb8ac650
Nov 3, 2026
Merged

ronaldtse merged 3 commits into
mainfrom
worktree-agent-a2b35cbe6fb8ac650

Conversation

@ronaldtse

Copy link
Copy Markdown
Contributor

Summary

  • WO13: the full ISC grammar ported to the parsanol .parg portable DSL (grammar/isc.parg), mirrored rule-for-rule from the normative parsanol-Ruby concerns (lib/interscript/isc/grammar/concerns/)
  • Validation harness tools/isc-parg-check/ (Rust, parsanol-rs): parses the ENTIRE corpus — 318/318 maps/ + 1/1 maps-staging at the time of the run — with verdict parity against the Ruby DSL, plus 7 construct fixtures and 4 negative cases (all rejected)
  • grammar/ISC-PARG-GAPS.md documents the four (non-blocking) deviations: longest-first keyword alternation, dead concern rules omitted, folded lexical helpers, and the field_value repeat-binding note — nothing proved inexpressible
  • Unblocks parsanol-codegen emission of the rs/py/ts runtimes (WO13-15)

Test plan

  • 318/318 corpus files parse via parsanol-rs with Ruby-DSL verdict parity
  • 7/7 construct fixtures parse; 4/4 negatives rejected
  • Existing Ruby test suite green (no Ruby code changed)

grammar/isc.parg mirrors lib/interscript/isc/grammar/concerns/*.rb
rule-for-rule: system/metadata/notes/relations/tests/aliases/
dependencies/stages, both sub forms, before/after/not_* constraints,
any(range/set/alias/item), capture/maybe/some, ref(N), the strict
comment_item, and the corpus escape rulings (\uXXXX, \U 4..8, lone \U).
Root pins full-input consumption with an explicit !utf.
tools/isc-parg-check compiles the .parg through parsanol-rs
(parse_grammar_with_mode + compile_entry_mode, edition v1) and parses
corpus files with the portable engine, reporting failure wires
(offset/line/col/expected) on misses. --expect-reject runs the negative
corpus: truncated rule string, unbalanced brace, stray stage identifier
(strict parse), trailing garbage.

Verdicts are at parity with the Ruby DSL on all runs: 319/319 corpus
files parse (318 maps/ + 1 maps-staging/), 4/4 negatives and 7/7
construct-coverage fixtures (stage(name) paren form, sequence,
title_case kwargs, separate separator, kwarg funcall, run map.N.stage.M,
relations, specification/provenance comma lists, aliases, capture+ref,
CJK/emoji string content) match DSL accept/reject exactly.
No concern construct proved inexpressible. The file records the one
forced deviation (keyword alternation reordered longest-first for the
parg shadow lint — semantics-preserving under negative lookahead), the
omitted dead concern rules (authority/source_spelling/target_spelling/
identifying/name fields are unreachable from metadata_field), the
field_value repeat-binding trap the corpus caught (din-hye), and the
any-matches-newlines semantics multiline descriptions depend on.
@ronaldtse
ronaldtse merged commit 4e601c5 into main Nov 3, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant