A block sequence must begin its own line. A '-' entry mid-line after an
inline mapping value ('key: - a') or a node property ('&anchor - x') is
invalid, but libyaml accepts both. A '-' after another '-' is still a
valid compact sequence ('- - a'), and an explicit key whose ':' is on a
later line may still open a sequence ('? k' / ': - a').
In fetchBlockEntry, when no line break was crossed, reject if the last
token is an anchor/tag, or a value that closed an inline implicit key
(told apart by a pending simple key: an explicit key's simple key has
gone stale across its line break). Extract the scanner guard helpers into
LibYAML.Scanner.Guards to stay within the file-length limit.
Surpasses libyaml on 5U3A, SY6V; whole-suite conformance 396/402,
canonical events 308/308.
58 lines
2.3 KiB
Swift
58 lines
2.3 KiB
Swift
extension PureYAML.Parsing.LibYAML.Scanner {
|
|
private typealias ScannerError = PureYAML.Parsing.LibYAML.ScannerError
|
|
|
|
/// Reject a flow-collection continuation line that is not indented past the
|
|
/// enclosing block context. YAML requires `s-flow-line-prefix` to be more
|
|
/// indented than the parent block; libyaml does not enforce it, so multi-line
|
|
/// flow content in column 0 (`[a,\nb]` under a key) wrongly parses.
|
|
mutating func checkFlowContinuationIndent() throws {
|
|
guard flowLevel > 0, crossedLineBreak, let next = reader.peek() else {
|
|
return
|
|
}
|
|
// A closing `]`/`}` (or a `,` separator) may sit at any indentation; only
|
|
// flow CONTENT must be indented past the parent block.
|
|
if next == "]" || next == "}" || next == "," {
|
|
return
|
|
}
|
|
if reader.column <= indentEngine.indent {
|
|
throw ScannerError(
|
|
context: "while parsing a flow node",
|
|
problem: "found insufficiently indented line in a flow collection",
|
|
mark: reader.mark,
|
|
)
|
|
}
|
|
}
|
|
|
|
/// Whether the last emitted token bars a block sequence from opening on the
|
|
/// same line: a mapping value indicator or a node property (anchor/tag). After
|
|
/// another block entry a compact sequence is allowed, so that is not barred.
|
|
func lastTokenForbidsInlineSequence() -> Bool {
|
|
switch indentEngine.tokens.last?.type {
|
|
case .anchor, .tag:
|
|
true
|
|
case .value:
|
|
lastValueWasInline
|
|
default:
|
|
false
|
|
}
|
|
}
|
|
|
|
/// The error raised when a tab is used where indentation is required (before a
|
|
/// block indicator or an implicit mapping key). A tab is valid separation but
|
|
/// never indentation.
|
|
func tabIndentationError() -> PureYAML.Parsing.LibYAML.ScannerError {
|
|
ScannerError(
|
|
context: "while scanning for the next token",
|
|
problem: "found a tab character where an indentation space is expected",
|
|
mark: reader.mark,
|
|
)
|
|
}
|
|
|
|
/// Whether this flow level's pending simple key is a JSON (quoted) node, which
|
|
/// lets an adjacent `:` open its value without a separating space.
|
|
var flowKeyIsJSON: Bool {
|
|
let key = simpleKeys[simpleKeys.count - 1]
|
|
return key.possible && key.isJSON
|
|
}
|
|
}
|