emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master 606fed1 10/60: Add simple JSON parser


From: Junpeng Qiu
Subject: [elpa] master 606fed1 10/60: Add simple JSON parser
Date: Tue, 25 Oct 2016 17:45:12 +0000 (UTC)

branch: master
commit 606fed1f322a1a694c53975dfd4a470d9a7238f7
Author: Junpeng Qiu <address@hidden>
Commit: Junpeng Qiu <address@hidden>

    Add simple JSON parser
---
 pjson.el |  141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git a/pjson.el b/pjson.el
new file mode 100644
index 0000000..ce4b19b
--- /dev/null
+++ b/pjson.el
@@ -0,0 +1,141 @@
+;;; pjson.el --- JSON parser using parsec.el         -*- lexical-binding: t; 
-*-
+
+;; Copyright (C) 2016  Junpeng Qiu
+
+;; Author: Junpeng Qiu <address@hidden>
+;; Keywords: extensions
+
+;; 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.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(defvar pjson-special-chars
+  '((?\" . ?\")
+    (?\\ . ?\\)
+    (?/ . ?/)
+    (?b . ?\b)
+    (?f . ?\f)
+    (?n . ?\n)
+    (?r . ?\r)
+    (?t . ?\t))
+  "Characters which are escaped in JSON, with their elisp counterparts.")
+
+(defsubst pjson-spaces ()
+  (parsec-many-as-string
+   (parsec-re "[[:space:]\r\n]")))
+
+(defmacro pjson-tok (parser)
+  `(parsec-return ,parser
+     (pjson-spaces)))
+
+(defun pjson-value ()
+  (parsec-and
+    (pjson-spaces)
+    (pjson-jvaule)))
+
+(defun pjson-jvalue ()
+  (parsec-or (pjson-null)
+             (pjson-boolean)
+             (pjson-number)
+             (pjson-string)
+             (pjson-array)
+             (pjson-object)))
+
+(defsubst pjson-null ()
+  (parsec-and
+    (pjson-tok (parsec-str "null"))
+    nil))
+
+(defsubst pjson-boolean ()
+  (parsec-or (parsec-and
+               (pjson-tok (parsec-str "true"))
+               t)
+             (parsec-and
+               (pjson-tok (parsec-str "false"))
+               nil)))
+
+(defsubst pjson-array ()
+  (apply #'vector
+         (parsec-between (pjson-tok (parsec-ch ?\[))
+                         (pjson-tok (parsec-ch ?\]))
+                         (parsec-sepby
+                          (pjson-jvalue)
+                          (pjson-tok (parsec-ch ?,))))))
+
+(defun pjson-char ()
+  (parsec-or
+   (parsec-and (parsec-ch ?\\) (pjson-esc))
+   (parsec-re "[^\"\\]")))
+
+(defun pjson-esc ()
+  (parsec-or
+   (assoc-default
+    (parsec-satisfy (lambda (x) (assq x pjson-special-chars)))
+    pjson-special-chars)
+   (parsec-and (parsec-ch ?u)
+               (pjson-uni))))
+
+(defun pjson-uni ()
+  (format "%c" (string-to-number
+                (parsec-re "[0-9a-zA-z]\\{4\\}")
+                16)))
+
+(defsubst pjson-string ()
+  (parsec-between (pjson-tok (parsec-ch ?\"))
+                  (pjson-tok (parsec-ch ?\"))
+                  (parsec-many-as-string (pjson-char))))
+
+(defun pjson-field ()
+  (cons (parsec-return (pjson-string)
+          (pjson-tok (parsec-ch ?:)))
+        (pjson-jvalue)))
+
+(defun pjson-object ()
+  (parsec-between (pjson-tok (parsec-ch ?\{))
+                  (pjson-tok (parsec-ch ?\}))
+                  (parsec-sepby
+                   (pjson-field)
+                   (pjson-tok (parsec-ch ?,)))))
+
+(defun pjson-number ()
+  (pjson-tok (string-to-number
+              (parsec-re 
"\\+?\\([0-9]+\\)\\(\\.[0-9]+\\)?\\([Ee][+-]?[0-9]+\\)?"))))
+
+(defun pjson-parse (input)
+  (parsec-do-parse input
+    (pjson-object)))
+
+(parsec-do-parse "123"
+  (pjson-number))
+(parsec-do-parse "\"asdf\""
+  (pjson-string))
+(parsec-do-parse "false"
+  (pjson-boolean))
+(parsec-do-parse "[1,true,1,\"abc\",[1],null]"
+  (pjson-array))
+(parsec-do-parse "{}"
+  (pjson-object))
+(parsec-do-parse "{\"a\" :1, \"b\":2, [{ \"c\":[1,true] }]}"
+  (pjson-object))
+
+(pjson-parse  "{\"a\" :1, \"b\":2, [{ \"c\":[1,true] }]}")
+(pjson-parse    "{\"a\" :1, \"b\":2, \"c\":[1,{\"d\":null}]}")
+(json-read-from-string  "{\"a\" :1, \"b\":2, \"c\":[1,{\"d\":null}]}")
+
+(provide 'pjson)
+;;; pjson.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]