json-abnf
Description
The json-abnf library contains procedures for parsing and printing JavaScript Object Notation (JSON) as described in RFC 8259. It is intended to conform closely to the ABNF grammar in the RFC.
A JSON value maps onto a plain Scheme value as follows:
- true and false are Scheme #t and #f
- null is the symbol 'null
- a JSON string is a Scheme string
- a JSON number is a Scheme number
- a JSON array is a Scheme vector
- a JSON object is an association list of (key . value) pairs, key a string
A complete JSON document can be any one of these -- an object, an array, a string, a number, true, false, or null -- optionally surrounded by whitespace, as RFC 8259 permits. (This is a relaxation from the older RFC 4627, which this library previously followed, and which required the outermost value to be an object or an array specifically.)
Library Procedures
[procedure] (parser TEXT) => VALUEParses TEXT as JSON, using the value mapping above, and returns the Scheme value it describes. On malformed input, prints an error message to the current output port and returns (error).
Bidirectional printing: preliminaries
The grammar in json-abnf is built with abnf's abnf-lens component, which makes every rule bidirectional: the same rule declaration produces both the parser behind parser above and the printer behind printer below, so a value your program builds is guaranteed to print as text parser can read back in (see the abnf page for more on abnf-lens itself, including a step-by-step tutorial).
[procedure] (printer VALUE) => STRINGPrints VALUE as JSON text, using the same value mapping described above -- VALUE can be any JSON value: an association list, a vector, a string, a number, #t, #f, or the symbol 'null. On a value printer cannot print, prints an error message to the current output port and returns "".
(import json-abnf) (define person (list (cons "name" "Ada") (cons "tags" (vector "mathematician" "programmer")))) (printer person) ;; => "{\"name\":\"Ada\",\"tags\":[\"mathematician\",\"programmer\"]}" (parser (printer person)) ;; => (("name" . "Ada") ("tags" . #("mathematician" "programmer"))) ;; A document doesn't need to be an object or an array (parser "42") ;; => 42 (printer "hello") ;; => "\"hello\""
Bidirectional grammar rules
The two rules below are what parser and printer are each built from (parser also accepts the narrower value shape internally; bi-text is the whole-document rule printer uses). They are exported directly, in case you want to embed the JSON grammar as part of a larger abnf-lens grammar.
Each rule is a bp value, used with the bp-parse and bp-print procedures. Both the bp record and these two procedures are documented on the abnf page, along with bi-iso, bi-seq, and the other combinators the rules are built from.
[procedure] bi-value => BPThe bidirectional counterpart of a JSON value: a bp whose parser reads any JSON value -- an object, an array, a string, a number, true, false, or null -- and whose printer writes any of those back out. Use it directly with bp-parse and bp-print when a value nested inside a larger structure, not a whole top-level document, is what needs parsing or printing.
[procedure] bi-text => BPThe bidirectional counterpart of a whole JSON document: like bi-value, but also accepts optional surrounding whitespace, matching RFC 8259's rule for a complete JSON text (ws value ws). printer is bp-print applied to bi-text.
(import json-abnf abnf-lens) ;; bp-parse returns (list (list matched-value) remaining-stream); ;; (car (car ...)) unwraps it to the matched value. (car (car (bp-parse bi-text "[1,2,3]" (lambda (s) (error "parse failed" s))))) ;; => #(1 2 3) (bp-print bi-text (vector 1 2 3)) ;; => "[1,2,3]"
Repository
https://github.com/iraikov/chicken-json-abnf
Requires
Version History
- 7.0 Ported to CHICKEN 6; added abnf-lens-based bidirectional transforms.
- 6.0 Using utf8 for char operations
- 5.1 More bug fixes in parsing booleans [thanks to Vok Vojwo]
- 5.0 Bug fixes in parsing booleans; using dotted lists for object representation [thanks to Vok Vojwo]
- 4.0 Compatibility with abnf 5
- 3.2 Bug fixes in the parser for escaped characters; handling of empty vectors, objects, strings [thanks to Moritz Heidkamp]
- 3.1 Updated version in setup file
- 1.0 Initial Release
License
Copyright 2009-2026 Ivan Raikov This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. A full copy of the GPL license can be found at <http://www.gnu.org/licenses/>.