Repository navigation
ParseTable carrier: prepare grammar once above the assemble fold (validate-once) - #6569
Merged
Merged
Conversation
…idate-once) grammar_validate_for_parse (5 whole-grammar checks + FIRST/nullable analysis, ~9.2s, all pure fns of the invariant grammar) ran inside parse_module — so a door call over a K-module import closure re-validated the SAME grammar K times, and compute_grammar_first_analysis ran twice per module (ambiguity check + parse_table_for_production). The cache-interface fields on ParseTableRealization (grammar_digest/materialization) were inert; the backend lookup is Miss-stubbed, so this was a recompute-per-module bug, not a missing cache. Fix (correctness by construction): PreparedGrammar carrier + prepare_grammar (well-formed + validate + analyze, once) hoisted ABOVE fold_list in program_assembly_fold_ingest; parse_module_prepared reuses it per module. parse_module / parse_production / parse_table_for_production / read_to_normalized_root keep backward-compatible wrappers (prepare then parse). Empty-ingest guarded so zero modules never pay the one-time prepare. Only fold_step's signature changed (internal, no external callers). Behavioral equivalence proven by execution: ledger histogram witness green with IDENTICAL causes (determinism->fact_density, error_primitives->resolve_unbound, bit->resolve_ambiguous_export); parse-table amortization green (2-file fold = one preparation, ~9.2s not ~18.4s); new empty-ingest guard witness green (4ms, no prepare). Cross-call content-addressed memo (across door calls) is the follow-up, gated on wiring the currently Miss-stubbed cache backend. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ParseTable carrier — prepare the grammar once, not per module
Finding
grammar_validate_for_parseruns five whole-grammar checks (undefined-nonterminals, duplicate-productions, left-recursion, choice-ambiguity, nullable-ambiguity) plus the FIRST/nullable analysis — all pure functions of the invariant 841-row grammar — insideparse_module. So a door call over a K-module import closure re-validated the same grammar K times, andcompute_grammar_first_analysisran twice per module (once for the ambiguity check, once inparse_table_for_production).The
ParseTableRealizationcarrier already hadgrammar_digest/nullable_set/first_rows/materializationslots — but the cache lookup isMiss-stubbed (resolve_cache_miss), so nothing was reused. This was a recompute-per-module bug, not a missing cache.Measured (release
claim_batch, wet,std.determinism): one parse+normalize ≈ 14.7s, of whichgrammar_validate_for_parsealone ≈ 9.2s, re-paid every module.Fix (correctness by construction)
A
PreparedGrammarcarrier +prepare_grammar(well-formed check + validate + analyze, once) hoisted abovefold_listinprogram_assembly_fold_ingest;parse_module_preparedreuses it for every module. A door call now validates its closure once, not K times — structurally, no timing gate.parse_module/parse_production/parse_table_for_production/program_assembly_read_to_normalized_rootkeep backward-compatible wrappers (prepare ∘ parse). Only the internalfold_stepsignature changed (no external callers).Proven by execution
determinism→fact_density_hollow_alias_locus,error_primitives→resolve_reason_unbound_symbol,bit→resolve_ambiguous_export).parse_table_grammar_memo_multi_file_ingest_parsesgreen; a 2-file fold costs ~9.2s = one preparation (not ~18.4s = two).Follow-up (not this PR)
Cross-call content-addressed memo (sharing the prepared grammar across door calls) is gated on wiring the currently
Miss-stubbed cache backend. Draft until by-execution sign — load-bearing parse stage.🤖 Generated with Claude Code