diff options
author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2024-11-08 15:06:17 -0300 |
---|---|---|
committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2024-11-08 15:06:17 -0300 |
commit | 688ade34430eb1d4d205698cae810c35c8f44d21 (patch) | |
tree | fe3e043c28eaf9beafe8f0be60c0ad6b43fe84bb | |
parent | 4e25074286e83a9e7b980e931284ad795361de94 (diff) | |
download | monparser-main.tar.gz monparser-main.zip |
-rw-r--r-- | base.lisp | 30 | ||||
-rw-r--r-- | core.lisp | 54 | ||||
-rw-r--r-- | package.lisp | 1 |
3 files changed, 43 insertions, 42 deletions
@@ -13,18 +13,18 @@ (declare (ignore lazy)) (make-parsing :tree tree :left input))) -(defun bind (parser f) - (lambda (input &key lazy) - (let ((r (funcall parser input))) - (cond ((parsing-p r) - (if lazy - (lambda (ignored-input &key lazy) - (declare (ignore ignored-input)) - (funcall (funcall f (parsing-tree r) input) - (parsing-left r) - :lazy lazy)) - (funcall (funcall f (parsing-tree r) input) - (parsing-left r)))) - ((failure-p r) - r) - (t (error (format nil "Invalid return value: ~a" r))))))) +(defmacro bind (parser f) + `(lambda (input &key lazy) + (let ((r (funcall ,parser input))) + (cond ((parsing-p r) + (if lazy + (lambda (ignored-input &key lazy) + (declare (ignore ignored-input)) + (funcall (funcall ,f (parsing-tree r) input) + (parsing-left r) + :lazy lazy)) + (funcall (funcall ,f (parsing-tree r) input) + (parsing-left r)))) + ((failure-p r) + r) + (t (error (format nil "Invalid return value: ~a" r))))))) @@ -30,33 +30,33 @@ :message (format nil "Expected: ~a, Got: ~a" ',predicate it)))) (make-failure :place input :message "Reached end of input.")))) -(defun one-of (first-parser second-parser &rest other-parsers) - (lambda (input &key lazy) - (declare (ignore lazy)) - (labels ((one-of-rec (parsers) - (let ((intermediate-parsers '()) - (result (make-failure :place input - :message "Exhausted options."))) - (dolist (p parsers) - (let ((r (funcall p - input - :lazy (> (length parsers) 1)))) - (cond ((functionp r) - (push r intermediate-parsers)) - ((parsing-p r) - (when (or (not (parsing-p result)) - (> (input-cursor (parsing-left r)) - (input-cursor (parsing-left result)))) - (setf result r))) - ((failure-p r) - (when (or (failure-p result) - (= (length parsers) 1)) - (setf result r))) - (t (error (format nil "Invalid return value: ~a" r)))))) - (if intermediate-parsers - (one-of-rec intermediate-parsers) - result)))) - (one-of-rec (cons first-parser (cons second-parser other-parsers)))))) +(defmacro one-of (first-parser second-parser &rest other-parsers) + `(lambda (input &key lazy) + (declare (ignore lazy)) + (labels ((one-of-rec (parsers) + (let ((intermediate-parsers '()) + (result (make-failure :place input + :message "Exhausted options."))) + (dolist (p parsers) + (let ((r (funcall p + input + :lazy (> (length parsers) 1)))) + (cond ((functionp r) + (push r intermediate-parsers)) + ((parsing-p r) + (when (or (not (parsing-p result)) + (> (input-cursor (parsing-left r)) + (input-cursor (parsing-left result)))) + (setf result r))) + ((failure-p r) + (when (or (failure-p result) + (= (length parsers) 1)) + (setf result r))) + (t (error (format nil "Invalid return value: ~a" r)))))) + (if intermediate-parsers + (one-of-rec intermediate-parsers) + result)))) + (one-of-rec (list ,first-parser ,second-parser ,@other-parsers))))) (defmacro comp (bindings &body body) (if (null bindings) diff --git a/package.lisp b/package.lisp index bd3f17b..cf3f1df 100644 --- a/package.lisp +++ b/package.lisp @@ -15,6 +15,7 @@ #:optional #:many #:repeat + #:whitespace? #:whitespace #:separated-list #:surround)) |