An anchor or alias name is ns-anchor-char+ (any printable character that is not whitespace, a line break, the BOM, or a flow indicator), so Unicode and punctuation names are valid. libyaml restricts the name to alphanumerics and rejects them. Canonical event conformance: 271 -> 275 of 308 (2SXE, 8XYN, W5VH, Y2GN). 379 tests pass.
46 lines
1.8 KiB
Swift
46 lines
1.8 KiB
Swift
extension PureYAML.Parsing.LibYAML.Scanner {
|
|
private typealias Classify = PureYAML.Parsing.LibYAML.CharacterClass
|
|
|
|
/// Port of `yaml_parser_scan_anchor`, widened to YAML 1.2: an anchor (`&name`)
|
|
/// or alias (`*name`) name is `ns-anchor-char+`, i.e. any printable character
|
|
/// that is not whitespace, a line break, or a flow indicator (`,[]{}`). libyaml
|
|
/// restricts the name to alphanumerics, which rejects Unicode and punctuation
|
|
/// anchor names that YAML 1.2 allows.
|
|
mutating func scanAnchor(isAnchor: Bool) throws -> PureYAML.Parsing.LibYAML.Token {
|
|
let startMark = reader.mark
|
|
reader.skip()
|
|
var name = ""
|
|
while let character = reader.peek(), isAnchorCharacter(character) {
|
|
name.unicodeScalars.append(character)
|
|
reader.skip()
|
|
}
|
|
let endMark = reader.mark
|
|
guard !name.isEmpty else {
|
|
throw PureYAML.Parsing.LibYAML.ScannerError(
|
|
context: isAnchor ? "while scanning an anchor" : "while scanning an alias",
|
|
problem: "did not find expected alphabetic or numeric character",
|
|
mark: startMark,
|
|
)
|
|
}
|
|
return PureYAML.Parsing.LibYAML.Token(
|
|
type: isAnchor ? .anchor(name: name) : .alias(name: name),
|
|
startMark: startMark,
|
|
endMark: endMark,
|
|
)
|
|
}
|
|
|
|
/// `ns-anchor-char`: a printable, non-blank, non-break character that is not a
|
|
/// flow indicator or the byte-order mark.
|
|
private func isAnchorCharacter(_ scalar: Unicode.Scalar) -> Bool {
|
|
guard Classify.isPrintable(scalar), !Classify.isBlankZ(scalar), scalar != "\u{FEFF}" else {
|
|
return false
|
|
}
|
|
switch scalar {
|
|
case ",", "[", "]", "{", "}":
|
|
return false
|
|
default:
|
|
return true
|
|
}
|
|
}
|
|
}
|