-
-
Save chaitanyagupta/ed528beb77269e0cdc41a3a1a51b9ae5 to your computer and use it in GitHub Desktop.
JSON parser implemented with cl-lex and CL-Yacc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#| | |
JSON parser implemented with cl-lex and CL-Yacc | |
USAGE: | |
JSON-PARSER> (parse-with-lexer (json-lexer | |
"{\"foo\":\"bar\",\"baz\":\"bang\",\"bing\":100,\"bingo\":1.1,\"bazo\": [1,2,\"foo\"]}") | |
json-parser) | |
(:OBJ ("foo" . "bar") ("baz" . "bang") ("bing" . 100) ("bingo" . 1.1) ("bazo" 1 2 "foo")) | |
JSON-PARSER> (with-open-file (*standard-input* "test.json") | |
(parse-with-lexer (stream-lexer #'read-line | |
#'json-lexer | |
#'(lambda (c) (declare (ignore c))) | |
#'(lambda (c) (declare (ignore c)))) | |
json-parser)) | |
(:OBJ ("foo" . "bar") ("baz" . "bang") ("bing" . 100) ("bingo" . 1.1) ("bazo" 1 2 "foo")) | |
|# | |
(in-package :cl-user) | |
(eval-when (:compile-toplevel :load-toplevel :execute) | |
(ql:quickload '(:yacc :cl-lex) :silent t)) | |
(defpackage :json-parser | |
(:use :cl :yacc :cl-lex)) | |
(in-package :json-parser) | |
(define-string-lexer json-lexer | |
("{" (return (values '{ $@))) | |
("}" (return (values '} $@))) | |
("\\[" (return (values '[ '[))) | |
("\\]" (return (values '] ']))) | |
(":" (return (values '|:| '|:|))) | |
("," (return (values '|,| '|,|))) | |
("'" (return (values '|'| '|'|))) | |
("\"([^\\\"]|\\.)*?\"" (return (values 'string (string-trim "\"" $@)))) | |
("-?0|[1-9][0-9]*(\\.[0-9]*)?([e|E][+-]?[0-9]+)?" (return (values 'number (read-from-string $@)))) | |
("true" (return (values 'true 'true))) | |
("false" (return (values 'false 'false))) | |
("null" (return (values 'null 'null)))) | |
(define-parser json-parser | |
(:start-symbol json) | |
(:terminals ({ } [ ] |:| |,| |'| string number true false null)) | |
(json object | |
array | |
string | |
number | |
true | |
false | |
null) | |
(array ([ ] | |
#'(lambda (_lp _rp) | |
(declare (ignore _lp _rp)) | |
(list :array))) | |
([ sequence ] | |
#'(lambda (_lp sequence _rp) | |
(declare (ignore _lp _rp)) | |
sequence))) | |
(sequence json | |
(json |,| sequence | |
#'(lambda (json _c sequence) | |
(declare (ignore _c)) | |
(if (listp sequence) | |
(cons json sequence) | |
(list json sequence))))) | |
(object ({ } | |
#'(lambda (_lp _rp) | |
(declare (ignore _lp _rp)) | |
(list :obj))) | |
({ members } | |
#'(lambda (_lp members _rp) | |
(declare (ignore _lp _rp)) | |
(cons :obj members)))) | |
(member (string |:| json | |
#'(lambda (string _c json) | |
(declare (ignore _c)) | |
(cons string json)))) | |
(members member | |
(member |,| members | |
#'(lambda (member _c members) | |
(declare (ignore _c)) | |
(if (listp (car members)) | |
(cons member members) | |
(list member members)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice example using cl-lex! Thanks!