Return TagIds instead of strings

This commit is contained in:
Felix Krause 2015-12-21 21:58:28 +01:00
parent 70597105cb
commit 32f36515e7
2 changed files with 49 additions and 32 deletions

View File

@ -8,14 +8,16 @@ type
yamlStartSequence, yamlEndSequence, yamlScalar, yamlAlias,
yamlError, yamlWarning
TagId* = distinct int
YamlParserEvent* = ref object
case kind*: YamlParserEventKind
of yamlStartMap, yamlStartSequence:
objAnchor* : string # may be nil, may not be empty
objTag* : string # may not be nil or empty, is a complete URI.
objTag* : TagId
of yamlScalar:
scalarAnchor* : string # may be nil
scalarTag* : string # may not be nil, is a complete URI.
scalarTag* : TagId
scalarContent*: string # may not be nil (but empty)
of yamlEndMap, yamlEndSequence, yamlStartDocument, yamlEndDocument:
discard
@ -49,8 +51,6 @@ type
BlockScalarStyle = enum
bsLiteral, bsFolded
TagId = distinct int
YamlSequentialParser* = object
tags: OrderedTable[string, TagId]
@ -63,6 +63,7 @@ const
proc `==`*(left: YamlParserEvent, right: YamlParserEvent): bool
proc `==`*(left, right: TagId): bool {.borrow.}
proc `$`*(id: TagId): string {.borrow.}
proc initParser*(): YamlSequentialParser
@ -122,7 +123,16 @@ template yieldError(d: string) {.dirty.} =
break parserLoop
template yieldScalar(content: string = "", quoted: bool = false) {.dirty.} =
let retTag = if isNil(tag): if quoted: "!" else: "?" else: tag
var retTag: TagId
if isNil(tag):
retTag = if quoted: tagNonSpecificEmark else: tagNonSpecificQmark
else:
try:
retTag = parser.tags[tag]
except KeyError:
retTag = cast[TagId](parser.tags.len)
parser.tags[tag] = retTag
yield YamlParserEvent(kind: yamlScalar,
scalarAnchor: anchor, scalarTag: retTag,
scalarContent: content)
@ -130,7 +140,16 @@ template yieldScalar(content: string = "", quoted: bool = false) {.dirty.} =
tag = nil
template yieldStart(k: YamlParserEventKind) {.dirty.} =
let retTag = if isNil(tag): "?" else: tag
var retTag: TagId
if isNil(tag):
retTag = tagNonSpecificQmark
else:
try:
retTag = parser.tags[tag]
except KeyError:
retTag = cast[TagId](parser.tags.len)
parser.tags[tag] = retTag
yield YamlParserEvent(kind: k, objAnchor: anchor, objTag: retTag)
anchor = nil
tag = nil
@ -145,8 +164,15 @@ template closeLevel(lvl: DocumentLevel) {.dirty.} =
of mBlockSequenceItem, mFlowSequenceItem:
yield YamlParserEvent(kind: yamlEndSequence)
of mScalar:
let retTag = if isNil(tag): if scalarCacheIsQuoted: "!" else: "?" else:
tag
var retTag: TagId
if isNil(tag):
retTag = tagNonSpecificQmark
else:
try:
retTag = parser.tags[tag]
except KeyError:
retTag = cast[TagId](parser.tags.len)
parser.tags[tag] = retTag
yield YamlParserEvent(kind: yamlScalar, scalarAnchor: anchor,
scalarTag: retTag, scalarContent: scalarCache)
@ -217,7 +243,7 @@ template handleTagHandle() {.dirty.} =
else:
yieldError("Unknown tag shorthand: " & handle)
iterator events*(parser: YamlSequentialParser,
iterator events*(parser: var YamlSequentialParser,
input: Stream): YamlParserEvent {.closure.} =
var
# parsing state
@ -424,7 +450,8 @@ iterator events*(parser: YamlSequentialParser,
level.indentationColumn = scalarIndentation
# tags and anchors are for key scalar, not for map.
yield YamlParserEvent(kind: yamlStartMap,
objAnchor: nil, objTag: "?")
objAnchor: nil,
objTag: tagNonSpecificQmark)
level.mode = mImplicitBlockMapValue
ancestry.add(level)
level = DocumentLevel(mode: mUnknown, indicatorColumn: -1,

View File

@ -11,7 +11,7 @@ proc endDoc(): YamlParserEvent =
new(result)
result.kind = yamlEndDocument
proc scalar(content: string, tag: string = "?",
proc scalar(content: string, tag: TagId = tagNonSpecificQmark,
anchor: string = nil): YamlParserEvent =
new(result)
result.kind = yamlScalar
@ -19,7 +19,8 @@ proc scalar(content: string, tag: string = "?",
result.scalarTag = tag
result.scalarContent = content
proc startSequence(anchor: string = nil, tag: string = "?"): YamlParserEvent =
proc startSequence(anchor: string = nil, tag: TagId = tagNonSpecificQmark):
YamlParserEvent =
new(result)
result.kind = yamlStartSequence
result.objAnchor = anchor
@ -29,7 +30,8 @@ proc endSequence(): YamlParserEvent =
new(result)
result.kind = yamlEndSequence
proc startMap(anchor: string = nil, tag: string = "?"): YamlParserEvent =
proc startMap(anchor: string = nil, tag: TagId = tagNonSpecificQmark):
YamlParserEvent =
new(result)
result.kind = yamlStartMap
result.objAnchor = anchor
@ -51,17 +53,8 @@ proc printDifference(expected, actual: YamlParserEvent) =
case expected.kind
of yamlScalar:
if expected.scalarTag != actual.scalarTag:
if isNil(expected.scalarTag):
echo "[\"" & actual.scalarContent &
"\".tag] expected <nil>, got " & actual.scalarTag
elif isNil(actual.scalarTag):
echo "[\"" & actual.scalarContent &
"\".tag] expected " & expected.scalarTag &
", got <nil>"
else:
echo "[\"" & actual.scalarContent &
"\".tag] expected tag " & expected.scalarTag &
", got " & actual.scalarTag
echo "[\"", actual.scalarContent, "\".tag] expected tag ",
expected.scalarTag, ", got ", actual.scalarTag
elif expected.scalarAnchor != actual.scalarAnchor:
echo "[scalar] expected anchor " & expected.scalarAnchor &
", got " & actual.scalarAnchor
@ -84,13 +77,8 @@ proc printDifference(expected, actual: YamlParserEvent) =
echo "[scalar] Unknown difference"
of yamlStartMap, yamlStartSequence:
if expected.objTag != actual.objTag:
if isNil(expected.objTag):
echo "[object.tag] expected <nil>, got " & actual.objTag
elif isNil(actual.objTag):
echo "[object.tag] expected " & expected.objTag &
", got <nil>"
else:
echo ""
echo "[object.tag] expected ", expected.objTag, ", got",
actual.objTag
else:
echo "Unknown difference in event kind " & $expected.kind
@ -177,4 +165,6 @@ suite "Parsing":
scalar("a"), scalar("ab\x0A\x0A \x0A"), endMap(), endDoc())
test "Parsing: Block scalar (strip)":
ensure("a: |-\x0A ab\x0A \x0A \x0A", startDoc(), startMap(),
scalar("a"), scalar("ab"), endMap(), endDoc())
scalar("a"), scalar("ab"), endMap(), endDoc())
test "Parsing: non-specific tags of quoted strings":
ensure("\"a\"", startDoc(), scalar("a", tagNonSpecificEmark), endDoc())