Skip to content

Instantly share code, notes, and snippets.

@takeoutweight
Forked from roman/gist:2339136
Created April 9, 2012 22:01
Show Gist options
  • Save takeoutweight/2346868 to your computer and use it in GitHub Desktop.
Save takeoutweight/2346868 to your computer and use it in GitHub Desktop.
(ns parse2
(:refer-clojure :exclude [char])
(:require [clojure.core :as core]
[clojure.string :as str]
[clojure.java.io :as io]
[zetta.core :as z]
[zetta.parser.seq :as s]
[zetta.combinators :as c])
(:use [zetta.core :only [<$> <* *> <|> do-parser]]))
(defn maybe
"returns nil or a single-element list containing the successful parse."
[p]
(c/option nil (<$> list p)))
(declare anything)
(def thing (s/satisfy? #{123}))
;left-factored dotted-pair or list parser.
(def form-contents
(do-parser [t1 anything
t2 (maybe (c/choice [anything (s/satisfy? #{'.})]))
t3 (maybe anything)
end? (c/many anything)]
(if (some #{'.} t2)
(if (and (not-empty t3)
(empty? end?))
(hash-map t1 (first t3))
(str "Ill-formed dotted pair: " t1 "," t3 "," end?)) ;aside: not failing the parse in the monad-- probably a better way?
(apply list t1 (concat t2 t3 end?)))))
(def anything
(c/choice [(<$> #(:result (z/parse-once form-contents %)) (s/satisfy? list?))
thing]))
;parse2> (z/parse-once anything '[(123 . (123 . (123 123 123)))])
;#zetta.core.ResultDone{:remainder (), :result {123 {123 (123 123 123)}}}
;Is this close to how you'd idiomatically parse nested structures w/ zetta?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment