diff options
author | Boutade <thegoofist@protonmail.com> | 2020-03-06 20:58:00 -0600 |
---|---|---|
committer | Boutade <thegoofist@protonmail.com> | 2020-03-06 20:58:00 -0600 |
commit | 1181af61564962efcd3cfcfcb651371d86e86714 (patch) | |
tree | a809a1d29bd00be6d1a7955a54291e61d8393c67 | |
parent | f448fcdb3319e74644d66c671c30c232d770615f (diff) |
added <<until combinator
-rw-r--r-- | package.lisp | 1 | ||||
-rw-r--r-- | parzival.asd | 2 | ||||
-rw-r--r-- | parzival.lisp | 21 |
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 |