(in-package #:monparser) (defun parse (parser data) (if (typep data 'string) (funcall parser (make-instance 'text :data data) (make-instance 'text :data data)) (error "Only string parsing is allowed."))) (defun append-on-failure (p message) (lambda (start input) (let ((result (funcall p start input))) (if (failure-p result) (make-failure :place (failure-place result) :message (concatenate 'string message (failure-message result)) :priority (failure-priority result)) result)))) (defmacro defparser (name args parser) (let ((message (format nil "In ~a:~&" name))) (cond ((equal args :const) `(defparameter ,name (append-on-failure ,parser ,message))) ((listp args) `(defun ,name ,args (append-on-failure ,parser ,message))) (t (error (format nil "Cannot define ~a: ~a is not :const or a list." name args))))))