Fixed more test suite failures

This commit is contained in:
Felix Krause 2016-09-14 12:18:00 +02:00
parent 2a6a103b36
commit b64e40ec41
3 changed files with 119 additions and 77 deletions

View File

@ -4,7 +4,6 @@ task build, "Compile the YAML module into a library":
setCommand "c", "yaml" setCommand "c", "yaml"
task tests, "Run all tests": task tests, "Run all tests":
--d:yamlDebug
--r --r
--verbosity:0 --verbosity:0
setCommand "c", "test/tests" setCommand "c", "test/tests"

View File

@ -60,9 +60,9 @@ type
ltYamlDirective, ltYamlVersion, ltTagDirective, ltTagShorthand, ltYamlDirective, ltYamlVersion, ltTagDirective, ltTagShorthand,
ltTagUri, ltUnknownDirective, ltUnknownDirectiveParams, ltEmptyLine, ltTagUri, ltUnknownDirective, ltUnknownDirectiveParams, ltEmptyLine,
ltDirectivesEnd, ltDocumentEnd, ltStreamEnd, ltIndentation, ltQuotedScalar, ltDirectivesEnd, ltDocumentEnd, ltStreamEnd, ltIndentation, ltQuotedScalar,
ltScalarPart, ltBlockScalarHeader, ltSeqItemInd, ltMapKeyInd, ltMapValInd, ltScalarPart, ltBlockScalarHeader, ltBlockScalar, ltSeqItemInd, ltMapKeyInd,
ltBraceOpen, ltBraceClose, ltBracketOpen, ltBracketClose, ltComma, ltMapValInd, ltBraceOpen, ltBraceClose, ltBracketOpen, ltBracketClose,
ltLiteralTag, ltTagHandle, ltAnchor, ltAlias ltComma, ltLiteralTag, ltTagHandle, ltAnchor, ltAlias
ChompType* = enum ChompType* = enum
ctKeep, ctClip, ctStrip ctKeep, ctClip, ctStrip
@ -469,7 +469,7 @@ proc outsideDoc[T](lex: YamlLexer): bool =
return false return false
of '.': of '.':
lex.indentation = 0 lex.indentation = 0
lex.nextState = possibleDocumentEnd[T] if possibleDocumentEnd[T](lex): return true
of spaceOrLineEnd + {'#'}: of spaceOrLineEnd + {'#'}:
lex.indentation = 0 lex.indentation = 0
while lex.c == ' ': while lex.c == ' ':
@ -499,6 +499,7 @@ proc insideDoc[T](lex: YamlLexer): bool =
while lex.c == ' ': while lex.c == ' ':
lex.indentation.inc() lex.indentation.inc()
lex.advance(T) lex.advance(T)
while lex.c in space: lex.advance(T)
case lex.c case lex.c
of lineEnd: of lineEnd:
lex.cur = ltEmptyLine lex.cur = ltEmptyLine
@ -541,7 +542,7 @@ proc flowIndicator[T](lex: YamlLexer, indicator: LexerToken): bool {.inline.} =
lex.cur = indicator lex.cur = indicator
lex.advance(T) lex.advance(T)
while lex.c in space: lex.advance(T) while lex.c in space: lex.advance(T)
if lex.c in lineEnd: if lex.c in lineEnd + {'#'}:
lex.nextState = expectLineEnd[T] lex.nextState = expectLineEnd[T]
result = true result = true
@ -598,6 +599,9 @@ proc singleQuotedScalar[T](lex: YamlLexer) =
continue continue
else: lex.buf.add(lex.c) else: lex.buf.add(lex.c)
lex.advance(T) lex.advance(T)
while lex.c in space: lex.advance(T)
if lex.c in lineEnd + {'#'}:
lex.nextState = expectLineEnd[T]
proc unicodeSequence[T](lex: YamlLexer, length: int) = proc unicodeSequence[T](lex: YamlLexer, length: int) =
debug("lex: unicodeSequence") debug("lex: unicodeSequence")
@ -667,6 +671,9 @@ proc doubleQuotedScalar[T](lex: YamlLexer) =
continue continue
else: lex.buf.add(lex.c) else: lex.buf.add(lex.c)
lex.advance(T) lex.advance(T)
while lex.c in space: lex.advance(T)
if lex.c in lineEnd + {'#'}:
lex.nextState = expectLineEnd[T]
proc insideLine[T](lex: YamlLexer): bool = proc insideLine[T](lex: YamlLexer): bool =
debug("lex: insideLine") debug("lex: insideLine")
@ -786,7 +793,7 @@ proc blockScalarHeader[T](lex: YamlLexer): bool =
of '1'..'9': of '1'..'9':
if lex.blockScalarIndent != UnknownIndentation: if lex.blockScalarIndent != UnknownIndentation:
raise generateError[T](lex, "Only one indentation indicator is allowed") raise generateError[T](lex, "Only one indentation indicator is allowed")
lex.blockScalarIndent = lex.indentation + ord(lex.c) - ord('\x30') lex.blockScalarIndent = ord(lex.c) - ord('\x30')
of spaceOrLineEnd: break of spaceOrLineEnd: break
else: else:
raise generateError[T](lex, raise generateError[T](lex,
@ -794,11 +801,75 @@ proc blockScalarHeader[T](lex: YamlLexer): bool =
'\'') '\'')
lex.nextState = expectLineEnd[T] lex.nextState = expectLineEnd[T]
lex.lineStartState = blockScalar[T] lex.lineStartState = blockScalar[T]
result = false lex.cur = ltBlockScalarHeader
result = true
proc blockScalarLineStart[T](lex: YamlLexer, recentWasMoreIndented: var bool):
bool =
while true:
case lex.c
of '-':
if lex.indentation < lex.blockScalarIndent:
lex.nextState = indentationAfterBlockScalar[T]
return false
discard possibleDirectivesEnd[T](lex)
case lex.cur
of ltDirectivesEnd:
lex.nextState = dirEndAfterBlockScalar[T]
return false
of ltIndentation:
if lex.nextState == afterSeqInd[T]:
lex.consumeNewlines()
lex.buf.add("- ")
else: discard
break
of '.':
if lex.indentation < lex.blockScalarIndent:
lex.nextState = indentationAfterBlockScalar[T]
return false
if possibleDocumentEnd[T](lex):
lex.nextState = docEndAfterBlockScalar[T]
return false
break
of spaceOrLineEnd:
while lex.c == ' ' and lex.indentation < lex.blockScalarIndent:
lex.indentation.inc()
lex.advance(T)
case lex.c
of '\l':
lex.newlines.inc()
lex.lexLF(T)
lex.indentation = 0
of '\c':
lex.newlines.inc()
lex.lexCR(T)
lex.indentation = 0
of EndOfFile:
lex.nextState = streamEnd
return false
of ' ', '\t':
recentWasMoreIndented = true
lex.buf.add(repeat('\l', lex.newlines))
lex.newlines = 0
return true
else: break
else: break
if lex.indentation < lex.blockScalarIndent:
lex.nextState = indentationAfterBlockScalar[T]
return false
if lex.folded and not recentWasMoreIndented: lex.consumeNewlines()
else:
recentWasMoreIndented = false
lex.buf.add(repeat('\l', lex.newlines))
lex.newlines = 0
result = true
proc blockScalar[T](lex: YamlLexer): bool = proc blockScalar[T](lex: YamlLexer): bool =
debug("lex: blockScalar") debug("lex: blockScalar")
block outer: block outer:
var recentWasMoreIndented = true
if lex.blockScalarIndent == UnknownIndentation: if lex.blockScalarIndent == UnknownIndentation:
while true: while true:
lex.blockScalarIndent = 0 lex.blockScalarIndent = 0
@ -806,8 +877,12 @@ proc blockScalar[T](lex: YamlLexer): bool =
lex.blockScalarIndent.inc() lex.blockScalarIndent.inc()
lex.advance(T) lex.advance(T)
case lex.c case lex.c
of '\l': lex.lexLF(T) of '\l':
of '\c': lex.lexCR(T) lex.lexLF(T)
lex.newlines.inc()
of '\c':
lex.lexCR(T)
lex.newlines.inc()
of EndOfFile: of EndOfFile:
lex.nextState = streamEnd lex.nextState = streamEnd
break outer break outer
@ -818,77 +893,23 @@ proc blockScalar[T](lex: YamlLexer): bool =
break outer break outer
lex.indentation = lex.blockScalarIndent lex.indentation = lex.blockScalarIndent
break break
var recentWasMoreIndented = false
while true:
block lineStart:
case lex.c
of '-':
if lex.indentation < lex.blockScalarIndent:
lex.nextState = indentationAfterBlockScalar[T]
break outer
discard possibleDirectivesEnd[T](lex)
case lex.cur
of ltDirectivesEnd:
lex.nextState = dirEndAfterBlockScalar[T]
break outer
of ltIndentation:
if lex.nextState == afterSeqInd[T]:
lex.consumeNewlines()
lex.buf.add("- ")
else: discard
of '.':
if lex.indentation < lex.blockScalarIndent:
lex.nextState = indentationAfterBlockScalar[T]
break outer
if possibleDocumentEnd[T](lex):
lex.nextState = docEndAfterBlockScalar[T]
discard
of spaceOrLineEnd:
while lex.c == ' ' and lex.indentation < lex.blockScalarIndent:
lex.indentation.inc()
lex.advance(T)
case lex.c
of '\l':
lex.newlines.inc()
lex.lexLF(T)
lex.indentation = 0
continue
of '\c':
lex.newlines.inc()
lex.lexCR(T)
lex.indentation = 0
continue
of EndOfFile:
lex.nextState = streamEnd
break outer
of ' ':
recentWasMoreIndented = true
lex.buf.add(repeat('\l', lex.newlines))
lex.newlines = 0
break lineStart
else: discard
else: discard
if lex.indentation < lex.blockScalarIndent:
lex.nextState = indentationAfterBlockScalar[T]
break outer
if lex.folded and not recentWasMoreIndented: lex.consumeNewlines()
else: else:
recentWasMoreIndented = false lex.blockScalarIndent += lex.indentation
lex.buf.add(repeat('\l', lex.newlines)) if not blockScalarLineStart[T](lex, recentWasMoreIndented): break outer
lex.newlines = 0 while true:
while lex.c notin lineEnd: while lex.c notin lineEnd:
lex.buf.add(lex.c) lex.buf.add(lex.c)
lex.advance(T) lex.advance(T)
if not blockScalarLineStart[T](lex, recentWasMoreIndented): break outer
case lex.chomp case lex.chomp
of ctStrip: discard of ctStrip: discard
of ctClip: lex.buf.add('\l') of ctClip:
if lex.buf.len > 0: lex.buf.add('\l')
of ctKeep: lex.buf.add(repeat('\l', lex.newlines)) of ctKeep: lex.buf.add(repeat('\l', lex.newlines))
lex.newlines = 0 lex.newlines = 0
lex.lineStartState = insideDoc[T] lex.lineStartState = insideDoc[T]
lex.cur = ltQuotedScalar lex.cur = ltBlockScalar
result = true result = true
proc indentationAfterBlockScalar[T](lex: YamlLexer): bool = proc indentationAfterBlockScalar[T](lex: YamlLexer): bool =
@ -904,11 +925,13 @@ proc dirEndAfterBlockScalar[T](lex: YamlLexer): bool =
lex.cur = ltDirectivesEnd lex.cur = ltDirectivesEnd
while lex.c in space: lex.advance(T) while lex.c in space: lex.advance(T)
lex.nextState = lex.insideLineImpl lex.nextState = lex.insideLineImpl
result = true
proc docEndAfterBlockScalar[T](lex: YamlLexer): bool = proc docEndAfterBlockScalar[T](lex: YamlLexer): bool =
lex.cur = ltDocumentEnd lex.cur = ltDocumentEnd
lex.nextState = expectLineEnd[T] lex.nextState = expectLineEnd[T]
lex.lineStartState = lex.outsideDocImpl lex.lineStartState = lex.outsideDocImpl
result = true
proc byteSequence[T](lex: YamlLexer) = proc byteSequence[T](lex: YamlLexer) =
debug("lex: byteSequence") debug("lex: byteSequence")

View File

@ -339,7 +339,7 @@ macro parserState(name: untyped, impl: untyped): typed =
parserStates(initial, blockLineStart, blockObjectStart, blockAfterObject, parserStates(initial, blockLineStart, blockObjectStart, blockAfterObject,
scalarEnd, plainScalarEnd, objectEnd, expectDocEnd, startDoc, scalarEnd, plainScalarEnd, objectEnd, expectDocEnd, startDoc,
afterDocument, closeStream, closeMoreIndentedLevels, endDoc, afterDocument, closeStream, closeMoreIndentedLevels,
emitEmptyScalar, tagHandle, anchor, alias, flow, leaveFlowMap, emitEmptyScalar, tagHandle, anchor, alias, flow, leaveFlowMap,
leaveFlowSeq, flowAfterObject, leaveFlowSinglePairMap) leaveFlowSeq, flowAfterObject, leaveFlowSinglePairMap)
@ -465,11 +465,15 @@ parserState initial:
result = true result = true
c.advance() c.advance()
state = blockObjectStart state = blockObjectStart
of ltDocumentEnd:
e = startDocEvent()
result = true
state = endDoc
else: internalError("Unexpected lexer token: " & $c.lex.cur) else: internalError("Unexpected lexer token: " & $c.lex.cur)
parserState blockLineStart: parserState blockLineStart:
case c.lex.cur case c.lex.cur
of ltIndentation: discard of ltIndentation: c.advance()
of ltEmptyLine: c.advance() of ltEmptyLine: c.advance()
of ltStreamEnd: of ltStreamEnd:
c.closeEverything() c.closeEverything()
@ -502,16 +506,24 @@ parserState blockObjectStart:
result = c.handleBlockItemStart(e) result = c.handleBlockItemStart(e)
c.advance() c.advance()
state = scalarEnd state = scalarEnd
of ltBlockScalarHeader:
c.lex.indentation = c.ancestry[^1].indentation
c.advance()
assert c.lex.cur == ltBlockScalar
if c.level.indentation == UnknownIndentation:
c.level.indentation = c.lex.indentation
c.advance()
state = scalarEnd
of ltScalarPart: of ltScalarPart:
result = c.handleBlockItemStart(e) result = c.handleBlockItemStart(e)
while true: while true:
c.advance() c.advance()
c.lex.newlines.inc()
case c.lex.cur case c.lex.cur
of ltEmptyLine: c.lex.newlines.inc()
of ltIndentation: of ltIndentation:
if c.lex.indentation <= c.ancestry[^1].indentation: break if c.lex.indentation <= c.ancestry[^1].indentation: break
c.lex.newlines.inc()
of ltScalarPart: discard of ltScalarPart: discard
of ltEmptyLine: c.lex.newlines.inc()
else: break else: break
c.lex.newlines = 0 c.lex.newlines = 0
state = plainScalarEnd state = plainScalarEnd
@ -534,6 +546,9 @@ parserState blockObjectStart:
result = c.handleBlockItemStart(e) result = c.handleBlockItemStart(e)
c.lex.setFlow(true) c.lex.setFlow(true)
state = flow state = flow
of ltStreamEnd:
c.closeEverything()
stored = afterDocument
else: else:
raise c.generateError("Unexpected token: " & $c.lex.cur) raise c.generateError("Unexpected token: " & $c.lex.cur)
@ -617,10 +632,15 @@ parserState startDoc:
result = true result = true
state = blockObjectStart state = blockObjectStart
parserState endDoc:
e = endDocEvent()
result = true
state = initial
parserState afterDocument: parserState afterDocument:
case c.lex.cur case c.lex.cur
of ltStreamEnd: c.isFinished = true of ltStreamEnd: c.isFinished = true
of ltIndentation, ltEmptyLine, ltDocumentEnd: c.advance() of ltEmptyLine: c.advance()
else: else:
c.initDocValues() c.initDocValues()
state = initial state = initial