feat(parsing): add authoritative canonical-event conformance gate

The conformance number was measured against a lossy oracle: the JSON
projection (in.json) discards anchors, tags, and scalar styles, and exists
for only about half the cases, so "passing" often meant only "parse did not
throw". Measured against the official suite's own test.event event streams,
the true exact conformance is 254 of 308 valid cases (40 emit a wrong event
stream, 14 false-reject), well below the JSON-proxy figure.

Add a canonical-event gate (Tests/CanonicalEventConformanceTests.swift) that
serializes the parser's events into the yaml-test-suite yeast format and
compares them exactly to each case's test.event, checking anchors, tags,
scalar styles, flow vs block, and explicit document markers, for every valid
case. The gate records the gap set and fails on any regression or unrecorded
fix. All 402 test.event files are vendored alongside their inputs.

To make the comparison exact, the parser Event model now records whether a
document boundary was explicit (documentStart/documentEnd carry an `explicit`
flag), distinguishing `---`/`...` from an implicit boundary. This resolves 89
cases that were previously correct but unverifiable without normalization.

No parser behavior changed; this is measurement and model fidelity. The 40
wrong-event and 14 false-reject cases are the real remaining gaps, to be fixed
against this gate.
This commit is contained in:
Mihaela Mihaljevic 2026-06-24 01:24:24 +02:00
parent ce0585f77e
commit e8987e4cfd
410 changed files with 4020 additions and 33 deletions

View File

@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Add an authoritative canonical-event conformance gate. The parser's event
stream is serialized into the official YAML test suite event (yeast) format and
compared exactly to each case's vendored `test.event`, which checks anchors,
tags, scalar styles, flow vs block, and explicit document markers for every
valid case (including the roughly half with no `in.json` projection). This
replaces the JSON-projection oracle, which was lossy: measured against ground
truth, 254 of 308 valid suite cases emit exactly correct events (40 emit a
wrong event stream, 14 false-reject), where the JSON proxy had reported a higher
figure. The gate records the gap set and fails on any regression or unrecorded
fix. All 402 cases' `test.event` files are vendored alongside their inputs.
### Changed
- Record whether a document boundary was explicit in the parser `Event` model
(`documentStart`/`documentEnd` now carry an `explicit` flag), so a `---`/`...`
marker is distinguished from an implicit boundary. This is required for exact
canonical-event comparison and resolves 89 cases that were previously correct
but unverifiable.
### Fixed
- Make the YAML test suite conformance gate comprehensive and repair the

View File

@ -2,8 +2,8 @@ extension PureYAML.Parsing {
enum Event: Equatable, CustomStringConvertible {
case streamStart(mark: Mark)
case streamEnd(mark: Mark)
case documentStart(mark: Mark)
case documentEnd(mark: Mark)
case documentStart(explicit: Bool, mark: Mark)
case documentEnd(explicit: Bool, mark: Mark)
case sequenceStart(anchor: String?, tag: String?, style: CollectionStyle, mark: Mark)
case sequenceEnd(mark: Mark)
case mappingStart(anchor: String?, tag: String?, style: CollectionStyle, mark: Mark)
@ -17,10 +17,10 @@ extension PureYAML.Parsing {
"streamStart @\(mark)"
case let .streamEnd(mark):
"streamEnd @\(mark)"
case let .documentStart(mark):
"documentStart @\(mark)"
case let .documentEnd(mark):
"documentEnd @\(mark)"
case let .documentStart(explicit, mark):
"documentStart explicit=\(explicit) @\(mark)"
case let .documentEnd(explicit, mark):
"documentEnd explicit=\(explicit) @\(mark)"
case let .sequenceStart(anchor, tag, style, mark):
"sequenceStart anchor=\(describe(anchor)) tag=\(describe(tag)) style=\(style) @\(mark)"
case let .sequenceEnd(mark):
@ -63,8 +63,6 @@ extension PureYAML.Parsing.Event {
var mark: PureYAML.Parsing.Mark {
switch self {
case let .alias(_, mark),
let .documentEnd(mark),
let .documentStart(mark),
let .mappingEnd(mark),
let .mappingStart(_, _, _, mark),
let .scalar(_, _, _, _, mark),
@ -73,6 +71,9 @@ extension PureYAML.Parsing.Event {
let .streamEnd(mark),
let .streamStart(mark):
mark
case let .documentEnd(_, mark),
let .documentStart(_, mark):
mark
}
}

View File

@ -35,7 +35,7 @@ extension PureYAML.Parsing {
}
return false
}
if case let .documentStart(mark)? = current {
if case let .documentStart(_, mark)? = current {
throw PureYAML.Parsing.ParseError.unsupportedMultiDocumentStream(line: mark.line)
}
_ = try expectStreamEnd()

View File

@ -50,9 +50,9 @@ extension PureYAML.Parsing {
didSeeStreamStart = true
case .streamEnd:
didSeeStreamEnd = true
case let .documentStart(mark):
case let .documentStart(_, mark):
try startDocument(mark: mark)
case let .documentEnd(mark):
case let .documentEnd(_, mark):
try endDocument(mark: mark)
case let .scalar(value, anchor, tag, style, mark):
try consumeScalar(value, anchor: anchor, tag: tag, style: style, mark: mark)

View File

@ -102,9 +102,9 @@ extension PureYAML.Parsing {
}
if !didParseDocument {
let mark = cursor.current?.mark ?? streamStart.endMark
try emit(.documentStart(mark: mark))
try emit(.documentStart(explicit: false, mark: mark))
try appendEmptyDocument(at: mark)
try emit(.documentEnd(mark: mark))
try emit(.documentEnd(explicit: false, mark: mark))
}
let streamEnd = try expect("stream end") { kind in
if case .streamEnd = kind {
@ -127,19 +127,19 @@ extension PureYAML.Parsing {
extension PureYAML.Parsing.TokenEventParser {
mutating func parseDocument() throws {
let startMark = try parseDocumentStartMark()
try emit(.documentStart(mark: startMark))
let (startMark, explicitStart) = try parseDocumentStartMark()
try emit(.documentStart(explicit: explicitStart, mark: startMark))
if cursor.current?.kind.isDocumentEnd == true {
let end = try expect("document end") { $0.isDocumentEnd }
try appendEmptyDocument(at: end.mark)
try emit(.documentEnd(mark: end.endMark))
try emit(.documentEnd(explicit: true, mark: end.endMark))
return
}
if cursor.current?.kind.isDocumentStart == true || cursor.current?.kind.isStreamEnd == true {
try appendEmptyDocument(at: cursor.current?.mark ?? startMark)
try emit(.documentEnd(mark: cursor.current?.mark ?? startMark))
try emit(.documentEnd(explicit: false, mark: cursor.current?.mark ?? startMark))
return
}
@ -154,7 +154,7 @@ extension PureYAML.Parsing.TokenEventParser {
// -- starts a fresh document on the next loop iteration, so emit the
// end here and return rather than demanding a document boundary token.
let end = try expect("document end") { $0.isDocumentEnd }
try emit(.documentEnd(mark: end.endMark))
try emit(.documentEnd(explicit: true, mark: end.endMark))
return
}
if let current = cursor.current, !canEndDocument(at: current) {
@ -165,7 +165,7 @@ extension PureYAML.Parsing.TokenEventParser {
column: current.mark.column,
)
}
try emit(.documentEnd(mark: endMark))
try emit(.documentEnd(explicit: false, mark: endMark))
}
mutating func parseDocumentRootNode() throws -> PureYAML.Parsing.NodeResult {
@ -180,12 +180,12 @@ extension PureYAML.Parsing.TokenEventParser {
return result
}
mutating func parseDocumentStartMark() throws -> PureYAML.Parsing.Mark {
mutating func parseDocumentStartMark() throws -> (mark: PureYAML.Parsing.Mark, explicit: Bool) {
guard cursor.current?.kind.isDocumentStart == true else {
return cursor.current?.mark ?? cursor.previous?.endMark ?? .start
return (cursor.current?.mark ?? cursor.previous?.endMark ?? .start, false)
}
let start = try cursor.advance()
return start?.mark ?? .start
return (start?.mark ?? .start, true)
}
mutating func appendEmptyDocument(at mark: PureYAML.Parsing.Mark) throws {

View File

@ -35,7 +35,7 @@ extension PureYAML.Tagged {
}
return false
}
if case let .documentStart(mark)? = current {
if case let .documentStart(_, mark)? = current {
throw PureYAML.Parsing.ParseError.unsupportedMultiDocumentStream(line: mark.line)
}
_ = try expect("stream end") { event in

View File

@ -0,0 +1,144 @@
import Foundation
@testable import PureYAML
import Testing
/// Authoritative conformance gate: serialize PureYAML's parse events into the
/// official YAML test suite "event" (yeast) format and compare EXACTLY to each
/// case's vendored `test.event`. Unlike the JSON-projection oracle, this checks
/// anchors, tags, scalar styles, flow vs block, and explicit document markers,
/// for every valid case (including those with no `in.json`). No normalization.
@Suite("Canonical Event Conformance")
struct CanonicalEventConformanceTests {
/// Valid suite cases whose event stream PureYAML does NOT yet emit exactly.
/// This is the authoritative gap set: a fix removes an id (and the test fails
/// until it is removed), a regression adds one (and the test fails). Of these,
/// 14 currently throw on valid input and 26 emit a wrong event stream.
static let knownEventGaps: Set<String> = [
// false-rejects (parseEvents throws on valid input)
"57H4", "58MP", "5T43", "6BFJ", "8XYN", "FH7J", "LX3P", "M5C3", "M5DY",
"Q9WF", "SKE5", "UKK6/00", "V9D5", "W5VH",
// wrong event stream (parses, but not the canonical events)
"2SXE", "4ABK", "4FJ6", "4MUZ/02", "652Z", "6CK3", "7BMT", "7FWL", "7ZZ5",
"8G76", "98YD", "9KAX", "AVM7", "CFD4", "CT4Q", "DBG4", "DC7X", "DK95/05",
"HM87/00", "HM87/01", "HS5T", "HWV9", "JEF9/02", "LP6E", "M2N8/00",
"M2N8/01", "M7A3", "NB6Z", "NKF9", "PW8X", "QF4Y", "QT73", "U3XV", "UGM3",
"UV7Q", "VJP3/01", "Y2GN", "Y79Y/002", "ZF4X", "ZK9H",
]
@Test("Every valid case emits canonical events, except the recorded gaps")
func test_canonicalEventConformance() throws {
var observedGaps: Set<String> = []
for testCase in CanonicalEventCorpus.validCases() {
guard let yaml = testCase.input, let expected = testCase.expectedEvents else { continue }
let events: [PureYAML.Parsing.Event]
do {
events = try PureYAML.Parsing.Parser().parseEvents(yaml)
} catch {
observedGaps.insert(testCase.id)
continue
}
let actual = events.map(CanonicalEventCorpus.serialize).joined(separator: "\n")
if actual != expected.trimmingTrailingNewline {
observedGaps.insert(testCase.id)
}
}
let regressions = observedGaps.subtracting(Self.knownEventGaps).sorted()
let fixed = Self.knownEventGaps.subtracting(observedGaps).sorted()
#expect(regressions.isEmpty, "Canonical-event REGRESSIONS (now wrong, were correct): \(regressions.joined(separator: " "))")
#expect(fixed.isEmpty, "Canonical-event cases now FIXED; remove from knownEventGaps: \(fixed.joined(separator: " "))")
}
}
enum CanonicalEventCorpus {
struct Case { let id: String }
static func validCases() -> [Case] {
// Every vendored case that is NOT an error case (no `error` marker).
guard let base = Bundle.module.url(forResource: "yaml-test-suite", withExtension: nil, subdirectory: "Fixtures") else { return [] }
let fileManager = FileManager.default
guard let walker = fileManager.enumerator(at: base, includingPropertiesForKeys: nil) else { return [] }
var out: [Case] = []
for case let url as URL in walker where url.lastPathComponent == "in.yaml" {
let dir = url.deletingLastPathComponent()
let id = dir.path.replacingOccurrences(of: base.path + "/", with: "")
if !fileManager.fileExists(atPath: dir.appendingPathComponent("error").path) {
out.append(Case(id: id))
}
}
return out.sorted { $0.id < $1.id }
}
static func url(_ id: String, _ name: String, _ ext: String?) -> URL? {
Bundle.module.url(forResource: name, withExtension: ext, subdirectory: "Fixtures/yaml-test-suite/" + id)
}
static func serialize(_ event: PureYAML.Parsing.Event) -> String {
switch event {
case .streamStart: "+STR"
case .streamEnd: "-STR"
case let .documentStart(explicit, _): explicit ? "+DOC ---" : "+DOC"
case let .documentEnd(explicit, _): explicit ? "-DOC ..." : "-DOC"
case let .sequenceStart(anchor, tag, style, _): "+SEQ" + (style == .flow ? " []" : "") + props(anchor, tag)
case .sequenceEnd: "-SEQ"
case let .mappingStart(anchor, tag, style, _): "+MAP" + (style == .flow ? " {}" : "") + props(anchor, tag)
case .mappingEnd: "-MAP"
case let .scalar(value, anchor, tag, style, _): "=VAL" + props(anchor, tag) + " " + styleChar(style) + escape(value)
case let .alias(anchor, _): "=ALI *" + anchor
}
}
static func props(_ anchor: String?, _ tag: String?) -> String {
var result = ""
if let anchor { result += " &" + anchor }
if let tag { result += " <" + tag + ">" }
return result
}
static func styleChar(_ style: PureYAML.Parsing.ScalarStyle) -> String {
switch style {
case .plain: ":"
case .singleQuoted: "'"
case .doubleQuoted: "\""
case .literal: "|"
case .folded: ">"
}
}
static func escape(_ value: String) -> String {
var out = ""
for scalar in value.unicodeScalars {
switch scalar {
case "\\": out += "\\\\"
case "\t": out += "\\t"
case "\n": out += "\\n"
case "\r": out += "\\r"
case "\u{08}": out += "\\b"
case "\u{00}": out += "\\0"
default: out.unicodeScalars.append(scalar)
}
}
return out
}
}
extension CanonicalEventCorpus.Case {
var input: String? {
guard let url = CanonicalEventCorpus.url(id, "in", "yaml") else { return nil }
return try? String(contentsOf: url, encoding: .utf8)
}
var expectedEvents: String? {
guard let url = CanonicalEventCorpus.url(id, "test", "event") else { return nil }
return try? String(contentsOf: url, encoding: .utf8)
}
}
private extension String {
var trimmingTrailingNewline: String {
var copy = self
while copy.hasSuffix("\n") {
copy.removeLast()
}
return copy
}
}

View File

@ -0,0 +1,22 @@
+STR
+DOC
+SEQ
+MAP
=VAL :name
=VAL :Mark McGwire
=VAL :hr
=VAL :65
=VAL :avg
=VAL :0.278
-MAP
+MAP
=VAL :name
=VAL :Sammy Sosa
=VAL :hr
=VAL :63
=VAL :avg
=VAL :0.288
-MAP
-SEQ
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
+MAP
=VAL :foo
=VAL :bar

View File

@ -0,0 +1,33 @@
+STR
+DOC
+MAP
=VAL "top1
+MAP
=VAL "key1
=VAL &alias1 :scalar1
-MAP
=VAL 'top2
+MAP
=VAL 'key2
=VAL &alias2 :scalar2
-MAP
=VAL :top3
+MAP &node3
=ALI *alias1
=VAL :scalar3
-MAP
=VAL :top4
+MAP
=ALI *alias2
=VAL :scalar4
-MAP
=VAL :top5
=VAL :scalar5
=VAL :top6
+MAP
=VAL &anchor6 'key6
=VAL :scalar6
-MAP
-MAP
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL :text
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC
+SEQ
=VAL <tag:yaml.org,2002:str> :a
=VAL :b
=VAL <tag:yaml.org,2002:int> :42
=VAL :d
-SEQ
-DOC
-STR

View File

@ -0,0 +1,2 @@
+STR
+DOC

View File

@ -0,0 +1,16 @@
+STR
+DOC
+MAP
=VAL :a!"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~
=VAL :safe
=VAL :?foo
=VAL :safe question mark
=VAL ::foo
=VAL :safe colon
=VAL :-foo
=VAL :safe dash
=VAL :this is#not
=VAL :a comment
-MAP
-DOC
-STR

View File

@ -0,0 +1,2 @@
+STR
+DOC ---

View File

@ -0,0 +1,2 @@
+STR
+DOC ---

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL |
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL |
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC
+MAP
=VAL :
=VAL :a
=VAL :
=VAL :b
-MAP
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL "foo
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC
+MAP
=VAL &a: :key
=VAL &a :value
=VAL :foo
=ALI *a:
-MAP
-DOC
-STR

View File

@ -0,0 +1,12 @@
+STR
+DOC ---
+MAP <tag:yaml.org,2002:set>
=VAL :Mark McGwire
=VAL :
=VAL :Sammy Sosa
=VAL :
=VAL :Ken Griff
=VAL :
-MAP
-DOC
-STR

View File

@ -0,0 +1,9 @@
+STR
+DOC ---
+SEQ
=VAL <tag:yaml.org,2002:int> :1
=VAL <tag:yaml.org,2002:int> :-2
=VAL <tag:yaml.org,2002:int> :33
-SEQ
-DOC
-STR

View File

@ -0,0 +1,16 @@
+STR
+DOC ---
+MAP <tag:yaml.org,2002:map>
=VAL :a
=VAL :b
-MAP
-DOC
+DOC ---
+SEQ <tag:yaml.org,2002:seq>
=VAL <tag:yaml.org,2002:str> :c
-SEQ
-DOC
+DOC ---
=VAL <tag:yaml.org,2002:str> :d e
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC ---
+MAP
=VAL :plain
=VAL :a b\nc
-MAP
-DOC
-STR

View File

@ -0,0 +1,11 @@
+STR
+DOC
+SEQ
+SEQ
=VAL :s1_i1
=VAL :s1_i2
-SEQ
=VAL :s2
-SEQ
-DOC
-STR

View File

@ -0,0 +1,14 @@
+STR
+DOC
+MAP
=VAL :First occurrence
=VAL &anchor :Foo
=VAL :Second occurrence
=ALI *anchor
=VAL :Override anchor
=VAL &anchor :Bar
=VAL :Reuse anchor
=ALI *anchor
-MAP
-DOC
-STR

View File

@ -0,0 +1,7 @@
+STR
+DOC ---
+MAP
=VAL :key
=VAL :value
-MAP
-DOC ...

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL :k:#foo &a !t s
-DOC
-STR

View File

@ -0,0 +1,7 @@
+STR
+DOC
+SEQ &sequence
=VAL :a
-SEQ
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
=VAL "1 leading \ttab
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
=VAL "2 leading \ttab
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
=VAL "3 leading tab
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
=VAL "4 leading \t tab
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
=VAL "5 leading \t tab
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
=VAL "6 leading tab
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC
+MAP
=VAL :escaped slash
=VAL "a/b
-MAP
-DOC
-STR

View File

@ -0,0 +1,12 @@
+STR
+DOC
+MAP {}
=VAL :unquoted
=VAL "separate
=VAL :http://foo.com
=VAL :
=VAL :omitted value
=VAL :
-MAP
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC
+MAP
=VAL :plain
=VAL :This unquoted scalar spans many lines.
=VAL :quoted
=VAL "So does this quoted scalar.\n
-MAP
-DOC
-STR

View File

@ -0,0 +1,4 @@
+STR
+DOC ---
+MAP
=VAL :a

View File

@ -0,0 +1,24 @@
+STR
+DOC ---
+SEQ []
+MAP {}
+SEQ []
=VAL :a
+SEQ []
+MAP {}
+SEQ []
+SEQ []
=VAL :b
=VAL :c
-SEQ
-SEQ
=VAL :d
-MAP
=VAL :e
-SEQ
-SEQ
=VAL :23
-MAP
-SEQ
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
=VAL 'here's to "quotes"
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC ---
+SEQ
=VAL :a
=VAL :b
=VAL :c
-SEQ
-DOC

View File

@ -0,0 +1,8 @@
+STR
+DOC
+MAP
=VAL :key
+SEQ
=VAL :ok
=VAL :also ok
-SEQ

View File

@ -0,0 +1,9 @@
+STR
+DOC
+MAP
=VAL :top1
+MAP &node1
=VAL &k1 :key1
=VAL :val1
-MAP
=VAL :top2

View File

@ -0,0 +1,8 @@
+STR
+DOC
+MAP {}
=VAL "foo
=VAL "bar
-MAP
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC
+MAP {}
=VAL "foo
=VAL :bar
-MAP
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC
+MAP {}
=VAL :foo
=VAL :bar
-MAP
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL >ab cd\nef\n\ngh\n
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC
+SEQ
=VAL |detected\n
=VAL >\n\n# detected\n
=VAL | explicit\n
=VAL >detected\n
-SEQ
-DOC
-STR

View File

@ -0,0 +1,9 @@
+STR
+DOC
+SEQ []
=VAL :1
=VAL :2
=VAL :3
-SEQ
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
=VAL "foo: bar": baz
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL :plain\\value\\with\\backslashes
-DOC
-STR

View File

@ -0,0 +1,12 @@
+STR
+DOC
+SEQ
+MAP
=VAL :aaa
=VAL |xxx\n
=VAL :bbb
=VAL |xxx\n
-MAP
-SEQ
-DOC
-STR

View File

@ -0,0 +1,12 @@
+STR
+DOC
+MAP
=VAL :plain
=VAL :text lines
=VAL :quoted
=VAL "text lines
=VAL :block
=VAL |text\n \tlines\n
-MAP
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL <!> :a
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC
+MAP {}
=VAL :foo
=VAL :you
=VAL :bar
=VAL :far
-MAP
-DOC
-STR

View File

@ -0,0 +1,2 @@
+STR
+DOC ---

View File

@ -0,0 +1,12 @@
+STR
+DOC
+MAP
=VAL :canonical
=VAL <tag:yaml.org,2002:binary> "R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLCAgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
=VAL :generic
=VAL <tag:yaml.org,2002:binary> |R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\nOTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\n+f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\nAgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=\n
=VAL :description
=VAL :The binary value above is a tiny arrow encoded as a gif image.
-MAP
-DOC
-STR

View File

@ -0,0 +1,18 @@
+STR
+DOC
+MAP
=VAL :sequence
+SEQ <tag:yaml.org,2002:seq>
=VAL :entry
+SEQ <tag:yaml.org,2002:seq>
=VAL :nested
-SEQ
-SEQ
=VAL :mapping
+MAP <tag:yaml.org,2002:map>
=VAL :foo
=VAL :bar
-MAP
-MAP
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC
+MAP {}
=VAL :x
=VAL ::x
-MAP
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC
+MAP
=VAL :literal
=VAL |some\ntext\n
=VAL :folded
=VAL >some text\n
-MAP
-DOC
-STR

View File

@ -0,0 +1,18 @@
+STR
+DOC
+SEQ
+MAP {}
=VAL :one
=VAL :two
=VAL :three
=VAL :four
-MAP
+MAP {}
=VAL :five
=VAL :six
=VAL :seven
=VAL :eight
-MAP
-SEQ
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC
+MAP
=VAL :Folding
=VAL "Empty line\nas a line feed
=VAL :Chomping
=VAL |Clipped empty lines\n
-MAP
-DOC
-STR

View File

@ -0,0 +1,14 @@
+STR
+DOC
+SEQ
+SEQ []
=VAL :one
=VAL :two
-SEQ
+SEQ []
=VAL :three
=VAL :four
-SEQ
-SEQ
-DOC
-STR

View File

@ -0,0 +1,4 @@
+STR
+DOC
+MAP
=VAL :block scalar

View File

@ -0,0 +1,8 @@
+STR
+DOC ---
+MAP {}
=VAL "foo
=VAL :bar
-MAP
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC
+MAP
=VAL :key
=VAL :value
-MAP
-DOC
-STR

View File

@ -0,0 +1,14 @@
+STR
+DOC
+SEQ
+MAP {}
=VAL "key
=VAL :value
-MAP
+MAP {}
=VAL "key
=VAL ::value
-MAP
-SEQ
-DOC
-STR

View File

@ -0,0 +1,2 @@
+STR
+DOC ---

View File

@ -0,0 +1,8 @@
+STR
+DOC ---
=VAL <!my-light> :fluorescent
-DOC ...
+DOC ---
=VAL <!my-light> :green
-DOC
-STR

View File

@ -0,0 +1,4 @@
+STR
+DOC
+MAP
=VAL :key

View File

@ -0,0 +1,13 @@
+STR
+DOC
+MAP
=VAL :explicit key
=VAL :
=VAL |block key\n
+SEQ
=VAL :one
=VAL :two
-SEQ
-MAP
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC ---
+MAP
=VAL :x
+MAP {}
=VAL :y
=VAL :z
-MAP

View File

@ -0,0 +1,10 @@
+STR
+DOC
+MAP {}
=VAL :?foo
=VAL :bar
=VAL :bar
=VAL :42
-MAP
-DOC
-STR

View File

@ -0,0 +1,7 @@
+STR
+DOC
+SEQ
=VAL :foo
-SEQ
-DOC
-STR

View File

@ -0,0 +1,14 @@
+STR
+DOC
+SEQ
+MAP
=VAL :foo
=VAL :bar
-MAP
+SEQ
=VAL :baz
=VAL :baz
-SEQ
-SEQ
-DOC
-STR

View File

@ -0,0 +1,12 @@
+STR
+DOC ---
+MAP &mapping
+SEQ [] &key
=VAL &item :a
=VAL :b
=VAL :c
-SEQ
=VAL :value
-MAP
-DOC
-STR

View File

@ -0,0 +1,6 @@
+STR
+DOC
+SEQ []
-SEQ
-DOC
-STR

View File

@ -0,0 +1,9 @@
+STR
+DOC ---
+SEQ
=VAL <!local> :foo
=VAL <tag:yaml.org,2002:str> :bar
=VAL <tag:example.com,2000:app/tag!> :baz
-SEQ
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL |ab\n\n \n
-DOC ...
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC
+MAP
=VAL 'foo: bar\\
=VAL :baz'
-MAP
-DOC
-STR

View File

@ -0,0 +1,17 @@
+STR
+DOC
+MAP
=VAL :Not indented
+MAP
=VAL :By one space
=VAL |By four\n spaces\n
=VAL :Flow style
+SEQ []
=VAL :By two
=VAL :Also by two
=VAL :Still by two
-SEQ
-MAP
-MAP
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL |\\//||\\/||\n// || ||__\n
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC ---
+SEQ []
+SEQ []
=VAL :a
=VAL :b
=VAL :c
-SEQ

View File

@ -0,0 +1,14 @@
+STR
+DOC
+MAP
=VAL :foo
+SEQ <tag:yaml.org,2002:seq>
=VAL <tag:yaml.org,2002:str> :a
+MAP <tag:yaml.org,2002:map>
=VAL :key
=VAL <tag:yaml.org,2002:str> :value
-MAP
-SEQ
-MAP
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC ---
+MAP
=VAL :a
=VAL &anchor :
=VAL :b
=ALI *anchor
-MAP
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL "foo
-DOC
-STR

View File

@ -0,0 +1,10 @@
+STR
+DOC
+MAP
=VAL &a :a
=VAL &b :b
=VAL :
=ALI *a
-MAP
-DOC
-STR

View File

@ -0,0 +1,14 @@
+STR
+DOC ---
+MAP
+SEQ
=VAL :a
=VAL :b
-SEQ
+SEQ
=VAL :c
=VAL :d
-SEQ
-MAP
-DOC
-STR

View File

@ -0,0 +1,7 @@
+STR
+DOC
+MAP
=VAL :key
+SEQ
=VAL :bar
=VAL :baz

View File

@ -0,0 +1,10 @@
+STR
+DOC
+MAP
=VAL "foo\nbar:baz\tx \\$%^&*()x
=VAL :23
=VAL 'x\\ny:z\\tx $%^&*()x
=VAL :24
-MAP
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC
=VAL >Sammy Sosa completed another fine season with great stats.\n\n 63 Home Runs\n 0.288 Batting Average\n\nWhat a year!\n
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC ---
=VAL <!foo> "bar
-DOC ...
+DOC ---
=VAL <tag:example.com,2000:app/foo> "bar
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL " foo\nbar\nbaz
-DOC
-STR

View File

@ -0,0 +1,8 @@
+STR
+DOC ---
=VAL :
-DOC
+DOC ---
=VAL :
-DOC
-STR

View File

@ -0,0 +1,14 @@
+STR
+DOC
=VAL :Document
-DOC
+DOC ---
=VAL :
-DOC ...
+DOC ---
+MAP
=VAL :matches %
=VAL :20
-MAP
-DOC
-STR

View File

@ -0,0 +1,12 @@
+STR
+DOC
+SEQ
=VAL "flow in block
=VAL >Block scalar\n
+MAP <tag:yaml.org,2002:map>
=VAL :foo
=VAL :bar
-MAP
-SEQ
-DOC
-STR

View File

@ -0,0 +1,16 @@
+STR
+DOC
+MAP
=VAL <tag:yaml.org,2002:str> :a
=VAL :b
=VAL :c
=VAL <tag:yaml.org,2002:int> :42
=VAL :e
=VAL <tag:yaml.org,2002:str> :f
=VAL :g
=VAL :h
=VAL <tag:yaml.org,2002:str> :23
=VAL <tag:yaml.org,2002:bool> :false
-MAP
-DOC
-STR

View File

@ -0,0 +1,5 @@
+STR
+DOC ---
=VAL |ab
-DOC ...
-STR

Some files were not shown because too many files have changed in this diff Show More