Implemented anchors and aliases

This commit is contained in:
Felix Krause 2016-09-11 13:04:10 +02:00
parent 4d1a444f61
commit 4e97e53489
2 changed files with 44 additions and 2 deletions

View File

@ -181,6 +181,8 @@ proc plainScalarPart[T](lex: YamlLexer): bool
proc blockScalarHeader[T](lex: YamlLexer): bool proc blockScalarHeader[T](lex: YamlLexer): bool
proc blockScalar[T](lex: YamlLexer): bool proc blockScalar[T](lex: YamlLexer): bool
proc tagHandle[T](lex: YamlLexer): bool proc tagHandle[T](lex: YamlLexer): bool
proc anchor[T](lex: YamlLexer): bool
proc alias[T](lex: YamlLexer): bool
proc streamEnd(lex: YamlLexer): bool proc streamEnd(lex: YamlLexer): bool
# implementation # implementation
@ -589,6 +591,15 @@ proc insideLine[T](lex: YamlLexer): bool =
of '!': of '!':
lex.nextState = tagHandle[T] lex.nextState = tagHandle[T]
result = false result = false
of '&':
lex.nextState = anchor[T]
result = false
of '*':
lex.nextState = alias[T]
result = false
of '@', '`':
raise generateError[T](lex,
"Reserved characters cannot start a plain scalar")
else: else:
lex.nextState = plainScalarPart[T] lex.nextState = plainScalarPart[T]
result = false result = false
@ -758,6 +769,29 @@ proc tagHandle[T](lex: YamlLexer): bool =
else: lex.nextState = insideLine[T] else: lex.nextState = insideLine[T]
result = true result = true
proc anchorName[T](lex: YamlLexer) =
debug("lex: anchorName")
while true:
lex.advance(T)
case lex.c
of spaceOrLineEnd, '[', ']', '{', '}', ',': break
else: lex.buf.add(lex.c)
while lex.c in space: lex.advance(T)
if lex.c in lineEnd: lex.nextState = expectLineEnd[T]
else: lex.nextState = insideLine[T]
proc anchor[T](lex: YamlLexer): bool =
debug("lex: anchor")
anchorName[T](lex)
lex.cur = ltAnchor
result = true
proc alias[T](lex: YamlLexer): bool =
debug("lex: alias")
anchorName[T](lex)
lex.cur = ltAlias
result = true
proc streamEnd(lex: YamlLexer): bool = proc streamEnd(lex: YamlLexer): bool =
debug("lex: streamEnd") debug("lex: streamEnd")
lex.cur = ltStreamEnd lex.cur = ltStreamEnd

View File

@ -4,7 +4,8 @@ import unittest, strutils
const tokensWithValue = const tokensWithValue =
{ltScalarPart, ltQuotedScalar, ltYamlVersion, ltTagShorthand, ltTagUri, {ltScalarPart, ltQuotedScalar, ltYamlVersion, ltTagShorthand, ltTagUri,
ltUnknownDirective, ltUnknownDirectiveParams, ltLiteralTag} ltUnknownDirective, ltUnknownDirectiveParams, ltLiteralTag, ltAnchor,
ltAlias}
type type
TokenWithValue = object TokenWithValue = object
@ -125,6 +126,8 @@ proc th(handle, suffix: string): TokenWithValue =
TokenWithValue(kind: ltTagHandle, handle: handle, suffix: suffix) TokenWithValue(kind: ltTagHandle, handle: handle, suffix: suffix)
proc lt(v: string): TokenWithValue = proc lt(v: string): TokenWithValue =
TokenWithValue(kind: ltLiteralTag, value: v) TokenWithValue(kind: ltLiteralTag, value: v)
proc an(v: string): TokenWithValue = TokenWithValue(kind: ltAnchor, value: v)
proc al(v: string): TokenWithValue = TokenWithValue(kind: ltAlias, value: v)
suite "Lexer": suite "Lexer":
test "Empty document": test "Empty document":
@ -203,3 +206,8 @@ suite "Lexer":
test "Literal tag handle": test "Literal tag handle":
assertEquals("!<tag:yaml.org,2002:str> string", i(0), assertEquals("!<tag:yaml.org,2002:str> string", i(0),
lt("tag:yaml.org,2002:str"), sp("string"), se()) lt("tag:yaml.org,2002:str"), sp("string"), se())
test "Anchors and aliases":
assertEquals("&a foo: {&b b: *a, *b : c}", i(0), an("a"), sp("foo"), mv(),
oo(), an("b"), sp("b"), mv(), al("a"), c(), al("b"), mv(), sp("c"),
oc(), se())