JSON解析簡單實現 之三

近來對讀取器的功能有新的理解,再次利用讀取器實現 JSON解析。

感覺效果不錯,解決了之前的一些問題。 

運行環境:clisp 2.49

附:

;json convert
;WHJ.20200510

;["ok1","ok2","OK3"]
;{"ok":1,"ok2":2,"ok3":3}
;[{"ok":1,"ok2":2,"ok3":3},"ok1","ok2","OK3",{"ok1":1,"ok2":2,"ok3":[3,4],"ok4":"5"}]

(defmacro with-json-environment (&body body)
     (let ((ha (gensym)))
        `(let ((*readtable* (copy-readtable))
               (,ha (make-hash-table :test #'equal)))
               
            (set-macro-character #\, (lambda (stream char) nil))
            (set-macro-character #\: (lambda (stream char) nil))
            (set-macro-character #\] (get-macro-character #\)))
            (set-macro-character #\} (get-macro-character #\)))
            
            (set-macro-character #\[ (lambda (stream char)
                (declare (ignore char))
                (coerce (remove-if 'null (read-delimited-list #\] stream))
                        'vector)))
                        
            (set-macro-character #\{ (lambda (stream char)
                (declare (ignore char))
                (let ((kv-list (remove-if 'null (read-delimited-list #\} stream))))
                     (loop for k on kv-list by #'cddr 
                        do (setf (gethash (car k) ,ha) (cadr k)))
                      ,ha)))
                      
            ,@body)))
            
                  
(defun json-cvt (json-string)
	(with-json-environment
        (read-from-string json-string)))
            
;---------------------------------------------------------------------
(defun test-1 nil
    (let ((json-str "[{\"ok\":1,\"ok2\":2,\"ok3\":3},\"ok1\",\"ok2\",\"OK3\",{\"ok1\":1,\"ok2\":2,\"ok3\":[3,4],\"ok4\":\"5\"}]"))
        (json-cvt json-str)))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章