Add more parsing combinators

This commit is contained in:
Greg Sexton 2014-04-13 20:24:33 +01:00
parent 3584641d4e
commit b55125cc8b

View File

@ -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)