[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master adf4706 20/60: Add many-till, notFollowedBy and fix others
From: |
Junpeng Qiu |
Subject: |
[elpa] master adf4706 20/60: Add many-till, notFollowedBy and fix others |
Date: |
Tue, 25 Oct 2016 17:45:13 +0000 (UTC) |
branch: master
commit adf47065e19dd0df4cdd2adb1a85cc9b26db81cf
Author: Junpeng Qiu <address@hidden>
Commit: Junpeng Qiu <address@hidden>
Add many-till, notFollowedBy and fix others
---
parsec.el | 112 +++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 76 insertions(+), 36 deletions(-)
diff --git a/parsec.el b/parsec.el
index abaa771..bf3348b 100644
--- a/parsec.el
+++ b/parsec.el
@@ -32,11 +32,11 @@
(defvar parsec-last-error-message nil)
-(defun parsec-eob-or-char-as-string ()
+(defun parsec-eof-or-char-as-string ()
(let ((c (char-after)))
(if c
(char-to-string c)
- "`eob'")))
+ "`EOF'")))
(defun parsec-error-new (msg)
(cons 'parsec-error msg))
@@ -71,14 +71,14 @@
(progn (forward-char 1)
(char-to-string ch))
(parsec-stop :expected (char-to-string ch)
- :found (parsec-eob-or-char-as-string)))))
+ :found (parsec-eof-or-char-as-string)))))
(defun parsec-any-ch ()
(if (not (eobp))
(prog1 (char-to-string (char-after))
(forward-char))
(parsec-stop :expected "any char"
- :found (parsec-eob-or-char-as-string))))
+ :found (parsec-eof-or-char-as-string))))
(defun parsec-satisfy (pred)
(let ((next-char (char-after)))
@@ -87,19 +87,19 @@
(progn (forward-char 1)
(char-to-string ch))
(parsec-stop :expected (format "%s" pred)
- :found (parsec-eob-or-char-as-string)))))
+ :found (parsec-eof-or-char-as-string)))))
(defun parsec-eob ()
(unless (eobp)
- (parsec-stop :expected "`eob'"
- :found (parsec-eob-or-char-as-string))))
+ (parsec-stop :expected "`EOF'"
+ :found (parsec-eof-or-char-as-string))))
(defun parsec-re (regexp)
(if (looking-at regexp)
(progn (goto-char (match-end 0))
(match-string 0))
(parsec-stop :expected regexp
- :found (parsec-eob-or-char-as-string))))
+ :found (parsec-eof-or-char-as-string))))
(defsubst parsec-str (str)
(parsec-re (regexp-quote str)))
@@ -127,12 +127,12 @@
(concat "None of the parsers succeeds:\n"
(mapconcat #'identity ,error-str-list-sym
"\n"))))
do
- (parsec-protect-atom
- (parsec-start
- (cl-return-from ,outer-sym
- (parsec-eavesdrop-error ,error-sym
- (parsec-make-atom (eval ,parser-sym))
- (push (parsec-error-str ,error-sym)
,error-str-list-sym)))))))))
+ (parsec-protect-atom parsec-or
+ (parsec-start
+ (cl-return-from ,outer-sym
+ (parsec-eavesdrop-error ,error-sym
+ (parsec-make-atom parsec-or (eval ,parser-sym))
+ (push (parsec-error-str ,error-sym)
,error-str-list-sym)))))))))
(defalias 'parsec-and 'progn)
@@ -159,20 +159,31 @@
(parsec-and ,@forms)
(goto-char ,orig-pt-sym)))))
-(defmacro parsec-protect-atom (parser)
+(defsubst parsec--atom-tag (name)
+ (intern (format "parsec-failed-at-half-%s" name)))
+
+(defmacro parsec-protect-atom (name parser)
"This must be used together with `parsec-make-atom'."
- `(catch 'parsec-success
- (parsec-throw (catch 'parsec-failed-at-half
- (throw 'parsec-success ,parser)))))
+ (declare (indent 1))
+ (let ((tag (parsec--atom-tag name)))
+ `(catch 'parsec-success
+ (parsec-throw (catch ',tag
+ (throw 'parsec-success ,parser))))))
-(defmacro parsec-make-atom (parser)
+(defmacro parsec-make-atom (name parser)
(let ((orig-pt-sym (make-symbol "orig-pt"))
- (error-sym (make-symbol "err")))
+ (error-sym (make-symbol "err"))
+ (tag (parsec--atom-tag name)))
`(let ((,orig-pt-sym (point)))
(parsec-eavesdrop-error ,error-sym
,parser
+ (message "equal=%s" (= (point) ,orig-pt-sym))
(unless (= (point) ,orig-pt-sym)
- (throw 'parsec-failed-at-half ,error-sym))))))
+ (throw ',tag ,error-sym))))))
+
+(defmacro parsec-continue (&rest forms)
+ `(parsec-eavesdrop-error _
+ (parsec-and ,@forms)))
(defmacro parsec-eavesdrop-error (error-sym parser &rest handler)
(declare (indent 2))
@@ -186,7 +197,7 @@
(declare (indent 1))
`(parsec-eavesdrop-error _
(parsec-and ,@forms)
- (parsec-throw (parsec-error-new msg))))
+ (parsec-throw (parsec-error-new ,msg))))
(defmacro parsec-ensure (&rest forms)
(let ((error-sym (make-symbol "err")))
@@ -200,24 +211,14 @@
(parsec-with-error-message ,msg
(parsec-and ,@forms))))
-;;; TODO
-(cl-defmacro parsec-until (parser &optional &key skip)
- `(catch 'done
- (while (not (eobp))
- (parsec-start
- (throw 'done ,parser))
- ,(if skip
- `(,skip 1)
- `(forward-char 1)))))
-
(defmacro parsec-many (parser)
(let ((res-sym (make-symbol "results"))
(error-sym (make-symbol "err")))
`(let (,res-sym)
- (parsec-protect-atom
- (parsec-start
- (while (not (eobp))
- (push (parsec-make-atom ,parser) ,res-sym))))
+ (parsec-protect-atom parsec-many
+ (parsec-start
+ (while (not (eobp))
+ (push (parsec-make-atom parsec-many ,parser) ,res-sym))))
(nreverse ,res-sym))))
(defmacro parsec-many1 (parser)
@@ -232,6 +233,45 @@
(defmacro parsec-many1-as-string (parser)
`(mapconcat #'identity (parsec-many1 ,parser) ""))
+(defmacro parsec-many-till (parser end &optional type)
+ (let ((res-sym (make-symbol "results"))
+ (end-res-sym (make-symbol "end-result")))
+ `(let* (,res-sym
+ (,end-res-sym (catch 'parsec-immediate-stop
+ (while t
+ (parsec-or (throw 'parsec-immediate-stop ,end)
+ (push ,parser ,res-sym))))))
+ (setq ,res-sym (nreverse ,res-sym))
+ ,(cond
+ ((eq type :both) `(cons ,res-sym ,end-res-sym))
+ ((eq type :end) end-res-sym)
+ (t res-sym)))))
+
+(defmacro parsec-many-till-as-string (parser end &optional type)
+ (let ((res-sym (make-symbol "results")))
+ (cond
+ ((eq type :both)
+ `(let ((,res-sym (parsec-many-till ,parser ,end ,type)))
+ (cons (parsec-list-to-string (car ,res-sym)) (cdr ,res-sym))))
+ (t
+ `(parsec-list-to-string (parsec-many-till ,parser ,end ,type))))))
+
+(defmacro parsec-until (parser &optional type)
+ `(parsec-many-till (parsec-any-ch) ,parser ,type))
+
+(defmacro parsec-until-as-string (parser &optional type)
+ `(parsec-many-till-as-string (parsec-any-ch) ,parser ,type))
+
+(defmacro parsec-not-followed-by (parser)
+ (let ((res-sym (make-symbol "results")))
+ `(catch 'parsec-not-followed-by
+ (let ((,res-sym
+ (catch 'parsec-immediate-stop
+ (throw 'parsec-not-followed-by
+ (parsec-or (throw 'parsec-immediate-stop (parsec-try
,parser))
+ nil)))))
+ (parsec-stop :message (format "Unexpected followed by: %s"
,res-sym))))))
+
(defmacro parsec-endby (parser end)
`(parsec-many (parsec-return ,parser
,end)))
- [elpa] master 34521c6 53/60: Update README about *-s functions, (continued)
- [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
- [elpa] master bf49fb6 38/60: Upate README, Junpeng Qiu, 2016/10/25
- [elpa] master 966ca9e 43/60: Add comments to parsec.el, Junpeng Qiu, 2016/10/25
- [elpa] master c61a38c 22/60: Add convenient newline methods, Junpeng Qiu, 2016/10/25
- [elpa] master 0c3408a 01/60: Init commit, Junpeng Qiu, 2016/10/25
- [elpa] master 1929932 02/60: Split into two files, Junpeng Qiu, 2016/10/25
- [elpa] master fd77961 25/60: Add a few simple API, Junpeng Qiu, 2016/10/25
- [elpa] master 12d2ad6 24/60: Bug fixes, Junpeng Qiu, 2016/10/25
- [elpa] master adf4706 20/60: Add many-till, notFollowedBy and fix others,
Junpeng Qiu <=
- [elpa] master 32809ad 30/60: Add parsec-error-new-2, Junpeng Qiu, 2016/10/25
- [elpa] master 3503e4a 13/60: Rename for easier understanding, Junpeng Qiu, 2016/10/25
- [elpa] master 4fb2abe 29/60: Update simple-csv-parser, Junpeng Qiu, 2016/10/25
- [elpa] master fa2e6f1 27/60: Add gitignore, Junpeng Qiu, 2016/10/25
- [elpa] master a06220c 42/60: Update README, Junpeng Qiu, 2016/10/25
- [elpa] master f7e8629 26/60: Add tests, Junpeng Qiu, 2016/10/25
- [elpa] master bc11325 50/60: Add file examples/.nosearch, Junpeng Qiu, 2016/10/25
- [elpa] master 1da4344 32/60: Update url-str-parser, Junpeng Qiu, 2016/10/25
- [elpa] master 89dd2ac 54/60: Fix some wording in README, Junpeng Qiu, 2016/10/25
- [elpa] master 55515ca 48/60: Add missing dependencies, Junpeng Qiu, 2016/10/25