mirror of https://github.com/status-im/NimYAML.git
Got tags working
This commit is contained in:
parent
32f36515e7
commit
f320449a2d
|
@ -514,6 +514,11 @@ iterator tokens*(my: var YamlLexer): YamlLexerToken {.closure.} =
|
||||||
yieldToken(yamlDash)
|
yieldToken(yamlDash)
|
||||||
of ',':
|
of ',':
|
||||||
yieldToken(yamlComma)
|
yieldToken(yamlComma)
|
||||||
|
of '!':
|
||||||
|
my.content = "!"
|
||||||
|
yieldToken(yamlTagHandle)
|
||||||
|
my.content = ""
|
||||||
|
yieldToken(yamlTagSuffix)
|
||||||
else:
|
else:
|
||||||
yieldError("Unexpected special char: \"" &
|
yieldError("Unexpected special char: \"" &
|
||||||
lastSpecialChar & "\"")
|
lastSpecialChar & "\"")
|
||||||
|
|
|
@ -33,6 +33,7 @@ type
|
||||||
ylBlockAfterAnchor, ylBlockAfterAnchorAndTag, ylBlockAfterScalar,
|
ylBlockAfterAnchor, ylBlockAfterAnchorAndTag, ylBlockAfterScalar,
|
||||||
ylBlockAfterColon, ylBlockMultilineScalar, ylBlockLineEnd,
|
ylBlockAfterColon, ylBlockMultilineScalar, ylBlockLineEnd,
|
||||||
ylBlockScalarHeader, ylBlockScalar, ylFlow, ylFlowAfterObject,
|
ylBlockScalarHeader, ylBlockScalar, ylFlow, ylFlowAfterObject,
|
||||||
|
ylFlowAfterTag, ylFlowAfterAnchor, ylFlowAfterAnchorAndTag,
|
||||||
ylExpectingDocumentEnd
|
ylExpectingDocumentEnd
|
||||||
|
|
||||||
DocumentLevelMode = enum
|
DocumentLevelMode = enum
|
||||||
|
@ -154,6 +155,12 @@ template yieldStart(k: YamlParserEventKind) {.dirty.} =
|
||||||
anchor = nil
|
anchor = nil
|
||||||
tag = nil
|
tag = nil
|
||||||
|
|
||||||
|
template yieldDocumentEnd() {.dirty.} =
|
||||||
|
yield YamlParserEvent(kind: yamlEndDocument)
|
||||||
|
tagShorthands = initTable[string, string]()
|
||||||
|
tagShorthands["!"] = "!"
|
||||||
|
tagShorthands["!!"] = "tag:yaml.org,2002:"
|
||||||
|
|
||||||
template closeLevel(lvl: DocumentLevel) {.dirty.} =
|
template closeLevel(lvl: DocumentLevel) {.dirty.} =
|
||||||
case lvl.mode
|
case lvl.mode
|
||||||
of mExplicitBlockMapKey, mFlowMapKey:
|
of mExplicitBlockMapKey, mFlowMapKey:
|
||||||
|
@ -239,7 +246,6 @@ template handleTagHandle() {.dirty.} =
|
||||||
yieldError("Missing tag suffix")
|
yieldError("Missing tag suffix")
|
||||||
continue
|
continue
|
||||||
tag = tagShorthands[handle] & lex.content
|
tag = tagShorthands[handle] & lex.content
|
||||||
level.indentationColumn = lex.column
|
|
||||||
else:
|
else:
|
||||||
yieldError("Unknown tag shorthand: " & handle)
|
yieldError("Unknown tag shorthand: " & handle)
|
||||||
|
|
||||||
|
@ -273,6 +279,8 @@ iterator events*(parser: var YamlSequentialParser,
|
||||||
scalarCacheIsQuoted: bool = false
|
scalarCacheIsQuoted: bool = false
|
||||||
|
|
||||||
lex.open(input)
|
lex.open(input)
|
||||||
|
tagShorthands["!"] = "!"
|
||||||
|
tagShorthands["!!"] = "tag:yaml.org,2002:"
|
||||||
|
|
||||||
var nextToken = tokens
|
var nextToken = tokens
|
||||||
var token = nextToken(lex)
|
var token = nextToken(lex)
|
||||||
|
@ -326,7 +334,7 @@ iterator events*(parser: var YamlSequentialParser,
|
||||||
state = ylBlockLineStart
|
state = ylBlockLineStart
|
||||||
of yamlDocumentEnd, yamlStreamEnd:
|
of yamlDocumentEnd, yamlStreamEnd:
|
||||||
yield YamlParserEvent(kind: yamlStartDocument)
|
yield YamlParserEvent(kind: yamlStartDocument)
|
||||||
yield YamlParserEvent(kind: yamlEndDocument)
|
yieldDocumentEnd()
|
||||||
else:
|
else:
|
||||||
yield YamlParserEvent(kind: yamlStartDocument)
|
yield YamlParserEvent(kind: yamlStartDocument)
|
||||||
state = ylBlockLineStart
|
state = ylBlockLineStart
|
||||||
|
@ -358,6 +366,7 @@ iterator events*(parser: var YamlSequentialParser,
|
||||||
level.mode = mScalar
|
level.mode = mScalar
|
||||||
of yamlTagHandle:
|
of yamlTagHandle:
|
||||||
handleTagHandle()
|
handleTagHandle()
|
||||||
|
level.indentationColumn = lex.column
|
||||||
state = ylBlockAfterTag
|
state = ylBlockAfterTag
|
||||||
of yamlVerbatimTag:
|
of yamlVerbatimTag:
|
||||||
tag = lex.content
|
tag = lex.content
|
||||||
|
@ -404,7 +413,7 @@ iterator events*(parser: var YamlSequentialParser,
|
||||||
break
|
break
|
||||||
of yamlDocumentEnd:
|
of yamlDocumentEnd:
|
||||||
closeAllLevels()
|
closeAllLevels()
|
||||||
yield YamlParserEvent(kind: yamlEndDocument)
|
yieldDocumentEnd()
|
||||||
state = ylInitial
|
state = ylInitial
|
||||||
of yamlOpeningBrace:
|
of yamlOpeningBrace:
|
||||||
state = ylFlow
|
state = ylFlow
|
||||||
|
@ -559,6 +568,12 @@ iterator events*(parser: var YamlSequentialParser,
|
||||||
state = ylBlockScalarHeader
|
state = ylBlockScalarHeader
|
||||||
scalarCache = ""
|
scalarCache = ""
|
||||||
level.mode = mScalar
|
level.mode = mScalar
|
||||||
|
of yamlTagHandle:
|
||||||
|
handleTagHandle()
|
||||||
|
state = ylBlockAfterTag
|
||||||
|
of yamlAnchor:
|
||||||
|
anchor = lex.content
|
||||||
|
state = ylBlockAfterAnchor
|
||||||
else:
|
else:
|
||||||
yieldError("Unexpected token (expected scalar or line end): " &
|
yieldError("Unexpected token (expected scalar or line end): " &
|
||||||
$token)
|
$token)
|
||||||
|
@ -733,8 +748,43 @@ iterator events*(parser: var YamlSequentialParser,
|
||||||
state = ylBlockLineEnd
|
state = ylBlockLineEnd
|
||||||
else:
|
else:
|
||||||
state = ylExpectingDocumentEnd
|
state = ylExpectingDocumentEnd
|
||||||
|
of yamlTagHandle:
|
||||||
|
handleTagHandle()
|
||||||
|
state = ylFlowAfterTag
|
||||||
|
of yamlAnchor:
|
||||||
|
anchor = lex.content
|
||||||
|
state = ylFlowAfterAnchor
|
||||||
else:
|
else:
|
||||||
yieldError("Unexpected token: " & $token)
|
yieldError("Unexpected token: " & $token)
|
||||||
|
of ylFlowAfterTag:
|
||||||
|
case token
|
||||||
|
of yamlTagHandle:
|
||||||
|
yieldError("Multiple tags on same node!")
|
||||||
|
of yamlAnchor:
|
||||||
|
anchor = lex.content
|
||||||
|
state = ylFlowAfterAnchorAndTag
|
||||||
|
else:
|
||||||
|
state = ylFlow
|
||||||
|
continue
|
||||||
|
of ylFlowAfterAnchor:
|
||||||
|
case token
|
||||||
|
of yamlAnchor:
|
||||||
|
yieldError("Multiple anchors on same node!")
|
||||||
|
of yamlTagHandle:
|
||||||
|
handleTagHandle()
|
||||||
|
state = ylFlowAfterAnchorAndTag
|
||||||
|
else:
|
||||||
|
state = ylFlow
|
||||||
|
continue
|
||||||
|
of ylFlowAfterAnchorAndTag:
|
||||||
|
case token
|
||||||
|
of yamlAnchor:
|
||||||
|
yieldError("Multiple anchors on same node!")
|
||||||
|
of yamlTagHandle:
|
||||||
|
yieldError("Multiple tags on same node!")
|
||||||
|
else:
|
||||||
|
state = ylFlow
|
||||||
|
continue
|
||||||
of ylFlowAfterObject:
|
of ylFlowAfterObject:
|
||||||
case token
|
case token
|
||||||
of yamlLineStart:
|
of yamlLineStart:
|
||||||
|
@ -798,10 +848,10 @@ iterator events*(parser: var YamlSequentialParser,
|
||||||
of yamlComment, yamlLineStart:
|
of yamlComment, yamlLineStart:
|
||||||
discard
|
discard
|
||||||
of yamlStreamEnd, yamlDocumentEnd:
|
of yamlStreamEnd, yamlDocumentEnd:
|
||||||
yield YamlParserEvent(kind: yamlEndDocument)
|
yieldDocumentEnd()
|
||||||
state = ylInitial
|
state = ylInitial
|
||||||
of yamlDirectivesEnd:
|
of yamlDirectivesEnd:
|
||||||
yield YamlParserEvent(kind: yamlEndDocument)
|
yieldDocumentEnd()
|
||||||
state = ylInitial
|
state = ylInitial
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -19,7 +19,7 @@ proc scalar(content: string, tag: TagId = tagNonSpecificQmark,
|
||||||
result.scalarTag = tag
|
result.scalarTag = tag
|
||||||
result.scalarContent = content
|
result.scalarContent = content
|
||||||
|
|
||||||
proc startSequence(anchor: string = nil, tag: TagId = tagNonSpecificQmark):
|
proc startSequence(tag: TagId = tagNonSpecificQmark, anchor: string = nil):
|
||||||
YamlParserEvent =
|
YamlParserEvent =
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = yamlStartSequence
|
result.kind = yamlStartSequence
|
||||||
|
@ -30,7 +30,7 @@ proc endSequence(): YamlParserEvent =
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = yamlEndSequence
|
result.kind = yamlEndSequence
|
||||||
|
|
||||||
proc startMap(anchor: string = nil, tag: TagId = tagNonSpecificQmark):
|
proc startMap(tag: TagId = tagNonSpecificQmark, anchor: string = nil):
|
||||||
YamlParserEvent =
|
YamlParserEvent =
|
||||||
new(result)
|
new(result)
|
||||||
result.kind = yamlStartMap
|
result.kind = yamlStartMap
|
||||||
|
@ -83,9 +83,7 @@ proc printDifference(expected, actual: YamlParserEvent) =
|
||||||
echo "Unknown difference in event kind " & $expected.kind
|
echo "Unknown difference in event kind " & $expected.kind
|
||||||
|
|
||||||
template ensure(input: string, expected: varargs[YamlParserEvent]) {.dirty.} =
|
template ensure(input: string, expected: varargs[YamlParserEvent]) {.dirty.} =
|
||||||
var
|
var i = 0
|
||||||
i = 0
|
|
||||||
parser = initParser()
|
|
||||||
|
|
||||||
for token in parser.events(newStringStream(input)):
|
for token in parser.events(newStringStream(input)):
|
||||||
if i >= expected.len:
|
if i >= expected.len:
|
||||||
|
@ -101,6 +99,9 @@ template ensure(input: string, expected: varargs[YamlParserEvent]) {.dirty.} =
|
||||||
i.inc()
|
i.inc()
|
||||||
|
|
||||||
suite "Parsing":
|
suite "Parsing":
|
||||||
|
setup:
|
||||||
|
var parser = initParser()
|
||||||
|
|
||||||
test "Parsing: Simple Scalar":
|
test "Parsing: Simple Scalar":
|
||||||
ensure("Scalar", startDoc(), scalar("Scalar"), endDoc())
|
ensure("Scalar", startDoc(), scalar("Scalar"), endDoc())
|
||||||
test "Parsing: Simple Sequence":
|
test "Parsing: Simple Sequence":
|
||||||
|
@ -168,3 +169,42 @@ suite "Parsing":
|
||||||
scalar("a"), scalar("ab"), endMap(), endDoc())
|
scalar("a"), scalar("ab"), endMap(), endDoc())
|
||||||
test "Parsing: non-specific tags of quoted strings":
|
test "Parsing: non-specific tags of quoted strings":
|
||||||
ensure("\"a\"", startDoc(), scalar("a", tagNonSpecificEmark), endDoc())
|
ensure("\"a\"", startDoc(), scalar("a", tagNonSpecificEmark), endDoc())
|
||||||
|
test "Parsing: explicit non-specific tag":
|
||||||
|
ensure("! a", startDoc(), scalar("a", tagNonSpecificEmark), endDoc())
|
||||||
|
test "Parsing: secondary tag handle resolution":
|
||||||
|
let id = parser.registerUri("tag:yaml.org,2002:str")
|
||||||
|
ensure("!!str a", startDoc(), scalar("a", id), endDoc())
|
||||||
|
test "Parsing: resolving custom tag handles":
|
||||||
|
let id = parser.registerUri("tag:example.com,2015:foo")
|
||||||
|
ensure("%TAG !t! tag:example.com,2015:\n---\n!t!foo a", startDoc(),
|
||||||
|
scalar("a", id), endDoc())
|
||||||
|
test "Parsing: tags in sequence":
|
||||||
|
let
|
||||||
|
idStr = parser.registerUri("tag:yaml.org,2002:str")
|
||||||
|
idInt = parser.registerUri("tag:yaml.org,2002:int")
|
||||||
|
ensure(" - !!str a\n - b\n - !!int c\n - d", startDoc(),
|
||||||
|
startSequence(), scalar("a", idStr), scalar("b"),
|
||||||
|
scalar("c", idInt), scalar("d"), endSequence(), endDoc())
|
||||||
|
test "Parsing: tags in implicit map":
|
||||||
|
let
|
||||||
|
idStr = parser.registerUri("tag:yaml.org,2002:str")
|
||||||
|
idInt = parser.registerUri("tag:yaml.org,2002:int")
|
||||||
|
ensure("!!str a: b\nc: !!int d\ne: !!str f\ng: h", startDoc(), startMap(),
|
||||||
|
scalar("a", idStr), scalar("b"), scalar("c"), scalar("d", idInt),
|
||||||
|
scalar("e"), scalar("f", idStr), scalar("g"), scalar("h"),
|
||||||
|
endMap(), endDoc())
|
||||||
|
test "Parsing: tags in explicit map":
|
||||||
|
let
|
||||||
|
idStr = parser.registerUri("tag:yaml.org,2002:str")
|
||||||
|
idInt = parser.registerUri("tag:yaml.org,2002:int")
|
||||||
|
ensure("? !!str a\n: !!int b\n? c\n: !!str d", startDoc(), startMap(),
|
||||||
|
scalar("a", idStr), scalar("b", idInt), scalar("c"),
|
||||||
|
scalar("d", idStr), endMap(), endDoc())
|
||||||
|
test "Parsing: tags for flow objects":
|
||||||
|
let
|
||||||
|
idStr = parser.registerUri("tag:yaml.org,2002:str")
|
||||||
|
idMap = parser.registerUri("tag:yaml.org,2002:map")
|
||||||
|
idSeq = parser.registerUri("tag:yaml.org,2002:seq")
|
||||||
|
ensure("!!map { k: !!seq [ a, !!str b] }", startDoc(), startMap(idMap),
|
||||||
|
scalar("k"), startSequence(idSeq), scalar("a"),
|
||||||
|
scalar("b", idStr), endSequence(), endMap(), endDoc())
|
Loading…
Reference in New Issue