diff options
author | Juan Manuel Tomás <jtomas1815@gmail.com> | 2025-06-15 07:24:38 -0300 |
---|---|---|
committer | Juan Manuel Tomás <jtomas1815@gmail.com> | 2025-06-15 07:24:38 -0300 |
commit | 4d355a842737f7938d148c53338ce6f3fa055628 (patch) | |
tree | 487f11aa2d2deef57c9f0078d2e802449bce1cc0 /core.lisp | |
parent | 66b6d675055eb8a5017376eb6f43d609887d1289 (diff) | |
download | monparser-4d355a842737f7938d148c53338ce6f3fa055628.tar.gz monparser-4d355a842737f7938d148c53338ce6f3fa055628.zip |
Make many into an iterative parser
Diffstat (limited to 'core.lisp')
-rw-r--r-- | core.lisp | 51 |
1 files changed, 21 insertions, 30 deletions
@@ -30,37 +30,28 @@ (make-failure :place input :message (format nil "Reached end of input. Expected: ~a." ',predicate))))) -(defparameter end +(defun one-of (first-parser second-parser &rest other-parsers) (lambda (input) - (if (has-data? input) - (make-failure :place input :message "Didn't reach end of input.") - (make-parsing :tree nil :left input)))) - -(defun select-parser (input parsers) - (let ((result (make-failure :place input))) - (dolist (p parsers) - (let ((r (funcall p input))) - (cond ((parsing-p r) - (when (or (not (parsing-p result)) - (> (input-cursor (parsing-left r)) - (input-cursor (parsing-left result)))) - (setf result r))) - ((failure-p r) - (when (failure-p result) - (let ((priority-cmp (- (failure-priority r) - (failure-priority result)))) - (when (or (> priority-cmp 0) - (and (= priority-cmp 0) - (>= (input-cursor (failure-place r)) - (input-cursor (failure-place result))))) - (setf result r))))) - (t (error (format nil "Invalid return value: ~a." r)))))) - result)) - -(defmacro one-of (first-parser second-parser &rest other-parsers) - `(lambda (input) - (select-parser input - (list ,first-parser ,second-parser ,@other-parsers)))) + (let ((parsers `(,first-parser ,second-parser ,@other-parsers)) + (result (make-failure :place input))) + (dolist (p parsers) + (let ((r (funcall p input))) + (cond ((parsing-p r) + (when (or (not (parsing-p result)) + (> (input-cursor (parsing-left r)) + (input-cursor (parsing-left result)))) + (setf result r))) + ((failure-p r) + (when (failure-p result) + (let ((priority-cmp (- (failure-priority r) + (failure-priority result)))) + (when (or (> priority-cmp 0) + (and (= priority-cmp 0) + (>= (input-cursor (failure-place r)) + (input-cursor (failure-place result))))) + (setf result r))))) + (t (error (format nil "Invalid return value: ~a." r)))))) + result))) ;;; TODO: Find a way to be able to use the input without needing to define a name for it. (defmacro comp (bindings &body body) |