lexer: Flow indicators

This commit is contained in:
Felix Krause 2016-09-10 17:33:58 +02:00
parent ba02b41555
commit 8e7b3b32bb
2 changed files with 27 additions and 8 deletions

View File

@ -432,12 +432,13 @@ proc possibleIndicatorChar[T](lex: YamlLexer[T], indicator: LexerToken,
lex.nextImpl = expectLineEnd[T]
proc flowIndicator[T](lex: YamlLexer[T], indicator: LexerToken,
t: var LexerToken, inFlow: static[bool]): bool {.inline.} =
t: var LexerToken): bool {.inline.} =
t = indicator
lex.advance()
while lex.c in space: lex.advance()
if lex.c in lineEnd:
lex.nextImpl = expectLineEnd[T]
result = true
proc addMultiple(s: var string, c: char, num: int) {.raises: [], inline.} =
for i in 1..num: s.add(c)
@ -581,10 +582,11 @@ proc blockStyleInline[T](lex: YamlLexer[T], t: var LexerToken): bool =
if lex.inFlow: lex.nextImpl = plainScalarPart[T]
else: lex.nextImpl = blockScalarHeader[T]
result = false
of '{': result = lex.flowIndicator(ltBraceOpen, t, false)
of '}': result = lex.flowIndicator(ltBraceClose, t, false)
of '[': result = lex.flowIndicator(ltBracketOpen, t, false)
of ']': result = lex.flowIndicator(ltBracketClose, t, false)
of '{': result = lex.flowIndicator(ltBraceOpen, t)
of '}': result = lex.flowIndicator(ltBraceClose, t)
of '[': result = lex.flowIndicator(ltBracketOpen, t)
of ']': result = lex.flowIndicator(ltBracketClose, t)
of ',': result = lex.flowIndicator(ltComma, t)
else:
lex.nextImpl = plainScalarPart[T]
result = false

View File

@ -32,8 +32,10 @@ proc actualRepr(lex: YamlLexer, t: LexerToken): string =
proc assertEquals(input: string, expected: varargs[TokenWithValue]) =
let lex = newYamlLexer(input)
lex.init()
var i = 0
var blockScalarEnd = -1
var
i = 0
blockScalarEnd = -1
flowDepth = 0
for expectedToken in expected:
inc(i)
try:
@ -61,6 +63,12 @@ proc assertEquals(input: string, expected: varargs[TokenWithValue]) =
"Wrong chomp indicator at #" & $i & ": Expected " &
$expectedToken.chomp & ", got " & $lex.chomp
blockScalarEnd = lex.indentation
of ltBraceOpen, ltBracketOpen:
inc(flowDepth)
if flowDepth == 1: lex.setFlow(true)
of ltBraceClose, ltBracketClose:
dec(flowDepth)
if flowDepth == 0: lex.setFlow(false)
else: discard
except YamlLexerError:
let e = (ref YamlLexerError)(getCurrentException())
@ -95,6 +103,11 @@ proc docE(): TokenWithValue = TokenWithValue(kind: ltDocumentEnd)
proc bs(folded: bool, chomp: ChompType): TokenWithValue =
TokenWithValue(kind: ltBlockScalarHeader, folded: folded, chomp: chomp)
proc el(): TokenWithValue = TokenWithValue(kind: ltEmptyLine)
proc ao(): TokenWithValue = TokenWithValue(kind: ltBracketOpen)
proc ac(): TokenWithValue = TokenWithValue(kind: ltBracketClose)
proc oo(): TokenWithValue = TokenWithValue(kind: ltBraceOpen)
proc oc(): TokenWithValue = TokenWithValue(kind: ltBraceClose)
proc c(): TokenWithValue = TokenWithValue(kind: ltComma)
suite "Lexer":
test "Empty document":
@ -155,4 +168,8 @@ suite "Lexer":
assertEquals("one : >2-\l foo\l bar\ltwo: |+\l bar\l baz", i(0),
sp("one"), mv(), bs(true, ctStrip), i(3), sp(" foo"), i(2), sp("bar"),
i(0), sp("two"), mv(), bs(false, ctKeep), i(1), sp("bar"), i(2),
sp(" baz"), se())
sp(" baz"), se())
test "Flow indicators":
assertEquals("bla]: {c: d, [e]: f}", i(0), sp("bla]"), mv(), oo(), sp("c"),
mv(), sp("d"), c(), ao(), sp("e"), ac(), mv(), sp("f"), oc(), se())