summaryrefslogtreecommitdiff
path: root/parzival.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'parzival.lisp')
-rw-r--r--parzival.lisp43
1 files changed, 28 insertions, 15 deletions
diff --git a/parzival.lisp b/parzival.lisp
index d00a1d4..4c47c32 100644
--- a/parzival.lisp
+++ b/parzival.lisp
@@ -123,21 +123,34 @@ in then. If the parse fails the combinator else is run instead."
"Consumes the stream one character at a time until PARSER succeeds. The parse
value of (<<UNTIL PARSER) is a list of the characters consumed, ending in the
value parsed by PARSER."
- (lambda (stream)
- (let ((collected nil))
- (labels ((rec (stream)
- (let ((chkpt (replay-streams:checkpoint stream)))
- (<<if (result parser stream)
- (progn
- (replay-streams:free-checkpoint stream chkpt)
- (<<result (reverse (cons result collected))))
- (progn
- (replay-streams:rewind-to stream chkpt)
- (<<bind <item<
- (lambda (item)
- (push item collected)
- #'rec)))))))
- (rec stream)))))
+ (let ((collected nil))
+ (labels ((rec (stream)
+ (let ((chkpt (replay-streams:checkpoint stream)))
+ (<<if (result parser stream)
+ (progn
+ (replay-streams:free-checkpoint stream chkpt)
+ (<<result (reverse (cons result collected))))
+ (progn
+ (replay-streams:rewind-to stream chkpt)
+ (<<bind <item<
+ (lambda (item)
+ (push item collected)
+ #'rec)))))))
+ #'rec)))
+
+(defun <<ignore-until (parser)
+ "Just like <<UNTIL except it does not build up intermediate results. Results
+ in the result of PARSER."
+ (labels ((rec (stream)
+ (let ((chkpt (checkpoint stream)))
+ (<<if (result parser stream)
+ (progn
+ (free-checkpoint stream chkpt)
+ (<<result result))
+ (progn
+ (rewind-to stream chkpt)
+ (<<and <item< #'rec))))))
+ #'rec))
(defun <<or (&rest parsers)
"Tries each parser one after the other, rewinding the input stream after each