Routes the value and stream APIs through the ported scanner+parser (the event API already was), so PureYAML now parses entirely on the libyaml port. Adds the features needed to match and exceed the previous engine: JSON UTF-16 surrogate-pair \u escapes, bare documents after an explicit `...`, reserved-directive handling that still requires a following `---`, and a 64-level nesting bound enforced on the event stream so deeply nested input fails with nestingTooDeep instead of overflowing a recursive consumer. Parser errors are translated to the diagnostic-aware ParseError, recovering precise codes where identifiable and a readable malformed fallback otherwise; error-reporting fixtures are rebased onto the port. Canonical event conformance: 268 -> 271 of 308 (7Z25, HWV9, QT73). 393 tests pass.
40 lines
1.9 KiB
Swift
40 lines
1.9 KiB
Swift
extension PureYAML.Parsing.ParseError {
|
|
/// Translate a ported-scanner error into the package's diagnostic-aware error,
|
|
/// converting libyaml's 0-based mark to the 1-based convention and mapping the
|
|
/// well-known scanner failures to precise diagnostic codes.
|
|
init(translating error: PureYAML.Parsing.LibYAML.ScannerError) {
|
|
let line = error.mark.line + 1
|
|
let column = error.mark.column + 1
|
|
let context = error.context ?? ""
|
|
if error.problem.hasPrefix("found a tab") {
|
|
self = .tabIndentation(line: line)
|
|
} else if context == "while scanning a quoted scalar", error.problem.hasSuffix("end of stream") {
|
|
self = .unterminatedQuotedString(line: line)
|
|
} else if context.hasPrefix("while scanning a tag") || context.hasSuffix("TAG directive") {
|
|
self = .unterminatedTag(line: line)
|
|
} else {
|
|
self = .malformed(reason: Self.reason(context: error.context, problem: error.problem), line: line, column: column)
|
|
}
|
|
}
|
|
|
|
/// Translate a ported-parser error into the package's diagnostic-aware error.
|
|
init(translating error: PureYAML.Parsing.LibYAML.ParserError) {
|
|
let line = error.mark.line + 1
|
|
let column = error.mark.column + 1
|
|
if error.problem == "found incompatible YAML document" {
|
|
self = .incompatibleYAMLDirective(line: line)
|
|
} else {
|
|
self = .malformed(reason: Self.reason(context: error.context, problem: error.problem), line: line, column: column)
|
|
}
|
|
}
|
|
|
|
/// Join a libyaml context and problem into one readable reason, e.g.
|
|
/// "while parsing a flow sequence, did not find expected ',' or ']'".
|
|
private static func reason(context: String?, problem: String) -> String {
|
|
guard let context else {
|
|
return problem
|
|
}
|
|
return "\(context), \(problem)"
|
|
}
|
|
}
|