Repository navigation
Count end of input as one more symbol read (3.8.1) - #223
Merged
Merged
Conversation
3.8 made [eof] tie with the accept of the state it is read from, so that an earlier rule matching [s] beat a later rule matching [s, eof]. With [s] empty, that is a rule matching the empty string before the [eof] rule, a common shape for a lexer loop: | Star (Sub (any, '@')) -> token buf | eof -> () At end of input the first rule now won, forever. pds does this, and no longer terminated. Go back to what every earlier release did: a match that reads end of input is longer than one that stops before it, between rules and within a rule. Any configuration of a state may read end of input, not only those preceding its first final one. End of input is still read once. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mseri
pushed a commit
to ocaml/opam-repository
that referenced
this pull request
Oct 6, 2026
CHANGES: ## Bug fixes - End of input counts as one more character read, as it did before 3.8: a rule matching `s, eof` beats an earlier rule matching `s`. 3.8 let the earlier rule win, so a lexer with a rule matching the empty string before its `eof` rule looped forever at end of input (ocaml-community/sedlex#223)
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.
3.8 made
eoftie with the accept of the state it is read from (#211), so anearlier rule matching
sbeat a later rule matchings, eof. Withsempty,that is a rule matching the empty string listed before the
eofrule, a commonshape for a lexer loop:
At end of input the
Starrule now won with an empty lexeme, forever. Foundthrough the opam-repository CI of the 3.8 release
(ocaml/opam-repository#30869):
pdshas this lexer, and every package runningpdsat build time was killed (hll,merlin-of-pds,revops,lua_pattern).This goes back to what every release before 3.8 did: end of input counts as
one more symbol read. A match that reads it is longer than one that stops just
before it, between rules and within a rule; rule order only decides between
matches of the same length under that count. The rest of #211 stays: end of
input is read once, so
Plus eofandStar ('a' | eof)terminate andeof, eofdoes not match.Changes:
Sedlex.transitions: every configuration of a state may read end of input,not only those preceding its first final one. The ppx and the runtime are
unchanged: an
eofarm still returns its rule directly, which is soundsince that match is preferred over the state's own accept.
test/basic.ml:eof_rule_prioritybecomeseof_longest_matchand gainsthe nullable-rule-before-
eofloop, twoeofrules in order, and a captureoverridden by the
eofrule;eof_zero_width_tie_within_rulegains abranch reading
eofafter the leftmost one.Not covered here: the oracle of #202 still implements the 3.8 rule.
🤖 Generated with Claude Code