[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master a268b9f 08/60: Add more APIs
From: |
Junpeng Qiu |
Subject: |
[elpa] master a268b9f 08/60: Add more APIs |
Date: |
Tue, 25 Oct 2016 17:45:12 +0000 (UTC) |
branch: master
commit a268b9ff21b8f32fe03a61a38e2458ac0ce83b6f
Author: Junpeng Qiu <address@hidden>
Commit: Junpeng Qiu <address@hidden>
Add more APIs
---
parsec.el | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 81 insertions(+), 9 deletions(-)
diff --git a/parsec.el b/parsec.el
index 9f13e88..3075a21 100644
--- a/parsec.el
+++ b/parsec.el
@@ -30,6 +30,8 @@
"Combinator parsing library for Emacs, similar to Haskell's Parsec"
:group 'development)
+(defvar parsec-last-error-message nil)
+
(defun parsec-eob-or-char-as-string ()
(let ((c (char-after)))
(if c
@@ -45,8 +47,12 @@
(defalias 'parsec-msg-get 'cdr)
+(defsubst parsec-throw (msg)
+ (throw 'failed msg))
+
(defun parsec-stop (&rest args)
- (throw 'failed
+ (parsec-throw
+ (setq parsec-last-error-message
(let ((msg (plist-get args :message))
(expected (plist-get args :expected))
(found (plist-get args :found)))
@@ -56,7 +62,7 @@
(parsec-msg (if (stringp msg)
msg
(format "Found \"%s\" -> Expected \"%s\""
- found expected)))))))
+ found expected))))))))
(defun parsec-ch (ch &rest args)
(let ((next-char (char-after)))
@@ -75,6 +81,23 @@
(parsec-stop :expected (char-to-string ch)
:found (parsec-eob-or-char-as-string)))))
+(defun parsec-satisfy (pred)
+ (let ((next-char (char-after)))
+ (if (and (not (eobp))
+ (funcall pred next-char))
+ (prog1
+ (cond
+ ((memq :nil args) nil)
+ ((memq :beg args)
+ (point))
+ ((memq :end args)
+ (1+ (point)))
+ (t
+ (char-to-string ch)))
+ (forward-char 1))
+ (parsec-stop :expected (format "%s" pred)
+ :found (parsec-eob-or-char-as-string)))))
+
(defun parsec-eob ()
(unless (eobp)
(parsec-stop :expected "`eob'"
@@ -109,13 +132,29 @@
(defsubst parsec-num (num &rest args)
(parsec-re (regexp-quote (number-to-string num))))
+(defsubst parsec-letter ()
+ (parsec-re "[a-zA-Z]"))
+
+(defsubst parsec-digit ()
+ (parsec-re "[0-9]"))
+
(defmacro parsec-or (&rest parsers)
(let ((outer-sym (make-symbol "outer"))
- (parser-sym (make-symbol "parser")))
- `(cl-loop named ,outer-sym for ,parser-sym in ',parsers
- finally (parsec-stop :message "None of the parsers succeeds") do
- (parsec-try
- (return-from ,outer-sym (eval ,parser-sym))))))
+ (parser-sym (make-symbol "parser"))
+ (msg-sym (make-symbol "msg"))
+ (error-sym (make-symbol "err")))
+ `(let (,msg-sym ,error-sym)
+ (cl-loop named ,outer-sym for ,parser-sym in ',parsers
+ finally (parsec-stop
+ :message
+ (if ,error-sym
+ (mapconcat #'identity ,error-sym "\n")
+ "None of the parsers succeeds"))
+ do
+ (parsec-try
+ (cl-return-from ,outer-sym
+ (parsec-propagate (,msg-sym (eval ,parser-sym))
+ (add-to-list ',error-sym (parsec-msg-get ,msg-sym)))))))))
(defalias 'parsec-and 'progn)
@@ -124,6 +163,25 @@
(defmacro parsec-try (&rest forms)
`(catch 'failed ,@forms))
+(defmacro parsec-save (&rest forms)
+ (let ((orig-pt-sym (make-symbol "orig-pt"))
+ (msg-sym (make-symbol "msg")))
+ `(let ((,orig-pt-sym (point))
+ ,msg-sym)
+ (parsec-propagate (,msg-sym (parsec-and ,@forms))
+ (goto-char ,orig-pt-sym)))))
+
+(defmacro parsec-propagate (parser-cons &rest body)
+ (declare (indent 1))
+ (let ((res-sym (car parser-cons)))
+ `(progn
+ (setq ,res-sym (parsec-try ,(cadr parser-cons)))
+ (if (parsec-msg-p ,res-sym)
+ (progn
+ ,@body
+ (parsec-throw ,res-sym))
+ ,res-sym))))
+
(defmacro parsec-try-with-message (msg &rest forms)
(declare (indent 1))
(let ((res-sym (make-symbol "result")))
@@ -136,7 +194,7 @@
(defmacro parsec-ensure-with-message (msg &rest forms)
(declare (indent 1))
- (let* ((error-sym (make-symbol "err")))
+ (let ((error-sym (make-symbol "err")))
`(let (,error-sym)
(if (parsec-msg-p (setq ,error-sym
(parsec-try-with-message ,msg ,@forms)))
@@ -148,7 +206,7 @@
(defalias 'parsec-parse 'parsec-try)
-(defmacro parsec-until (parser &optional &key skip)
+(cl-defmacro parsec-until (parser &optional &key skip)
`(catch 'done
(while (not (eobp))
(parsec-try
@@ -186,6 +244,12 @@
(cons ,parser (parsec-many (parsec-and ,separator ,parser)))
nil))
+(defmacro parsec-between (open close parser)
+ `(parsec-save
+ ,open
+ (parsec-return ,parser
+ ,close)))
+
(defun parsec-just (x) (cons 'Just x))
(defvar parsec-nothing 'Nothing)
@@ -204,5 +268,13 @@
parsec-nothing
(parsec-just ,res)))))
+(defmacro parsec-do-parse (input &rest parsers)
+ (declare (indent 1))
+ `(with-temp-buffer
+ (insert ,input)
+ (goto-char (point-min))
+ (parsec-try
+ ,@parsers)))
+
(provide 'parsec)
;;; parsec.el ends here
- [elpa] master 054a753 06/60: Rename to parsec, (continued)
- [elpa] master 054a753 06/60: Rename to parsec, Junpeng Qiu, 2016/10/25
- [elpa] master 2cce1e3 37/60: Rename parsec-from-just to parsec-from-maybe, Junpeng Qiu, 2016/10/25
- [elpa] master cdb8c0d 47/60: Remove unused symbols, Junpeng Qiu, 2016/10/25
- [elpa] master fdb3d99 44/60: Fix some code in simple-csv-parser.el, Junpeng Qiu, 2016/10/25
- [elpa] master 701964f 57/60: Prepare headers for GNU ELPA, Junpeng Qiu, 2016/10/25
- [elpa] master cbd3352 55/60: Add parsec-lookahead, Junpeng Qiu, 2016/10/25
- [elpa] master a951fbe 41/60: Unify tag names, Junpeng Qiu, 2016/10/25
- [elpa] master dfb3af0 60/60: Add 'packages/parsec/' from commit '8f0c266d8b9b0ee5fcf9b80c518644b2849ff3b3', Junpeng Qiu, 2016/10/25
- [elpa] master 6cc3100 07/60: Fix indentations, Junpeng Qiu, 2016/10/25
- [elpa] master d98e8c8 05/60: Add url-encoded string parser, Junpeng Qiu, 2016/10/25
- [elpa] master a268b9f 08/60: Add more APIs,
Junpeng Qiu <=
- [elpa] master 13637e1 15/60: Rename parsec-do-parse to parsec-with-input, Junpeng Qiu, 2016/10/25
- [elpa] master ba23b01 19/60: Add more APIs, Junpeng Qiu, 2016/10/25
- [elpa] master f3ce070 09/60: Add simple scheme parser, Junpeng Qiu, 2016/10/25
- [elpa] master 9bc1d77 28/60: Move examples to under sub-directory, Junpeng Qiu, 2016/10/25
- [elpa] master 52f1886 33/60: Update pjson, Junpeng Qiu, 2016/10/25
- [elpa] master 7e65db0 51/60: Merge pull request #1 from tarsius/master, Junpeng Qiu, 2016/10/25
- [elpa] master 311a5ca 49/60: Fix typo, Junpeng Qiu, 2016/10/25
- [elpa] master e6d5f38 46/60: Update the comment in source file, Junpeng Qiu, 2016/10/25
- [elpa] master 8c22dcb 39/60: Add :group example, Junpeng Qiu, 2016/10/25
- [elpa] master a45d8f4 03/60: Error propagation to pl-until, Junpeng Qiu, 2016/10/25