[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
- [elpa] master updated (e479a3e -> dfb3af0), Junpeng Qiu, 2016/10/25
- [elpa] master d21bf7d 14/60: Remove unused code, Junpeng Qiu, 2016/10/25
- [elpa] master 108879f 11/60: Better propagate naming and implementation, Junpeng Qiu, 2016/10/25
- [elpa] master 5810eef 21/60: Remove parsec-continue, Junpeng Qiu, 2016/10/25
- [elpa] master 452ec1e 35/60: Update scheme parser, Junpeng Qiu, 2016/10/25
- [elpa] master 14b28a1 16/60: Add basic README, Junpeng Qiu, 2016/10/25
- [elpa] master 606fed1 10/60: Add simple JSON parser,
Junpeng Qiu <=
- [elpa] master d8cd9d6 17/60: Better naming, Junpeng Qiu, 2016/10/25
- [elpa] master a5ca813 04/60: Full & simple parser, Junpeng Qiu, 2016/10/25
- [elpa] master 9996b5b 31/60: Update full-csv-parser, Junpeng Qiu, 2016/10/25
- [elpa] master bdfcbde 23/60: Update library description, Junpeng Qiu, 2016/10/25
- [elpa] master 2e8c52b 40/60: Make sure parsec-not-followed-by consumes no input, Junpeng Qiu, 2016/10/25
- [elpa] master fb26929 34/60: Fix parsec-make-alternatives, Junpeng Qiu, 2016/10/25
- [elpa] master 31388e6 52/60: Add -s aliases, Junpeng Qiu, 2016/10/25
- [elpa] master 34521c6 53/60: Update README about *-s functions, Junpeng Qiu, 2016/10/25
- [elpa] master 8f0c266 58/60: Add doc for parsec-peek(-p), Junpeng Qiu, 2016/10/25
- [elpa] master ffd42de 45/60: Use simple-csv-parser.el as a demo, Junpeng Qiu, 2016/10/25