diff options
author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2025-06-15 07:24:38 -0300 |
---|---|---|
committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2025-06-15 07:24:38 -0300 |
commit | 4d355a842737f7938d148c53338ce6f3fa055628 (patch) | |
tree | 487f11aa2d2deef57c9f0078d2e802449bce1cc0 /quant.lisp | |
parent | 66b6d675055eb8a5017376eb6f43d609887d1289 (diff) | |
download | monparser-4d355a842737f7938d148c53338ce6f3fa055628.tar.gz monparser-4d355a842737f7938d148c53338ce6f3fa055628.zip |
Make many into an iterative parser
Diffstat (limited to 'quant.lisp')
-rw-r--r-- | quant.lisp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/quant.lisp b/quant.lisp new file mode 100644 index 0000000..bdd0cfc --- /dev/null +++ b/quant.lisp @@ -0,0 +1,33 @@ +(in-package #:monparser) + +(defparameter nothing + (new nil)) + +(defun optional (p) + (one-of p nothing)) + +(defun many (p &key all) + (lambda (input) + (let* ((result '()) + (last-failure + (do ((r (funcall p input) (funcall p input))) ((failure-p r) r) + (when (parsing-p r) + (setf input (parsing-left r)) + (when (parsing-tree r) + (push (parsing-tree r) result)))))) + (if (or (not result) + (and result all (has-data? (failure-place last-failure)))) + (make-failure :place input :message (failure-message last-failure)) + (make-parsing :tree (reverse result) :left input))))) + +; TODO: Need to be redone in a non-recursive way +(defun repeat (p min &optional (max 0)) + (if (> min 0) + (comp ((x p) + (xs (repeat p (1- min) (1- max)))) + (cons x xs)) + (if (> max 0) + (comp ((x (optional p)) + (xs (repeat p 0 (if x (1- max) 0)))) + (if x (cons x xs) x)) + nothing))) |