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

View File

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