parsejson
nimony/lib/std/parsejson.nim
This module implements a json parser. It is used and exported by the json standard library module, but can also be used in its own right.
This is a port of Nim's std/parsejson to Nimony. It keeps the original design: JsonParser inherits from lexbase.BaseLexer, so it parses straight off a Stream with a fixed-size, sentinel-terminated buffer (good for embedded / streaming use) instead of slurping the whole input. Because Nimony models exceptions as ErrorCode values (without an attached message), the JsonKindError/JsonParsingError exception types are gone: raiseParseErr raises a plain ValueError. The helpful message is still available through errorMsg/errorMsgExpected.
type JsonEventKind = enum jsonError = (0, "jsonError") jsonEof = (1, "jsonEof") jsonString = (2, "jsonString") jsonInt = (3, "jsonInt") jsonFloat = (4, "jsonFloat") jsonTrue = (5, "jsonTrue") jsonFalse = (6, "jsonFalse") jsonNull = (7, "jsonNull") jsonObjectStart = (8, "jsonObjectStart") jsonObjectEnd = (9, "jsonObjectEnd") jsonArrayStart = (10, "jsonArrayStart") jsonArrayEnd = (11, "jsonArrayEnd")
func dollar`.JsonEventKind(e: JsonEventKind): stringtype TokKind = enum tkError = (0, "tkError") tkEof = (1, "tkEof") tkString = (2, "tkString") tkInt = (3, "tkInt") tkFloat = (4, "tkFloat") tkTrue = (5, "tkTrue") tkFalse = (6, "tkFalse") tkNull = (7, "tkNull") tkCurlyLe = (8, "tkCurlyLe") tkCurlyRi = (9, "tkCurlyRi") tkBracketLe = (10, "tkBracketLe") tkBracketRi = (11, "tkBracketRi") tkColon = (12, "tkColon") tkComma = (13, "tkComma")
func dollar`.TokKind(e: TokKind): stringtype JsonError = enum errNone = (0, "errNone") errInvalidToken = (1, "errInvalidToken") errStringExpected = (2, "errStringExpected") errColonExpected = (3, "errColonExpected") errCommaExpected = (4, "errCommaExpected") errBracketRiExpected = (5, "errBracketRiExpected") errCurlyRiExpected = (6, "errCurlyRiExpected") errQuoteExpected = (7, "errQuoteExpected") errEOC_Expected = (8, "errEOC_Expected") errEofExpected = (9, "errEofExpected") errExprExpected = (10, "errExprExpected")
func dollar`.JsonError(e: JsonError): stringfunc dollar`.ParserState(e: ParserState): stringtype JsonParser = object a: string tok: TokKind kind: JsonEventKind err: JsonError state: seq filename: string rawStringLiterals: bool
const errorMessages: array[0..10, string]proc open(my: var JsonParser; input: ref StreamObj; filename: string; rawStringLiterals: bool)initializes the parser with an input stream.
Filenameis only used for nice error messages. IfrawStringLiteralsis true, string literals are kept with their surrounding quotes and escape sequences in them are left untouched too.proc close(my: var JsonParser)closes the parser
myand its associated input stream.proc str(my: JsonParser): stringreturns the character data for the events:
jsonInt,jsonFloat,jsonStringproc getInt(my: JsonParser): int64returns the number for the event:
jsonIntproc getFloat(my: JsonParser): float64returns the number for the event:
jsonFloatproc kind(my: JsonParser): JsonEventKindreturns the current event type for the JSON parser
proc getColumn(my: JsonParser): int64get the current column the parser has arrived at.
proc getLine(my: JsonParser): int64get the current line the parser has arrived at.
proc getFilename(my: JsonParser): stringget the filename of the file that the parser processes.
proc errorMsgFor(my: JsonParser; err: JsonError): stringFormat a diagnostic for a specific
JsonError, in the<file>(<line>, <col>) Error: <msg>form. Non-raising (plain string concatenation, no%) so the whole parse stack staysraises-free. The caller passes the error explicitly becausemy.erris sticky (it keeps the first error), whereas an in-tree placeholder wants the message for the error at its own position.proc errorMsg(my: JsonParser): stringreturns a helpful error message for the current error state
proc errorMsgExpected(my: JsonParser; e: string): stringreturns an error message "
eexpected" in the same format as the other error messagesproc parseEscapedUTF16(buf: openArray; pos: var int64): int64proc getTok(my: var JsonParser): TokKindproc next(my: var JsonParser)retrieves the first/next event. This controls the parser.
proc setError(p: var JsonParser; err: JsonError)Record a syntax error in the parser's state instead of raising. After this,
kind(p)isjsonErrorandhasError(p)is true. The parser collects errors rather than raising, so callers (e.g.std/json) stay exception-free; inspect the state withhasError/errorMsg.proc hasError(my: JsonParser): boolTrue once the parser has recorded a syntax error (see
setError).proc raiseParseErr(p: var JsonParser; msg: string)Records a syntax error in
p's state. Despite the historical name it no longer raises —msgonly documents the expectation; useerrorMsgExpected(p, msg)for the human-readable text.proc eat(p: var JsonParser; tok: TokKind)