Skip to content

Instantly share code, notes, and snippets.

@cgrand
Created September 10, 2009 13:28
Show Gist options
  • Save cgrand/184549 to your computer and use it in GitHub Desktop.
Save cgrand/184549 to your computer and use it in GitHub Desktop.
(def simple-lisp
(parser
{:main [[:w ? :expr]* :w ?]
:expr #{:symbol ["("[:w ? :expr]* :w ? ")"]}
:symbol #"\w+"
:w #"\s+"}))
;; helper functions to display results in a more readable way
(defn terse-result [[items _]]
(map (fn self [item]
(if (map? item)
(cons (:class item) (map self (:contents item)))
item)) items))
(defn prn-terse [results]
(doseq [result results]
(prn (terse-result result))))
;; let's parse this snippet
(-> simple-lisp (step "()(hello)") results prn-terse)
;;> ((:main (:expr "()") (:expr "(" (:expr (:symbol "hello")) ")")))
;; let's parse this snippet in two steps
(-> simple-lisp (step "()(hel") (step "lo)") results prn-terse)
;;> ((:main (:expr "()") (:expr "(" (:expr (:symbol "hello")) ")")))
;; and now, the incremental parsing!
(let [c1 (-> simple-lisp reset (step "()(hel"))
c2 (-> c1 reset (step "lo)" nil))
_ (-> (stitch c1 c2) results prn-terse) ; business as usual
c1b (-> simple-lisp reset (step "(bonjour)(hel")) ; an updated 1st chunk
_ (-> (stitch c1b c2) results prn-terse)]
nil)
;;> ((:main (:expr "()") (:expr "(" (:expr (:symbol "hello")) ")")))
;;> ((:main (:expr "(" (:expr (:symbol "bonjour")) ")") (:expr "(" (:expr (:symbol "hello")) ")")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment