mirror of https://github.com/status-im/NimYAML.git
Support tags for sequences and maps in block style
This commit is contained in:
parent
d7f1e726ab
commit
2c9d065ecb
|
@ -731,6 +731,7 @@ iterator tokens(my: var YamlLexer): YamlLexerToken {.closure.} =
|
|||
state = ylTagHandle
|
||||
my.content = "!"
|
||||
lastSpecialChar = '\0'
|
||||
my.column = curPos - 1
|
||||
else:
|
||||
my.content.add(lastSpecialChar)
|
||||
advanceTypeHint(lastSpecialChar)
|
||||
|
|
|
@ -106,6 +106,10 @@ template yieldScalar(content: string, typeHint: YamlTypeHint,
|
|||
when defined(yamlDebug):
|
||||
echo "Parser token [mode=", level.mode, ", state=", state, "]: ",
|
||||
"scalar[\"", content, "\", type=", typeHint, "]"
|
||||
if objectTag.len > 0:
|
||||
if tag.len > 0:
|
||||
yieldError("Duplicate tag for scalar")
|
||||
tag = objectTag
|
||||
yield YamlStreamEvent(kind: yamlScalar,
|
||||
scalarAnchor: resolveAnchor(parser, anchor),
|
||||
scalarTag: resolveTag(parser, tag, quoted),
|
||||
|
@ -227,7 +231,7 @@ template handleBlockIndicator(expected, possible: openarray[DocumentLevelMode],
|
|||
cachedAnchor = anchor
|
||||
cachedTag = tag
|
||||
anchor = ""
|
||||
tag = ""
|
||||
tag = objectTag
|
||||
yieldStart(entering)
|
||||
anchor = cachedAnchor
|
||||
tag = cachedTag
|
||||
|
@ -286,6 +290,7 @@ proc parse*(parser: YamlSequentialParser, s: Stream): YamlStream =
|
|||
|
||||
# cached values
|
||||
tag: string = ""
|
||||
objectTag: string = ""
|
||||
anchor: string = ""
|
||||
scalarCache: string = nil
|
||||
scalarCacheType: YamlTypeHint
|
||||
|
@ -363,6 +368,8 @@ proc parse*(parser: YamlSequentialParser, s: Stream): YamlStream =
|
|||
case token
|
||||
of tTagHandle:
|
||||
handleTagHandle()
|
||||
objectTag = tag
|
||||
tag = ""
|
||||
state = ypBlockLineEnd
|
||||
of tComment:
|
||||
state = ypBlockLineEnd
|
||||
|
@ -373,7 +380,11 @@ proc parse*(parser: YamlSequentialParser, s: Stream): YamlStream =
|
|||
of ypBlockLineStart:
|
||||
case token
|
||||
of tLineStart:
|
||||
discard
|
||||
if objectTag.len > 0:
|
||||
yieldError("Duplicate tag for object")
|
||||
else:
|
||||
objectTag = tag
|
||||
tag = ""
|
||||
of tDash:
|
||||
handleBlockIndicator([mBlockSequenceItem], [],
|
||||
mBlockSequenceItem, yamlStartSequence)
|
||||
|
@ -499,21 +510,20 @@ proc parse*(parser: YamlSequentialParser, s: Stream): YamlStream =
|
|||
closeAllLevels()
|
||||
state = ypAfterDirectivesEnd
|
||||
continue
|
||||
of tAlias:
|
||||
else:
|
||||
leaveMoreIndentedLevels()
|
||||
if level.mode == mScalar:
|
||||
yieldUnexpectedToken()
|
||||
state = ypBlockLineStart
|
||||
continue
|
||||
else:
|
||||
yieldUnexpectedToken()
|
||||
of ypBlockAfterScalar:
|
||||
case token
|
||||
of tColon:
|
||||
assert level.mode in [mUnknown, mImplicitBlockMapKey, mScalar]
|
||||
if level.mode in [mUnknown, mScalar]:
|
||||
# tags and anchors are for key scalar, not for map.
|
||||
yield YamlStreamEvent(kind: yamlStartMap,
|
||||
mapAnchor: anchorNone,
|
||||
mapTag: tagQuestionMark)
|
||||
mapTag: parser.resolveTag(objectTag))
|
||||
level.mode = mBlockMapValue
|
||||
ancestry.add(level)
|
||||
level = DocumentLevel(mode: mUnknown, indicatorColumn: -1,
|
||||
|
@ -584,11 +594,9 @@ proc parse*(parser: YamlSequentialParser, s: Stream): YamlStream =
|
|||
of tAnchor:
|
||||
anchor = lex.content
|
||||
state = ypBlockAfterAnchorAndTag
|
||||
of tScalar, tColon, tStreamEnd:
|
||||
of tScalar, tColon, tStreamEnd, tScalarPart:
|
||||
state = ypBlockLineStart
|
||||
continue
|
||||
of tScalarPart:
|
||||
startPlainScalar()
|
||||
of tLineStart:
|
||||
state = ypBlockLineStart
|
||||
of tOpeningBracket, tOpeningBrace:
|
||||
|
@ -602,11 +610,9 @@ proc parse*(parser: YamlSequentialParser, s: Stream): YamlStream =
|
|||
state = ypBlockLineStart
|
||||
continue
|
||||
case token
|
||||
of tScalar, tColon, tStreamEnd:
|
||||
of tScalar, tColon, tStreamEnd, tScalarPart:
|
||||
state = ypBlockLineStart
|
||||
continue
|
||||
of tScalarPart:
|
||||
startPlainScalar()
|
||||
of tLineStart:
|
||||
discard
|
||||
of tOpeningBracket, tOpeningBrace:
|
||||
|
@ -627,11 +633,9 @@ proc parse*(parser: YamlSequentialParser, s: Stream): YamlStream =
|
|||
state = ypBlockLineStart
|
||||
continue
|
||||
case token
|
||||
of tScalar, tColon, tStreamEnd:
|
||||
of tScalar, tColon, tStreamEnd, tScalarPart:
|
||||
state = ypBlockLineStart
|
||||
continue
|
||||
of tScalarPart:
|
||||
startPlainScalar()
|
||||
of tLineStart:
|
||||
discard
|
||||
of tOpeningBracket, tOpeningBrace:
|
||||
|
|
|
@ -50,8 +50,8 @@ proc printDifference(expected, actual: YamlStreamEvent) =
|
|||
if expected.kind != actual.kind:
|
||||
echo "expected " & $expected.kind & ", got " & $actual.kind
|
||||
if actual.kind == yamlError:
|
||||
echo "Error message: (", actual.line, ", ", actual.column, ") ",
|
||||
actual.description
|
||||
echo "Error message: (line: ", actual.line, ", column: ",
|
||||
actual.column, ") ", actual.description
|
||||
elif actual.kind == yamlWarning:
|
||||
echo "Warning message: " & actual.description
|
||||
else:
|
||||
|
@ -238,6 +238,12 @@ suite "Parsing":
|
|||
ensure("? !!str a\n: !!int b\n? c\n: !!str d", startDoc(), startMap(),
|
||||
scalar("a", tagString), scalar("b", tagInteger), scalar("c"),
|
||||
scalar("d", tagString), endMap(), endDoc())
|
||||
test "Parsing: tags for block objects":
|
||||
ensure("--- !!map\nfoo: !!seq\n - a\n - !!str b\n!!str bar: !!str baz",
|
||||
startDoc(), startMap(tagMap), scalar("foo"),
|
||||
startSequence(tagSequence), scalar("a"), scalar("b", tagString),
|
||||
endSequence(), scalar("bar", tagString),
|
||||
scalar("baz", tagString), endMap(), endDoc())
|
||||
test "Parsing: tags for flow objects":
|
||||
ensure("!!map { k: !!seq [ a, !!str b] }", startDoc(), startMap(tagMap),
|
||||
scalar("k"), startSequence(tagSequence), scalar("a"),
|
||||
|
|
Loading…
Reference in New Issue