Last active
August 29, 2015 14:01
-
-
Save db48x/a0f68f85fa6ca1420ab8 to your computer and use it in GitHub Desktop.
parser combinators for parsing dice expressions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (defun labeled-dice-expressions () | |
| (series (either (label) | |
| (nothing)) | |
| (either (dice-expression) | |
| (nothing)))) | |
| (defun dice-expression () | |
| (series (sum-expression) | |
| (optional (whitespace)) | |
| (token "⇒") | |
| (optional (whitespace)) | |
| (sum-expression) | |
| (optional (whitespace)) | |
| (token "=") | |
| (optional (whitespace)) | |
| (number))) | |
| (defun sum-expression () | |
| (series (either (dice-expression) | |
| (number)) | |
| (optional (whitespace)) | |
| (either (token "+") | |
| (token "-")) | |
| (optional (whitespace)) | |
| (sum-expression))) | |
| (defun dice-expression () | |
| (series (optional (number)) | |
| (token "d") | |
| (number))) | |
| ;;; these are the parser combinators, they compose parser functions | |
| ;;; into more complex parser functions | |
| (defun optional (parser) | |
| (lambda (text) | |
| (let ((r (parser text))) | |
| (or r (list "" text))))) | |
| (defun either (&rest parsers) | |
| ;; test this, but I'm pretty sure that until returns the value of | |
| ;; the test expression, which is what we want | |
| (lambda (text) | |
| (loop for parser in parsers | |
| until (parser text)))) | |
| (defun all (&rest parsers) | |
| ;; should do this ourselves, so that we can stop when one fails | |
| ;; (or maybe that's alexandria:conjoin?) | |
| (lambda (text) | |
| (apply #'alexandria:compose parsers))) | |
| ;;; the primitive parser generator; creates a parser that matches a | |
| ;;; simple token at the beginning of the text | |
| (defun token (token) | |
| (lambda (text) | |
| (if (starts-with text token) | |
| (list (subseq text 0 (length token)) | |
| (subseq text (length token)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment