近来对读取器的功能有新的理解,再次利用读取器实现 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)))
青水
原创文章 78获赞 11访问量 5万+
关注
私信
展开阅读全文
作者:青水