Add more parsing combinators
This commit is contained in:
parent
3584641d4e
commit
b55125cc8b
59
origami.el
59
origami.el
@ -201,42 +201,65 @@ used to nil out data. This mutates the node."
|
|||||||
(origami-do (content <- (origami-parser-get))
|
(origami-do (content <- (origami-parser-get))
|
||||||
(origami-parser-return (origami-content-consumed-count content))))
|
(origami-parser-return (origami-content-consumed-count content))))
|
||||||
|
|
||||||
(defun origami-parser-sat (p)
|
(defun origami-parser-sat (pred)
|
||||||
(origami-do (pos <- (origami-parser-position))
|
(origami-do (pos <- (origami-parser-position))
|
||||||
(a <- (origami-parser-item))
|
(a <- (origami-parser-item))
|
||||||
(if (funcall p a)
|
(if (funcall pred a)
|
||||||
(origami-parser-return pos)
|
(origami-parser-return pos)
|
||||||
(origami-parser-zero))))
|
(origami-parser-zero))))
|
||||||
|
|
||||||
(defun origami-parser-char (x)
|
(defun origami-parser-char (x)
|
||||||
(origami-parser-sat (lambda (c) (equal x c))))
|
(origami-parser-sat (lambda (c) (equal x c))))
|
||||||
|
|
||||||
(defun origami-parser-paired (start end children)
|
(defun origami-parser-conj (p1 p2)
|
||||||
(origami-do (begin <- start)
|
(lambda (content)
|
||||||
(children <- children)
|
(or (origami-run-parser p1 content)
|
||||||
(end <- end)
|
(origami-run-parser p2 content))))
|
||||||
(origami-parser-return (origami-fold-node begin end t children))))
|
|
||||||
|
|
||||||
(defun origami-parser-many (p)
|
(defun origami-parser-0+ (p)
|
||||||
|
(origami-parser-conj
|
||||||
|
(origami-parser-1+ p)
|
||||||
|
(origami-parser-return nil)))
|
||||||
|
|
||||||
|
(defun origami-parser-1+ (p)
|
||||||
;; recursive isn't going to cut it in elisp
|
;; recursive isn't going to cut it in elisp
|
||||||
(lambda (content)
|
(lambda (content)
|
||||||
(let ((res (origami-run-parser p content))
|
(let ((res (origami-run-parser p content))
|
||||||
(acc nil))
|
(acc nil))
|
||||||
(while res
|
(while res
|
||||||
(setq acc (cons (car res) acc))
|
(setq acc (cons (car res) acc))
|
||||||
(setq res (origami-run-parser p (cdr res))))
|
(setq content (cdr res))
|
||||||
(reverse acc))))
|
(setq res (origami-run-parser p content)))
|
||||||
|
(when acc
|
||||||
|
(cons (reverse acc) content)))))
|
||||||
|
|
||||||
(defun origami-parser-conj (p1 p2)
|
(defun origami-parser-1? (p)
|
||||||
(lambda (content)
|
(origami-parser-conj p (origami-parser-return nil)))
|
||||||
(or (origami-run-parser p1 content)
|
|
||||||
(origami-run-parser p2 content))))
|
(defun origami-parser-paired (start end children)
|
||||||
|
(origami-do (begin <- start)
|
||||||
|
(children <- (origami-parser-0+ children))
|
||||||
|
(end <- end)
|
||||||
|
(origami-parser-return (origami-fold-node begin end t children))))
|
||||||
|
|
||||||
|
(defun origami-parser-consume-while (pred)
|
||||||
|
(origami-do (positions <- (origami-parser-1+ (origami-parser-sat pred)))
|
||||||
|
(origami-parser-return (car (last positions)))))
|
||||||
|
|
||||||
(origami-run-parser
|
(origami-run-parser
|
||||||
(origami-parser-many (origami-parser-paired (origami-parser-char "{")
|
(origami-parser-0+ (origami-do
|
||||||
(origami-parser-char "}")
|
(origami-parser-consume-while (lambda (x)
|
||||||
(origami-parser-return nil)))
|
(not (equal x "{"))))
|
||||||
(origami-content 7 "{}{}{}{}{}"))
|
(origami-parser-paired (origami-parser-char "{")
|
||||||
|
(origami-parser-char "}")
|
||||||
|
(origami-do
|
||||||
|
(origami-parser-consume-while (lambda (x) (and (not (equal x "}"))
|
||||||
|
(not (equal x "{")))))
|
||||||
|
(origami-parser-1?
|
||||||
|
(origami-parser-paired (origami-parser-char "{")
|
||||||
|
(origami-parser-char "}")
|
||||||
|
(origami-parser-zero)))))))
|
||||||
|
(origami-content 7 " { {} } { } "))
|
||||||
|
|
||||||
;;; TODO: rework this
|
;;; TODO: rework this
|
||||||
(defun origami-parse (buffer parser)
|
(defun origami-parse (buffer parser)
|
||||||
|
Loading…
Reference in New Issue
Block a user