extension PureYAML.Parsing.LibYAML.Parser { /// Port of `yaml_parser_parse_block_sequence_entry`. mutating func parseBlockSequenceEntry(first: Bool) throws -> Event { if first { marks.append(peekToken().startMark) skipToken() } let token = peekToken() if case .blockEntry = token.type { let mark = token.endMark skipToken() let next = peekToken() if !isBlockEntry(next), !isBlockEnd(next) { states.append(.blockSequenceEntry) return try parseNode(block: true, indentlessSequence: false) } state = .blockSequenceEntry return processEmptyScalar(at: mark) } if case .blockEnd = token.type { state = states.removeLast() _ = marks.popLast() skipToken() return .sequenceEnd(mark: token.startMark) } throw ParserError( context: "while parsing a block collection", problem: "did not find expected '-' indicator", mark: marks.popLast() ?? token.startMark, ) } /// Port of `yaml_parser_parse_indentless_sequence_entry`. The closing token /// belongs to the enclosing collection, so the SEQUENCE-END is emitted without /// consuming it. mutating func parseIndentlessSequenceEntry() throws -> Event { let token = peekToken() guard case .blockEntry = token.type else { state = states.removeLast() return .sequenceEnd(mark: token.startMark) } let mark = token.endMark skipToken() let next = peekToken() if !isBlockEntry(next), !isKey(next), !isValue(next), !isBlockEnd(next) { states.append(.indentlessSequenceEntry) return try parseNode(block: true, indentlessSequence: false) } state = .indentlessSequenceEntry return processEmptyScalar(at: mark) } /// Port of `yaml_parser_parse_block_mapping_key`. mutating func parseBlockMappingKey(first: Bool) throws -> Event { if first { marks.append(peekToken().startMark) skipToken() } let token = peekToken() if case .key = token.type { let mark = token.endMark skipToken() let next = peekToken() if !isKey(next), !isValue(next), !isBlockEnd(next) { states.append(.blockMappingValue) return try parseNode(block: true, indentlessSequence: true) } state = .blockMappingValue return processEmptyScalar(at: mark) } if case .blockEnd = token.type { state = states.removeLast() _ = marks.popLast() skipToken() return .mappingEnd(mark: token.startMark) } // YAML 1.2 permits an empty (null) key: a VALUE indicator with no // preceding key denotes a mapping entry whose key is empty. libyaml // rejects this here; instead emit the empty scalar key and leave the // VALUE token for `parseBlockMappingValue` to consume. if case .value = token.type { state = .blockMappingValue return processEmptyScalar(at: token.startMark) } throw ParserError( context: "while parsing a block mapping", problem: "did not find expected key", mark: marks.popLast() ?? token.startMark, ) } /// Port of `yaml_parser_parse_block_mapping_value`. mutating func parseBlockMappingValue() throws -> Event { let token = peekToken() guard case .value = token.type else { state = .blockMappingKey return processEmptyScalar(at: token.startMark) } let mark = token.endMark skipToken() let next = peekToken() if !isKey(next), !isValue(next), !isBlockEnd(next) { states.append(.blockMappingKey) return try parseNode(block: true, indentlessSequence: true) } state = .blockMappingKey return processEmptyScalar(at: mark) } }