diff options
author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2024-10-12 16:43:50 -0300 |
---|---|---|
committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2024-10-12 16:43:50 -0300 |
commit | b196a5d56db31d6836c1ed028f38146cbb08436c (patch) | |
tree | ffe56d98484b4897b3c2be4a9d98cb87b6bba8f6 /parser.lisp | |
parent | 1b00d7b4b1eaa3b1ce2ea12e3bfa255450143cb5 (diff) | |
download | monparser-b196a5d56db31d6836c1ed028f38146cbb08436c.tar.gz monparser-b196a5d56db31d6836c1ed028f38146cbb08436c.zip |
Implement literal as a macro that chains unit
Diffstat (limited to 'parser.lisp')
-rw-r--r-- | parser.lisp | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/parser.lisp b/parser.lisp index d22ae81..c627af1 100644 --- a/parser.lisp +++ b/parser.lisp @@ -40,10 +40,6 @@ :message (format nil "Didn't reach expected limit: ~a." limit)) (make-parsing :tree tree :left input)))) -(defun fail (message) - (lambda (input &key limit lazy) - (make-failure :place input :message message))) - (defun bind (p f &key (greedy t)) (lambda (input &key limit lazy) (let (r) @@ -127,6 +123,10 @@ result)))) (one-of-rec (cons first-parser (cons second-parser other-parsers)))))) +(defun fail (message) + (lambda (input &key limit lazy) + (make-failure :place input :message message))) + (defmacro unit (&optional predicate) (cond ((null predicate) (setf predicate '(characterp it))) @@ -151,14 +151,18 @@ :message (format nil "Expected: ~a, Got: ~a" ',predicate it)))) (make-failure :place input :message "Reached end of input."))))) -(defun literal (target) - (lambda (input &key limit lazy) - (declare (ignore lazy limit)) - (if (has-data? input) - (if (prefix? target input) - (make-parsing :tree target :left (advance input (length target))) - (make-failure :place input :message "Predicate not satisfied.")) - (make-failure :place input :message "Reached end of input.")))) +(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) + (coerce ,(cons 'list (reverse name-list)) 'string)))) (defparameter nothing (new nil)) |