From 32f36515e7317cc14094c9ac60ce8825b0b7be7a Mon Sep 17 00:00:00 2001 From: Felix Krause Date: Mon, 21 Dec 2015 21:58:28 +0100 Subject: [PATCH] Return TagIds instead of strings --- src/yaml/sequential.nim | 47 ++++++++++++++++++++++++++++++++--------- test/parsing.nim | 34 +++++++++++------------------ 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/src/yaml/sequential.nim b/src/yaml/sequential.nim index 7a320ce..0943b5c 100644 --- a/src/yaml/sequential.nim +++ b/src/yaml/sequential.nim @@ -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, diff --git a/test/parsing.nim b/test/parsing.nim index 54c99d6..3343c12 100644 --- a/test/parsing.nim +++ b/test/parsing.nim @@ -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 , got " & actual.scalarTag - elif isNil(actual.scalarTag): - echo "[\"" & actual.scalarContent & - "\".tag] expected " & expected.scalarTag & - ", got " - 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 , got " & actual.objTag - elif isNil(actual.objTag): - echo "[object.tag] expected " & expected.objTag & - ", got " - 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()) \ No newline at end of file + scalar("a"), scalar("ab"), endMap(), endDoc()) + test "Parsing: non-specific tags of quoted strings": + ensure("\"a\"", startDoc(), scalar("a", tagNonSpecificEmark), endDoc()) \ No newline at end of file