summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoutade <thegoofist@protonmail.com>2020-03-06 20:58:00 -0600
committerBoutade <thegoofist@protonmail.com>2020-03-06 20:58:00 -0600
commit1181af61564962efcd3cfcfcb651371d86e86714 (patch)
treea809a1d29bd00be6d1a7955a54291e61d8393c67
parentf448fcdb3319e74644d66c671c30c232d770615f (diff)
added <<until combinator
-rw-r--r--package.lisp1
-rw-r--r--parzival.asd2
-rw-r--r--parzival.lisp21
3 files changed, 22 insertions, 2 deletions
diff --git a/package.lisp b/package.lisp
index 8b33dac..9d8f654 100644
--- a/package.lisp
+++ b/package.lisp
@@ -13,6 +13,7 @@
#:<<if
#:<<when
#:<<plus
+ #:<<until
#:<<or
#:<<~
#:<<?
diff --git a/parzival.asd b/parzival.asd
index 1814260..168389c 100644
--- a/parzival.asd
+++ b/parzival.asd
@@ -4,7 +4,7 @@
:description "Streaming parser language in Common Lisp."
:author "Boutade <thegoofist@protonmail.com>"
:license "GPLv3"
- :version "0.1.0"
+ :version "0.2.0"
:serial t
:depends-on (#:replay-streams)
:components ((:file "package")
diff --git a/parzival.lisp b/parzival.lisp
index 35d6304..d00a1d4 100644
--- a/parzival.lisp
+++ b/parzival.lisp
@@ -119,6 +119,26 @@ in then. If the parse fails the combinator else is run instead."
(rewind-to stream chkpt)
parser2)))))
+(defun <<until (parser)
+ "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)))))
+
(defun <<or (&rest parsers)
"Tries each parser one after the other, rewinding the input stream after each
failure, and resulting in the first successful parse."
@@ -200,7 +220,6 @@ in then. If the parse fails the combinator else is run instead."
(lambda (result)
(<<map (returning result) <eof<))))
-
;;; PARSING INDIVIDUAL ITEMS from the stream. The basic parser thats of any real
;;; use is <<sat. It lets you check that a stream item meets some kind of
;;; condition, and fails to parse if it does not. The follwing section contains