(in-package #:monparser) (defparameter whitespace (many (unit #'char:whitespace?))) (defparameter end-of-input (lambda (input) (if (cursed:has-data? input) (make-failure :place input :message "Didn't reach end of input.") (make-parsing :tree nil :start input :end input)))) (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))) (defmacro literal (word) (when (not (stringp word)) (error "Literal only accepts strings as input.")) (let ((binding-list '()) (name-list '())) (loop :for c :across word :do (when c (let ((name (gensym))) (push name name-list) (push `(,name (unit ,c)) binding-list)))) `(comp ,(reverse binding-list) ,(cons 'list (reverse name-list))))) (defmacro within (left p right) `(comp ((_ ,left) (cell ,p) (_ ,right)) cell)) (defmacro interlinked (p separator) `(many (comp ((cell ,p) (_ (optional ,separator))) cell)))