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