mirror of https://github.com/status-im/NimYAML.git
Finished JSON parser. Restructuring.
* Made JSON parser resolve anchors and aliases * Moved exported consts and types to yaml.nim
This commit is contained in:
parent
c83d488886
commit
2c4e681f0b
|
@ -1,6 +1,8 @@
|
||||||
nimcache
|
nimcache
|
||||||
nakefile
|
nakefile
|
||||||
test/tests
|
test/tests
|
||||||
test/tests.exe
|
test/parsing
|
||||||
test/tests.pdb
|
test/lexing
|
||||||
test/tests.ilk
|
test/*.exe
|
||||||
|
test/*.pdb
|
||||||
|
test/*.ilk
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
type
|
type
|
||||||
Level = tuple[node: JsonNode, key: string]
|
Level = tuple[node: JsonNode, key: string]
|
||||||
|
|
||||||
proc initLevel(node: JsonNode): Level = (node: node, key: nil)
|
proc initLevel(node: JsonNode): Level = (node: node, key: cast[string](nil))
|
||||||
|
|
||||||
proc jsonFromScalar(content: string, typeHint: YamlTypeHint): JsonNode =
|
proc jsonFromScalar(content: string, typeHint: YamlTypeHint): JsonNode =
|
||||||
new(result)
|
new(result)
|
||||||
|
@ -36,6 +36,7 @@ proc parseToJson*(s: Stream): seq[JsonNode] =
|
||||||
tagInt = parser.registerUri("tag:yaml.org,2002:int")
|
tagInt = parser.registerUri("tag:yaml.org,2002:int")
|
||||||
tagFloat = parser.registerUri("tag:yaml.org,2002:float")
|
tagFloat = parser.registerUri("tag:yaml.org,2002:float")
|
||||||
events = parser.parse(s)
|
events = parser.parse(s)
|
||||||
|
anchors = initTable[AnchorId, JsonNode]()
|
||||||
|
|
||||||
for event in events():
|
for event in events():
|
||||||
case event.kind
|
case event.kind
|
||||||
|
@ -47,23 +48,36 @@ proc parseToJson*(s: Stream): seq[JsonNode] =
|
||||||
# we can savely assume that levels has e length of exactly 1.
|
# we can savely assume that levels has e length of exactly 1.
|
||||||
result.add(levels.pop().node)
|
result.add(levels.pop().node)
|
||||||
of yamlStartSequence:
|
of yamlStartSequence:
|
||||||
levels.add((node: newJArray(), key: cast[string](nil)))
|
levels.add(initLevel(newJArray()))
|
||||||
|
if event.objAnchor != anchorNone:
|
||||||
|
anchors[event.objAnchor] = levels[levels.high].node
|
||||||
of yamlStartMap:
|
of yamlStartMap:
|
||||||
levels.add((node: newJObject(), key: cast[string](nil)))
|
levels.add(initLevel(newJObject()))
|
||||||
|
if event.objAnchor != anchorNone:
|
||||||
|
anchors[event.objAnchor] = levels[levels.high].node
|
||||||
of yamlScalar:
|
of yamlScalar:
|
||||||
case levels[levels.high].node.kind
|
case levels[levels.high].node.kind
|
||||||
of JArray:
|
of JArray:
|
||||||
levels[levels.high].node.elems.add(
|
let jsonScalar = jsonFromScalar(event.scalarContent,
|
||||||
jsonFromScalar(event.scalarContent, event.scalarType))
|
event.scalarType)
|
||||||
|
levels[levels.high].node.elems.add(jsonScalar)
|
||||||
|
if event.scalarAnchor != anchorNone:
|
||||||
|
anchors[event.scalarAnchor] = jsonScalar
|
||||||
of JObject:
|
of JObject:
|
||||||
if isNil(levels[levels.high].key):
|
if isNil(levels[levels.high].key):
|
||||||
# JSON only allows strings as keys
|
# JSON only allows strings as keys
|
||||||
levels[levels.high].key = event.scalarContent
|
levels[levels.high].key = event.scalarContent
|
||||||
|
if event.scalarAnchor != anchorNone:
|
||||||
|
raise newException(ValueError,
|
||||||
|
"scalar keys may not have anchors in JSON")
|
||||||
else:
|
else:
|
||||||
|
let jsonScalar = jsonFromScalar(event.scalarContent,
|
||||||
|
event.scalarType)
|
||||||
levels[levels.high].node.fields.add(
|
levels[levels.high].node.fields.add(
|
||||||
(key: levels[levels.high].key, val: jsonFromScalar(
|
(key: levels[levels.high].key, val: jsonScalar))
|
||||||
event.scalarContent, event.scalarType)))
|
|
||||||
levels[levels.high].key = nil
|
levels[levels.high].key = nil
|
||||||
|
if event.scalarAnchor != anchorNone:
|
||||||
|
anchors[event.scalarAnchor] = jsonScalar
|
||||||
else:
|
else:
|
||||||
discard # will never happen
|
discard # will never happen
|
||||||
of yamlEndSequence, yamlEndMap:
|
of yamlEndSequence, yamlEndMap:
|
||||||
|
@ -91,4 +105,19 @@ proc parseToJson*(s: Stream): seq[JsonNode] =
|
||||||
echo "YAML error at line ", event.line, ", column ", event.column,
|
echo "YAML error at line ", event.line, ", column ", event.column,
|
||||||
": ", event.description
|
": ", event.description
|
||||||
of yamlAlias:
|
of yamlAlias:
|
||||||
discard # todo
|
# we can savely assume that the alias exists in anchors
|
||||||
|
# (else the parser would have already thrown an exception)
|
||||||
|
case levels[levels.high].node.kind
|
||||||
|
of JArray:
|
||||||
|
levels[levels.high].node.elems.add(anchors[event.aliasTarget])
|
||||||
|
of JObject:
|
||||||
|
if isNil(levels[levels.high].key):
|
||||||
|
raise newException(ValueError,
|
||||||
|
"cannot use alias node as key in JSON")
|
||||||
|
else:
|
||||||
|
levels[levels.high].node.fields.add(
|
||||||
|
(key: levels[levels.high].key,
|
||||||
|
val: anchors[event.aliasTarget]))
|
||||||
|
levels[levels.high].key = nil
|
||||||
|
else:
|
||||||
|
discard # will never happen
|
|
@ -25,36 +25,6 @@ type
|
||||||
BlockScalarStyle = enum
|
BlockScalarStyle = enum
|
||||||
bsLiteral, bsFolded
|
bsLiteral, bsFolded
|
||||||
|
|
||||||
const
|
|
||||||
tagExclamationMark*: TagId = 0.TagId # "!" non-specific tag
|
|
||||||
tagQuestionMark* : TagId = 1.TagId # "?" non-specific tag
|
|
||||||
anchorNone*: AnchorId = (-1).AnchorId # no anchor defined
|
|
||||||
|
|
||||||
# interface
|
|
||||||
|
|
||||||
proc `==`*(left: YamlParserEvent, right: YamlParserEvent): bool
|
|
||||||
|
|
||||||
proc `==`*(left, right: TagId): bool {.borrow.}
|
|
||||||
proc `$`*(id: TagId): string {.borrow.}
|
|
||||||
|
|
||||||
proc `==`*(left, right: AnchorId): bool {.borrow.}
|
|
||||||
proc `$`*(id: AnchorId): string {.borrow.}
|
|
||||||
|
|
||||||
proc newParser*(): YamlSequentialParser
|
|
||||||
|
|
||||||
# iterators cannot be pre-declared.
|
|
||||||
#
|
|
||||||
# iterator events*(parser: YamlSequentialParser,
|
|
||||||
# input: Stream): YamlParserEvent
|
|
||||||
|
|
||||||
proc uri*(parser: YamlSequentialParser, id: TagId): string
|
|
||||||
|
|
||||||
proc registerUri*(parser: var YamlSequentialParser, uri: string): TagId
|
|
||||||
|
|
||||||
proc anchor*(parser: YamlSequentialParser, id: AnchorId): string
|
|
||||||
|
|
||||||
# implementation
|
|
||||||
|
|
||||||
proc newParser*(): YamlSequentialParser =
|
proc newParser*(): YamlSequentialParser =
|
||||||
new(result)
|
new(result)
|
||||||
result.tags = initOrderedTable[string, TagId]()
|
result.tags = initOrderedTable[string, TagId]()
|
||||||
|
|
25
src/yaml.nim
25
src/yaml.nim
|
@ -1,4 +1,4 @@
|
||||||
import streams, unicode, lexbase, tables, strutils, json
|
import streams, unicode, lexbase, tables, strutils, json, hashes
|
||||||
|
|
||||||
type
|
type
|
||||||
YamlTypeHint* = enum
|
YamlTypeHint* = enum
|
||||||
|
@ -36,8 +36,31 @@ type
|
||||||
tags: OrderedTable[string, TagId]
|
tags: OrderedTable[string, TagId]
|
||||||
anchors: OrderedTable[string, AnchorId]
|
anchors: OrderedTable[string, AnchorId]
|
||||||
|
|
||||||
|
const
|
||||||
|
tagExclamationMark*: TagId = 0.TagId # "!" non-specific tag
|
||||||
|
tagQuestionMark* : TagId = 1.TagId # "?" non-specific tag
|
||||||
|
anchorNone*: AnchorId = (-1).AnchorId # no anchor defined
|
||||||
|
|
||||||
# interface
|
# interface
|
||||||
|
|
||||||
|
proc `==`*(left: YamlParserEvent, right: YamlParserEvent): bool
|
||||||
|
|
||||||
|
proc `==`*(left, right: TagId): bool {.borrow.}
|
||||||
|
proc `$`*(id: TagId): string {.borrow.}
|
||||||
|
proc hash*(id: TagId): Hash {.borrow.}
|
||||||
|
|
||||||
|
proc `==`*(left, right: AnchorId): bool {.borrow.}
|
||||||
|
proc `$`*(id: AnchorId): string {.borrow.}
|
||||||
|
proc hash*(id: AnchorId): Hash {.borrow.}
|
||||||
|
|
||||||
|
proc newParser*(): YamlSequentialParser
|
||||||
|
|
||||||
|
proc uri*(parser: YamlSequentialParser, id: TagId): string
|
||||||
|
|
||||||
|
proc registerUri*(parser: var YamlSequentialParser, uri: string): TagId
|
||||||
|
|
||||||
|
proc anchor*(parser: YamlSequentialParser, id: AnchorId): string
|
||||||
|
|
||||||
proc parse*(parser: YamlSequentialParser, s: Stream):
|
proc parse*(parser: YamlSequentialParser, s: Stream):
|
||||||
iterator(): YamlParserEvent
|
iterator(): YamlParserEvent
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
import lexing, parsing
|
|
Loading…
Reference in New Issue