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