extension PureYAML.Parsing.Scanner { func scanNamedToken( kind: (String) -> PureYAML.Parsing.TokenKind, missingNameError: (Int) -> PureYAML.Parsing.ParseError, state: inout State, ) throws { let start = state.reader.mark // An anchor or alias may itself begin a flow simple key, so record the // position before the token is appended; the following node then does not // start a new key, leaving `&anchor key :` anchored at the `&` (libyaml's // fetch_anchor saves the simple key before clearing simple_key_allowed). saveFlowSimpleKey(&state) state.reader.advance() // An anchor or alias name is a run of name characters that ends at the // first non-name character, mirroring `yaml_parser_scan_anchor`: the // name must stop at whitespace, `:`, `?`, flow indicators, and the other // indicator characters so that `*alias:` reads the alias `alias` // followed by a `:` mapping indicator rather than swallowing the colon. let name = state.reader.consume { character in isAnchorNameCharacter(character) } guard !name.isEmpty else { throw missingNameError(start.line) } state.append(kind(name), mark: start, endMark: state.reader.mark) } func scanTag(_ state: inout State) throws { let start = state.reader.mark // A tag may itself begin a flow simple key (see `scanNamedToken`). saveFlowSimpleKey(&state) state.reader.advance() var value = "!" if state.reader.peek() == "<" { value.append(state.reader.advance() ?? "<") var didClose = false while let character = state.reader.peek() { value.append(character) state.reader.advance() if character == ">" { didClose = true break } } guard didClose else { throw PureYAML.Parsing.ParseError.unterminatedTag(line: start.line) } } else { value += state.reader.consume { character in !isTokenTerminator(character) } value = expandTag(value, state: state) } state.append(.tag(value), mark: start, endMark: state.reader.mark) } }