3 JSON
| (require parser-combinator/json) | |
| package: parser-combinator | |
This library parses text in the JSON data exchange format into Racket values. See the JSON web site for more about JSON. The library is written entirely with parser-combinator/parse.
3.1 JSON Values
JSON : any/c
An empty JSON array is '() and an empty JSON object is #hasheq(), so every kind of JSON value can be told apart with list?, hash?, and the other predicates above. If a name appears more than once in an object, the last value wins. The order of the names in the text is not kept.
; {"a": [1, 2], "b": {}} > (define obj (string->json "{\"a\": [1, 2], \"b\": {}}")) > (hash-ref obj 'a) '(1 2)
> (list-ref (hash-ref obj 'a) 1) 2
procedure
(string->json str) → JSON
str : string?
> (string->json "[]") '()
> (string->json "-1.5e3") -1500
; [1, {"foo": false}, null] > (string->json "[1, {\"foo\": false}, null]") '(1 #hasheq((foo . #f)) null)
> (string->json "[1, 2") bad input, got error
Escape sequences in strings are decoded, so \n becomes a newline character. See STRING.
; "a\nb" > (string->json "\"a\\nb\"") "a\nb"
3.2 Grammar
The grammar behind string->json is made of the parsers below. SPACE matches whitespace, and its Value is the matched text. The rest produce the JSON itself, using seq and seq* constructors: NUMBER, STRING, ARRAY, and OBJECT for those kinds of value, PAIR for one name and value in an object, and VALUE for any JSON value. These parsers are exported so that programs can use them directly.
It produces the number as an exact number.
> (parse NUMBER "7") 7
> (parse NUMBER "-1.5e2") -150
> (parse NUMBER "1.") bad input, had leftover text "."
It produces the text between the quotes as a string, with each escape sequence replaced by the character it stands for. A \u escape names a UTF-16 code unit, so a character outside the Basic Multilingual Plane is written as a surrogate pair, two \u escapes in a row, which together produce one character. A surrogate without its other half produces the replacement character U+FFFD.
; "hi" > (parse STRING "\"hi\"") "hi"
; "a\tb \u00e9 \uD83D\uDE00" > (parse STRING "\"a\\tb \\u00e9 \\uD83D\\uDE00\"") "a\tb é 😀"
; "\uD83D!" > (parse STRING "\"\\uD83D!\"") "�!"
; "a b" with a raw tab, which JSON doesn't allow > (parse STRING "\"a\tb\"") bad input, got error
> (parse OBJECT "{}") '#hasheq()
; {"a": 1, "b": 2} > (parse OBJECT "{\"a\": 1, \"b\": 2}") '#hasheq((a . 1) (b . 2))
Wherever the grammar allows whitespace around a value or a punctuation mark, the parsers skip an optional SPACE with unwrap.