summaryrefslogtreecommitdiff
path: root/quant.lisp
diff options
context:
space:
mode:
authorJuan Manuel Tomás <jtomas1815@gmail.com>2025-06-15 07:24:38 -0300
committerJuan Manuel Tomás <jtomas1815@gmail.com>2025-06-15 07:24:38 -0300
commit4d355a842737f7938d148c53338ce6f3fa055628 (patch)
tree487f11aa2d2deef57c9f0078d2e802449bce1cc0 /quant.lisp
parent66b6d675055eb8a5017376eb6f43d609887d1289 (diff)
downloadmonparser-4d355a842737f7938d148c53338ce6f3fa055628.tar.gz
monparser-4d355a842737f7938d148c53338ce6f3fa055628.zip
Make many into an iterative parser
Diffstat (limited to 'quant.lisp')
-rw-r--r--quant.lisp33
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)))