Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First implementation. #1

Closed
diasbruno opened this issue May 22, 2018 · 0 comments
Closed

First implementation. #1

diasbruno opened this issue May 22, 2018 · 0 comments

Comments

@diasbruno
Copy link
Owner

In this first implementation, the goal is to make it easy to parse and apply transformations on the parsed items.

Combinators:

  • (:char #\a) test the next element on the stream with the given char.
  • (:one #'fn) test using a function to get the next char in the stream.
  • (:string "abc") test if the string is in the stream.
  • (:and exp ...) collect many expressions.
  • (:or exp ...) collect the expression that matches.
  • (:many exp) collect all matches of the expression, if any.
  • (:maybe exp) turns the failed test into a valid one.

Declaration

A macro is used to declare all rules for the BNF.

(:= word (:many (:one #'alpha-char-p)) :call #'stringify)

Valid transformations:

  • :call apply a function to the results using funcall.
  • :apply apply a function to the results using apply.
  • :tag return a cons like (cons TAG RESULTS).
  • If none where specified, it return a nested list of all matches.

Example

Parsing a valid json number:

(load #P"~/projects/cl-bnf/cl-bnf.lisp")

(:= decimal-number (:many (:one #'numeric-char-p)))
(:= real-number (:or (:and #'decimal-number
                           (:char #\.)
                           #'decimal-number)
                     (:and #'decimal-number
                           (:char #\.))))
(:= signed-part (:or (:char #\+) (:char #\-)))
(:= exp-chars (:or (:char #\e)
                   (:char #\E)))
(:= exp-part (:or (:and #'exp-chars
                        #'signed-part
                        #'decimal-number)
                  (:and #'exp-chars
                        #'decimal-number)))
(:= numeric (:or #'real-number
                 #'decimal-number))
(:= number-literal (:or (:and #'numeric
                              #'exp-part)
                        #'numeric)
    :call (lambda (matches)
            (cons :number (stringify matches))))

(parse #number-literal "1e3")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant