Marks every step of the port plan done and adds a status section: the port is integrated as PureYAML's only parser, verified byte-for-byte against libyaml on 307/308 cases, and scores 275/308 on the canonical event gate, ahead of libyaml's own 252 and the prior hand-rolled parser's 267.
4.1 KiB
Faithful libyaml port
Status: complete and integrated
The port is finished and is now PureYAML's only parsing engine. Every step
below has landed, the hand-rolled approximation has been deleted, and parseEvents,
parseStreaming, and parseStreamStreaming all run on the port.
- Faithfulness: verified byte-for-byte against the libyaml reference event
dumper across all 308 vendored valid cases. The port matches libyaml on 307; the
single difference (
L24T/01) is the port being more correct than libyaml. - Conformance (canonical
test.eventgate, of 308): libyaml itself scores 252, the old hand-rolled parser scored 267, and the port scores 275 after closing real YAML 1.2 gaps libyaml lacks (reserved directives ignored with a warning, newer%YAMLminor versions, multi-line flow keys, bare documents after..., tab-only blank lines, JSON UTF-16 surrogate-pair\uescapes, fullns-anchor-charanchor/alias names). - Integration boundary (
Sources/Parsing/Parser.Events.swift): converts libyaml's 0-based marks to PureYAML's 1-based, translates scanner/parser errors to the diagnostic-awareParseError, and enforces a 64-level nesting bound so deep input throwsnestingTooDeeprather than overflowing the recursive composer.
Remaining open gaps and their clusters are tracked by knownEventGaps in
Tests/CanonicalEventConformanceTests.swift.
Why
PureYAML's original scanner is a hand-rolled approximation of libyaml's
algorithm. Its bugs (block-mapping indentation, simple keys, empty values) are
the gap between that approximation and the proven reference. Rather than keep
patching the approximation, the scanner is being re-derived as a faithful,
function-by-function Swift port of libyaml's scanner.c, with the parser to
follow from parser.c. Correctness is then by construction: each Swift function
mirrors its C counterpart and is verified against libyaml directly.
The constraint that PureYAML ships no C or generated runtime is preserved: this is a translation of the algorithm into pure Swift, not a binding to libyaml.
Reference and verification
- Source of truth:
PureYAMLResearch/Sources/CYaml/src/scanner.candparser.c(libyaml 0.2.5). - Oracle: the libyaml differential harness (
scratchpad/run_events.ccompiled against the sameCYamlsource emits the canonical yeast event stream). Each ported stage is checked token-for-token / event-for-event against it, in addition to the vendoredtest.eventsuite ground truth. - The port lands as a parallel implementation under
PureYAML.Parsing.LibYAMLand is only swapped in for the current scanner once it matches the reference on the full suite and the real-world corpus, so the working parser is never regressed mid-port.
Order (each step verified before the next)
- Indent engine (DONE):
yaml_parser_roll_indent/yaml_parser_unroll_indentand theindentsstack. A block collection opens only when content is strictly more indented than the current level, which fixes the- a:/ same-columnb:bug by construction. Implemented inSources/Parsing/LibYAML.IndentEngine.swift, unit-tested inTests/LibYAMLIndentEngineTests.swift. - Simple-key mechanism (DONE):
save_simple_key,remove_simple_key,stale_simple_keys, thesimple_keysstack andsimple_key_allowedflag. - Token-fetch core (DONE):
fetch_more_tokens,fetch_next_token,scan_to_next_token, and thefetch_*dispatch (fetch_key,fetch_valuewith its empty-scalar and roll-indent logic,fetch_block_entry,fetch_flow_*, document indicators, stream start/end). - Scalar scanners (DONE):
scan_plain_scalar,scan_flow_scalar,scan_block_scalar(+ breaks),scan_anchor,scan_tag,scan_directive. - Reader (DONE): scalar-based
Readerwithpeek/skip/skipLineand marks. - Parser (DONE):
parser.cported to compose events from the token stream. - Integration (DONE):
parseEvents/parseStreamrun on the port and the approximation has been deleted; the canonical event gate and libyaml differential are green with zero regressions.