diff options
author | Boutade <thegoofist@protonmail.com> | 2020-03-07 07:12:34 -0600 |
---|---|---|
committer | Boutade <thegoofist@protonmail.com> | 2020-03-07 07:12:34 -0600 |
commit | db9bab71b4660062c601ab527b1dfdbcc884cc21 (patch) | |
tree | e072fbb3a2a43c84cd64c8c0f6d16983fb364ef2 | |
parent | 1181af61564962efcd3cfcfcb651371d86e86714 (diff) |
added <<ignore-until
-rw-r--r-- | package.lisp | 1 | ||||
-rw-r--r-- | parzival.asd | 2 | ||||
-rw-r--r-- | parzival.lisp | 43 |
3 files changed, 30 insertions, 16 deletions
diff --git a/package.lisp b/package.lisp index 9d8f654..dc26c34 100644 --- a/package.lisp +++ b/package.lisp @@ -14,6 +14,7 @@ #:<<when #:<<plus #:<<until + #:<<ignore-until #:<<or #:<<~ #:<<? diff --git a/parzival.asd b/parzival.asd index 168389c..c819f69 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.2.0" + :version "0.3.0" :serial t :depends-on (#:replay-streams) :components ((:file "package") 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 |