Made token output conform to yaml test suite

* Added -d:yamlScalarRepInd switch
 * Modified `$` on stream items to use yaml test suite format
This commit is contained in:
Felix Krause 2017-02-14 19:06:41 +01:00
parent 5ebde01ca5
commit 58ef5da17b
5 changed files with 93 additions and 29 deletions

View File

@ -72,6 +72,7 @@ task clean, "Remove all generated files":
task server, "Compile server daemon": task server, "Compile server daemon":
--d:release --d:release
--d:yamlScalarRepInd
setCommand "c", "server/server" setCommand "c", "server/server"
task testSuiteEvents, "Compile the testSuiteEvents tool": task testSuiteEvents, "Compile the testSuiteEvents tool":

View File

@ -32,10 +32,11 @@ routes:
of "block": style = psBlockOnly of "block": style = psBlockOnly
of "tokens": of "tokens":
var var
output = "" output = "+STR\n"
parser = newYamlParser() parser = newYamlParser()
events = parser.parse(newStringStream(@"input")) events = parser.parse(newStringStream(@"input"))
for event in events: output.add($event & "\n") for event in events: output.add($event & "\n")
output &= "-STR"
resultNode["code"] = %0 resultNode["code"] = %0
resultNode["output"] = %output resultNode["output"] = %output
msg = resultNode.pretty msg = resultNode.pretty

View File

@ -143,6 +143,9 @@ proc initLevel(k: FastParseLevelKind): FastParseLevel {.raises: [], inline.} =
FastParseLevel(kind: k, indentation: UnknownIndentation) FastParseLevel(kind: k, indentation: UnknownIndentation)
proc emptyScalar(c: ParserContext): YamlStreamEvent {.raises: [], inline.} = proc emptyScalar(c: ParserContext): YamlStreamEvent {.raises: [], inline.} =
when defined(yamlScalarRepInd):
result = scalarEvent("", c.tag, c.anchor, srPlain)
else:
result = scalarEvent("", c.tag, c.anchor) result = scalarEvent("", c.tag, c.anchor)
c.tag = yTagQuestionMark c.tag = yTagQuestionMark
c.anchor = yAnchorNone c.anchor = yAnchorNone
@ -244,6 +247,12 @@ proc handlePossibleMapStart(c: ParserContext, e: var YamlStreamEvent,
result = true result = true
c.level.indentation = c.lex.indentation c.level.indentation = c.lex.indentation
template implicitScalar(): YamlStreamEvent =
when defined(yamlScalarRepInd):
scalarEvent("", yTagQuestionMark, yAnchorNone, srPlain)
else:
scalarEvent("", yTagQuestionMark, yAnchorNone)
proc handleMapKeyIndicator(c: ParserContext, e: var YamlStreamEvent): bool = proc handleMapKeyIndicator(c: ParserContext, e: var YamlStreamEvent): bool =
result = false result = false
case c.level.kind case c.level.kind
@ -255,7 +264,7 @@ proc handleMapKeyIndicator(c: ParserContext, e: var YamlStreamEvent): bool =
raise c.generateError("Invalid p.indentation of map key indicator " & raise c.generateError("Invalid p.indentation of map key indicator " &
"(expected" & $c.level.indentation & ", got " & $c.lex.indentation & "(expected" & $c.level.indentation & ", got " & $c.lex.indentation &
")") ")")
e = scalarEvent("", yTagQuestionMark, yAnchorNone) e = implicitScalar()
result = true result = true
c.level.kind = fplMapKey c.level.kind = fplMapKey
c.ancestry.add(c.level) c.ancestry.add(c.level)
@ -456,7 +465,7 @@ proc handleMapValueIndicator(c: ParserContext, e: var YamlStreamEvent): bool =
of fplMapKey: of fplMapKey:
if c.level.indentation != c.lex.indentation: if c.level.indentation != c.lex.indentation:
raise c.generateError("Invalid p.indentation of map key indicator") raise c.generateError("Invalid p.indentation of map key indicator")
e = scalarEvent("", yTagQuestionMark, yAnchorNone) e = implicitScalar()
result = true result = true
c.level.kind = fplMapValue c.level.kind = fplMapValue
c.ancestry.add(c.level) c.ancestry.add(c.level)
@ -640,6 +649,12 @@ parserState blockObjectStart:
parserState scalarEnd: parserState scalarEnd:
if c.tag == yTagQuestionMark: c.tag = yTagExclamationMark if c.tag == yTagQuestionMark: c.tag = yTagExclamationMark
c.currentScalar(e) c.currentScalar(e)
when defined(yamlScalarRepInd):
case c.lex.scalarKind
of skSingleQuoted: e.scalarRep = srSingleQuoted
of skDoubleQuoted: e.scalarRep = srDoubleQuoted
of skLiteral: e.scalarRep = srLiteral
of skFolded: e.scalarRep = srFolded
result = true result = true
state = objectEnd state = objectEnd
stored = blockAfterObject stored = blockAfterObject
@ -671,7 +686,7 @@ parserState blockAfterObject:
e = c.objectStart(yamlStartMap) e = c.objectStart(yamlStartMap)
result = true result = true
of fplMapKey: of fplMapKey:
e = scalarEvent("", yTagQuestionMark, yAnchorNone) e = implicitScalar()
result = true result = true
c.level.kind = fplMapValue c.level.kind = fplMapValue
c.ancestry.add(c.level) c.ancestry.add(c.level)
@ -771,7 +786,7 @@ parserState closeMoreIndentedLevels:
state = stored state = stored
parserState emitEmptyScalar: parserState emitEmptyScalar:
e = scalarEvent("", yTagQuestionMark, yAnchorNone) e = implicitScalar()
result = true result = true
state = stored state = stored
@ -989,7 +1004,7 @@ parserState flowAfterObject:
case c.level.kind case c.level.kind
of fplSequence: discard of fplSequence: discard
of fplMapValue: of fplMapValue:
e = scalarEvent("", yTagQuestionMark, yAnchorNone) e = implicitScalar()
result = true result = true
c.level.kind = fplMapKey c.level.kind = fplMapKey
c.explicitFlowKey = false c.explicitFlowKey = false

View File

@ -9,6 +9,10 @@ when defined(yamlDebug):
import terminal import terminal
export terminal export terminal
when defined(yamlScalarRepInd):
type ScalarKind* = enum
skSingleQuoted, skDoubleQuoted, skLiteral, skFolded
type type
StringSource* = object StringSource* = object
src: string src: string
@ -30,6 +34,9 @@ type
indentation*: int indentation*: int
# ltTagHandle # ltTagHandle
shorthandEnd*: int shorthandEnd*: int
when defined(yamlScalarRepInd):
# ltQuotedScalar, ltBlockScalarHeader
scalarKind*: ScalarKind
# may be modified from outside; will be consumed at plain scalar starts # may be modified from outside; will be consumed at plain scalar starts
newlines*: int newlines*: int
@ -585,6 +592,7 @@ proc processQuotedWhitespace[T](lex: YamlLexer, newlines: var int) =
proc singleQuotedScalar[T](lex: YamlLexer) = proc singleQuotedScalar[T](lex: YamlLexer) =
debug("lex: singleQuotedScalar") debug("lex: singleQuotedScalar")
startToken[T](lex) startToken[T](lex)
when defined(yamlScalarRepInd): lex.scalarKind = skSingleQuoted
lex.advance(T) lex.advance(T)
while true: while true:
case lex.c case lex.c
@ -627,6 +635,7 @@ proc unicodeSequence[T](lex: YamlLexer, length: int) =
proc doubleQuotedScalar[T](lex: YamlLexer) = proc doubleQuotedScalar[T](lex: YamlLexer) =
debug("lex: doubleQuotedScalar") debug("lex: doubleQuotedScalar")
startToken[T](lex) startToken[T](lex)
when defined(yamlScalarRepInd): lex.scalarKind = skDoubleQuoted
lex.advance(T) lex.advance(T)
while true: while true:
case lex.c case lex.c
@ -778,6 +787,8 @@ proc blockScalarHeader[T](lex: YamlLexer): bool =
lex.chomp = ctClip lex.chomp = ctClip
lex.blockScalarIndent = UnknownIndentation lex.blockScalarIndent = UnknownIndentation
lex.folded = lex.c == '>' lex.folded = lex.c == '>'
when defined(yamlScalarRepInd):
lex.scalarKind = if lex.folded: skFolded else: skLiteral
startToken[T](lex) startToken[T](lex)
while true: while true:
lex.advance(T) lex.advance(T)

View File

@ -15,6 +15,10 @@
import hashes import hashes
import private/internal, taglib import private/internal, taglib
when defined(yamlScalarRepInd):
type ScalarRepresentationIndicator* = enum
srPlain, srSingleQuoted, srDoubleQuoted, srLiteral, srFolded
type type
AnchorId* = distinct int ## \ AnchorId* = distinct int ## \
## An ``AnchorId`` identifies an anchor in the current document. It ## An ``AnchorId`` identifies an anchor in the current document. It
@ -52,6 +56,8 @@ type
scalarAnchor* : AnchorId scalarAnchor* : AnchorId
scalarTag* : TagId scalarTag* : TagId
scalarContent*: string # may not be nil (but empty) scalarContent*: string # may not be nil (but empty)
when defined(yamlScalarRepInd):
scalarRep* : ScalarRepresentationIndicator
of yamlEndMap, yamlEndSeq, yamlStartDoc, yamlEndDoc: discard of yamlEndMap, yamlEndSeq, yamlStartDoc, yamlEndDoc: discard
of yamlAlias: of yamlAlias:
aliasTarget* : AnchorId aliasTarget* : AnchorId
@ -97,8 +103,7 @@ proc noLastContext(s: YamlStream, line, column: var int,
proc basicInit*(s: YamlStream, lastTokenContextImpl: proc basicInit*(s: YamlStream, lastTokenContextImpl:
proc(s: YamlStream, line, column: var int, lineContent: var string): bool proc(s: YamlStream, line, column: var int, lineContent: var string): bool
{.raises: [].} = noLastContext) {.raises: [].} = noLastContext) {.raises: [].} =
{.raises: [].} =
## initialize basic values of the YamlStream. Call this in your constructor ## initialize basic values of the YamlStream. Call this in your constructor
## if you subclass YamlStream. ## if you subclass YamlStream.
s.peeked = false s.peeked = false
@ -240,25 +245,46 @@ proc `==`*(left: YamlStreamEvent, right: YamlStreamEvent): bool {.raises: [].} =
left.scalarContent == right.scalarContent left.scalarContent == right.scalarContent
of yamlAlias: result = left.aliasTarget == right.aliasTarget of yamlAlias: result = left.aliasTarget == right.aliasTarget
proc renderAttrs(tag: TagId, anchor: AnchorId): string =
result = ""
case tag
of yTagQuestionmark: discard
of yTagExclamationmark: result &= " !"
else: result &= " !<" & $tag & ">"
if anchor != yAnchorNone: result &= " &" & $anchor
proc yamlEscape(s: string): string =
result = ""
for c in s:
case c
of '\l': result.add("\\n")
of '\c': result.add("\\c")
of '\\': result.add("\\\\")
else: result.add(c)
proc `$`*(event: YamlStreamEvent): string {.raises: [].} = proc `$`*(event: YamlStreamEvent): string {.raises: [].} =
## outputs a human-readable string describing the given event ## outputs a human-readable string describing the given event.
## This string is compatible to the format used in the yaml test suite.
result = $event.kind & '(' result = $event.kind & '('
case event.kind case event.kind
of yamlEndMap, yamlEndSeq, yamlStartDoc, yamlEndDoc: discard of yamlEndMap: result = "-MAP"
of yamlStartMap: of yamlEndSeq: result = "-SEQ"
result &= "tag=" & $event.mapTag of yamlStartDoc: result = "+DOC"
if event.mapAnchor != yAnchorNone: result &= ", anchor=" & $event.mapAnchor of yamlEndDoc: result = "-DOC"
of yamlStartSeq: of yamlStartMap: result = "+MAP" & renderAttrs(event.mapTag, event.mapAnchor)
result &= "tag=" & $event.seqTag of yamlStartSeq: result = "+SEQ" & renderAttrs(event.seqTag, event.seqAnchor)
if event.seqAnchor != yAnchorNone: result &= ", anchor=" & $event.seqAnchor
of yamlScalar: of yamlScalar:
result &= "tag=" & $event.scalarTag result = "=VAL" & renderAttrs(event.scalarTag, event.scalarAnchor)
if event.scalarAnchor != yAnchorNone: when defined(yamlScalarRepInd):
result &= ", anchor=" & $event.scalarAnchor case event.scalarRep
result &= ", content=\"" & event.scalarContent & '\"' of srPlain: result &= " :"
of yamlAlias: of srSingleQuoted: result &= " \'"
result &= "aliasTarget=" & $event.aliasTarget of srDoubleQuoted: result &= " \""
result &= ")" of srLiteral: result &= " |"
of srFolded: result &= " >"
else: result &= " :"
result &= yamlEscape(event.scalarContent)
of yamlAlias: result = "=ALI *" & $event.aliasTarget
proc tag*(event: YamlStreamEvent): TagId {.raises: [FieldError].} = proc tag*(event: YamlStreamEvent): TagId {.raises: [FieldError].} =
## returns the tag of the given event ## returns the tag of the given event
@ -294,6 +320,16 @@ proc endSeqEvent*(): YamlStreamEvent {.inline, raises: [].} =
## creates a new event that marks the end of a YAML sequence ## creates a new event that marks the end of a YAML sequence
result = YamlStreamEvent(kind: yamlEndSeq) result = YamlStreamEvent(kind: yamlEndSeq)
when defined(yamlScalarRepInd):
proc scalarEvent*(content: string = "", tag: TagId = yTagQuestionMark,
anchor: AnchorId = yAnchorNone,
scalarRep: ScalarRepresentationIndicator = srPlain):
YamlStreamEvent {.inline, raises: [].} =
## creates a new event that represents a YAML scalar
result = YamlStreamEvent(kind: yamlScalar, scalarTag: tag,
scalarAnchor: anchor, scalarContent: content,
scalarRep: scalarRep)
else:
proc scalarEvent*(content: string = "", tag: TagId = yTagQuestionMark, proc scalarEvent*(content: string = "", tag: TagId = yTagQuestionMark,
anchor: AnchorId = yAnchorNone): YamlStreamEvent {.inline, raises: [].} = anchor: AnchorId = yAnchorNone): YamlStreamEvent {.inline, raises: [].} =
## creates a new event that represents a YAML scalar ## creates a new event that represents a YAML scalar