Last active
May 8, 2021 12:15
-
-
Save borkdude/4e66410b09894b544d4d26483014815b to your computer and use it in GitHub Desktop.
Jasentaa parser combinator with babashka
This file contains 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
#!/usr/bin/env bb | |
(require '[babashka.deps :as deps]) | |
(deps/add-deps '{:deps {jasentaa/jasentaa | |
{:git/url "https://github.com/borkdude/jasentaa" | |
:sha "7161b0bd8029eb29760abd1eb3026a48a8cde318"}}}) | |
(ns jasentaa.worked-example-1 | |
(:require | |
[jasentaa.monad :as m] | |
[jasentaa.parser :refer [parse-all]] | |
[jasentaa.parser.basic :refer :all] | |
[jasentaa.parser.combinators :refer :all] | |
[jasentaa.position :refer [strip-location]])) | |
(def digit (from-re #"[0-9]")) | |
(def letter (from-re #"[a-z]")) | |
(def alpha-num (any-of letter digit)) | |
(declare search-expr) | |
(def single-word | |
(m/do* | |
(w <- (token (plus alpha-num))) | |
(m/return (strip-location w)))) | |
(def quoted-string | |
(m/do* | |
(symb "\"") | |
(t <- (plus (any-of digit letter (match " ")))) | |
(symb "\"") | |
(m/return (strip-location t)))) | |
(def bracketed-expr | |
(m/do* | |
(symb "(") | |
(expr <- (token search-expr)) | |
(symb ")") | |
(m/return expr))) | |
(def search-term | |
(m/do* | |
(neg <- (optional (symb "not"))) | |
(term <- (any-of single-word quoted-string bracketed-expr)) | |
(m/return (if (empty? neg) term (list :NOT term))))) | |
(def search-and | |
(m/do* | |
(lst <- (separated-by search-term (symb "and"))) | |
(m/return (if (= (count lst) 1) | |
(first lst) | |
(cons :AND lst))))) | |
(def search-expr | |
(m/do* | |
(lst <- (separated-by search-and (symb "or"))) | |
(m/return (if (= (count lst) 1) | |
(first lst) | |
(cons :OR lst))))) | |
(prn (parse-all search-expr "wood and blue or red")) | |
;; => (:OR (:AND "wood" "blue") "red") | |
(prn (parse-all search-expr "wood and (blue or red)")) | |
;; => (:AND "wood" (:OR "blue" "red")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment