feat: frontier/expected-set for error localization (#467 step 3)#470
Open
SJrX wants to merge 1 commit into
Open
feat: frontier/expected-set for error localization (#467 step 3)#470SJrX wants to merge 1 commit into
SJrX wants to merge 1 commit into
Conversation
…step 3)
parse() only returns successful matches, so when a value is malformed the failing
paths vanish and we lose how far we got — e.g. for "AF_INET, AF_INET6" the outer
Seq(..., EOF()) drops the partial path when EOF fails at the comma, and the
reported furthest collapsed to 0.
Add a Frontier: a high-water-mark recorder threaded through parse() (one extra,
defaulted parameter so the 2-arg call still works). Every leaf matcher (terminals
and EOF) reports itself when consulted at an offset; the Frontier keeps only the
deepest offset reached and the set of matchers expected there. validate() now
reports SyntaxError(furthest, expected) from it.
This is one mechanism with two payoffs:
- error localization: "AF_INET, AF_INET6" now reports furthest=7 (the comma) and
expected={whitespace, end-of-input};
- the seed of completion (#343): the expected set at a position is exactly "what
could come next here" — a new test shows the empty value expects "none", "~",
or an address-family name.
Combinators thread the shared frontier into their children; only the leaf matchers
record. The old SyntacticMatch/SemanticMatch engine and GrammarOptionValue are
untouched; full suite green.
Refs #467 #345 #343
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.
What
Adds a frontier: a high-water-mark recorder threaded through
parse()so that even when no path matches, we know where parsing got stuck and what was expected there.The problem it fixes
parse()only returns successful matches, so a malformed value's failing paths vanish and we lose how far we got. ForAF_INET, AF_INET6against the real grammarSeq( …family-list… , EOF() ):AF_INETand stops at the comma (offset 7);SeqtriesEOF()at 7, which matches nothing → the wholeSeqyields an empty sequence;validate()'smaxOfOrNull { it.end }over an empty sequence →furthest = 0.The "we reached offset 7" fact existed for a moment and was thrown away. (This is the limitation that was pinned with a
furthest == 0assertion in #469.)How the frontier works
A small mutable
Frontierrides along throughparse()(one extra parameter, defaulted so the 2-arg call still works). Every leaf matcher — the terminals andEOF— reports itself when consulted at an offset. The frontier keeps only the deepest offset reached and the set of matchers wanted there. Combinators just thread the same instance into their children; they don't record.validate()reads it:SyntaxErrornow carries(furthest, expected).One mechanism, two payoffs
AF_INET, AF_INET6now reportsfurthest = 7(the comma) andexpected = {whitespace, end-of-input}. The pinned== 0assertion from feat: add parse() (list-of-successes) to the grammar combinators (#467 step 2) #469 is flipped to== 7.expectedcontaining the address-family names (FlexibleLiteralChoiceTerminal) andnone/~(LiteralChoiceTerminal) — i.e. the completion list at offset 0.Scope / notes
SyntacticMatch/SemanticMatchengine andGrammarOptionValueare untouched; full suite is green.Set<Combinator>(soEOFcan appear alongside terminals); a real completion contributor would map these to lookup strings (e.g. aLiteralChoiceTerminal's choices) — that's the next step, not this one.Refs #467 #345 #343
🤖 Generated with Claude Code