Looking for library to annotate structures with grammar descriptions

176 views
Skip to first unread message

Brian Marick

unread,
Jun 25, 2015, 12:35:54 PM6/25/15
to clojure
Suppose we have a structure like this:

[ :a [:a :b :c] [:a [:b1 :b2] :c ] ]

That is a *required* list. It consists of keywords and *paths* (nested
vector like [:a :b :c] above). A path consists of keywords and
*alternates* (a twice-nested vector like [:b1 :b2]) above.

It's easy to descend this by hand and keep track of which "type" of
vector you're dealing with. However, this sort of thing comes up enough
that it would be convenient if there were a function that takes a
grammar and a structure and returns that structure annotated (metadata?)
with type information. Coupled with Specter
https://github.com/nathanmarz/specter, that would make a good number of
data transformations easy-peasy.

Is there such a library? Or a library I can build on? A quick scan shows
a lot of parsers for dealing with strings, but we've already got one of
those: it's called `read`.

@marick

Frank Castellucci

unread,
Jun 26, 2015, 6:56:26 AM6/26/15
to clo...@googlegroups.com
Have you looked at:

clojure.walk ?
clojure.zip ?

namespaces?

You could use either to traverse and set meta data.

There are also 'zipper' predicate libraries that do similar things as 'specter'

Aaron Cohen

unread,
Jun 26, 2015, 1:24:23 PM6/26/15
to clo...@googlegroups.com
I took a swing at this using prismatic schema:

(ns schema-test.core
  (:require [schema.core :as s]
            [schema.utils :as utils]
            [schema.coerce :as coerce])
  (:import schema.core.NamedSchema))

(def Alternate (s/named [s/Keyword] "alternate"))

(def Path (s/named [(s/either s/Keyword Alternate)] "path"))

(def T [(s/either s/Keyword Path)])


(def example [ :a   [:a :b :c]    [:a  [:b1 :b2] :c ] ] )

(defn annotater [schema]
  (s/start-walker
   (fn [s]
     (let [walk (s/walker s)]
       (fn [x]
         (if (and (instance? clojure.lang.IObj x) (instance? schema.core.NamedSchema s))
           (with-meta (walk x) {:schema (.name s)}) 
           (walk x)))))
   schema))

(defn annotate [schema data] ((annotater schema) data))

(def r (annotate T example))

(map meta r) ; => (nil {:schema "path"} {:schema "path"})

(meta (nth (nth r 2) 1)) ; => {:schema "alternate"}




@marick

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Brian Marick

unread,
Jul 7, 2015, 7:02:42 PM7/7/15
to clo...@googlegroups.com


Aaron Cohen wrote:
> Have you looked at:
>
> clojure.walk ?
> clojure.zip ?

Yes - I use zippers heavily in midje. Futzing with metadata is awkward,
so I was hoping for something more specialized.

(Sorry for the delayed reply.)
Reply all
Reply to author
Forward
0 new messages