Implement fn:parse-ietf-date with a hand-written parser#154
Open
ajbufort wants to merge 1 commit into
Open
Conversation
The previous implementation delegated to chrono's parse_from_rfc2822, which rejects most of the formats the spec requires (asctime layout, two-digit years, named timezones, single-digit fields, liberal whitespace) and accepts some it forbids (three-digit years). 51 conformance tests were filtered as known failures. Following the direction in Paligo#36, this is a hand-written recursive descent parser for the exact grammar in XPath F&O 3.1 section 9.9.1, adding no parser-library usage to xee-interpreter. Two deliberate details: - Edge whitespace is exactly the grammar's S set (x09/x0A/x0D/x20); the old stub trimmed all Unicode whitespace, so e.g. a trailing U+00A0 now raises FORG0010. Pinned by tests. - 24:00 requires a completely zero time; a nonzero fractional digit beyond nanosecond precision still counts as nonzero. All 105 tests in fn/parse-ietf-date.xml and the 5 fo-test-fn-parse-ietf-date tests in misc now pass: the XPath conformance check goes from 20221 to 20272 passed, with the filters updated and no regressions in the XPath or XSLT suites. A deterministic mutation-fuzz test guards against panics on arbitrary input. Fixes Paligo#36 Co-Authored-By: Claude Fable 5 <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.
Fixes #36.
The previous implementation delegated to chrono's
parse_from_rfc2822, which rejects most of the formats the spec requires (the asctime layout, two-digit years, named timezones, single-digit fields, liberal whitespace) and accepts some it forbids (three-digit years). 51 conformance tests were filtered as known failures.Following the direction in #36, this replaces it with a hand-written recursive descent parser for the exact grammar in F&O 3.1 section 9.9.1, adding no dependencies to
xee-interpreter.What's covered
datespec S timeand asctime), optional/ignored dayname, comma and hyphen separator forms0070)UT/UTC/GMT/EST/...), offsets with and without colons (-05,-05:,-5:00,-500,-0500), the parenthesized-and-ignored tzname after an offset, and the +/-14:00 range check24:00[:00]rolling over to the next day, calendar validation (Feb 29, day 00/32), withFORG0010on any violationx09|x0A|x0D|x20count as whitespace, per the grammar'sSproductionTesting
library/ietf_date.rscover the spec examples, the whole conformance truth table, and edge cases the suite doesn't reach (offset boundary+14:00/+14:01, half-hour offsets in every lexical form, tab/CR/LF whitespace,24:00:00.5and a nonzero fraction beyond nanosecond precision, leap seconds, non-ASCII whitespace at the edges and interior, lexical year extremes0001/9999including 24:00 rollover)fn/parse-ietf-date.xmland the 5fo-test-fn-parse-ietf-datetests inmiscnow pass: the XPathcheckrun goes from 20221 to 20272 passed, filters updated via theupdate/checkflow from hacking.md, no regressions in the XPath or XSLT suites (verified in release and in debug mode, as CI runs it)cargo fmt,cargo clippy --all-targets --all-features -- -D warnings, andcargo testare all cleanNotes
trim()ed all Unicode whitespace before parsing; this parser accepts exactly the grammar'sSset (x09|x0A|x0D|x20) at the edges, so e.g. a trailing U+00A0 is nowFORG0010where it previously parsed. I read the spec's whitespace note as deliberate about those four characters, so the stricter behavior is pinned by tests - easy to relax if you'd rather keep the lenient trim.parse-ietf-date("Dec 31 24:00 9999")correctly yields the year-10000xs:dateTime, which exposes a pre-existing serializer quirk: five-digit years print with a leading+(+10000-...), which the engine's ownxs:dateTimecast then rejects. That's reachable on main viaxs:dateTime("10000-01-01T00:00:00Z")too - happy to file it separately.The parser lives in its own module (
xee-interpreter/src/library/ietf_date.rs) withparse_ietf_dateindatetime.rsdelegating to it - happy to restructure if you'd prefer it inline or elsewhere.Generated with Claude Code