Add more parsing combinators
This commit is contained in:
		
							
								
								
									
										57
									
								
								origami.el
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								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-consume-while (lambda (x) | ||||||
|  |                                                      (not (equal x "{")))) | ||||||
|  |                      (origami-parser-paired (origami-parser-char "{") | ||||||
|                                             (origami-parser-char "}") |                                             (origami-parser-char "}") | ||||||
|                                              (origami-parser-return nil))) |                                             (origami-do | ||||||
|  (origami-content 7 "{}{}{}{}{}")) |                                              (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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user