(in-package #:monparser) (defun whitespace? (it) (or (char= it #\Space) (not (graphic-char-p it)))) (declaim (ftype (function (parser integer &optional integer) parser) repeat)) (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))))) (declaim (ftype (function (parser parser &optional parser) parser) within)) (defun within (left p &optional right) (comp ((_ left) (cell p) (_ (or right left))) cell)) (declaim (ftype (function (parser parser) parser) interlinked)) (defun interlinked (p separator) (many (comp ((cell p) (_ (optional separator))) cell)))