Support tags for sequences and maps in block style

This commit is contained in:
Felix Krause 2015-12-27 17:37:42 +01:00
parent d7f1e726ab
commit 2c9d065ecb
3 changed files with 29 additions and 18 deletions

View File

@ -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)

View File

@ -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:

View File

@ -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"),