Skip to content

Instantly share code, notes, and snippets.

@borkdude
Last active May 8, 2021 12:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save borkdude/4e66410b09894b544d4d26483014815b to your computer and use it in GitHub Desktop.
Save borkdude/4e66410b09894b544d4d26483014815b to your computer and use it in GitHub Desktop.
Jasentaa parser combinator with babashka
#!/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