I'm experimenting with Clojure and Instaparse. I have created a small toy language, and I'm getting stuck at how to properly treat the resulting tree. This is what i get:
[:ClassDescription
[:ClassName "Test"]
[:Properties
[:Property
[:PropertyName "ID"]
[:PropertyType "Int"]]
[:Property
[:PropertyName "Name"]
[:PropertyType "string"]]]]
Now, as an example I would like to extract all PropertyTypes. I have two main ways and I'd like a solution for both.
- By specifying a path; something like
[:ClassDescription :Properties :Property :PropertyType] - By extracting all
:PropertyTypeelements, regardless of depth.
For A., my first idea was to convert some parts of it to maps via insta/transform and then use get-in, but then I get a really clunky solution involving nested loops and get-in.
I can also use nth, and drill my self into the structure, but that seems cumbersome, and will break easily if I add another layer.
My other idea was a recursive solution where I treat every element the same way and loop through it and check for all matches.
For B. my only solution so far is a recursive function that just drills through everything and tries to match the first element.
I believe that these "handwritten" functions could be avoided by some clever combination of insta/transform, map, filter, reduce, etc. Can it?
For getting elements out of the parsed data, you could use
tree-seqto iterate all and pick what you need. E.g.:Yet you might be better off to shape your data already in the first place by using
<...>in your parser and/or by turning them into something more mapish, what would be easier to access via transformation. E.g. turn the:Propertiesinto a list of maps and turn the whole thing into a map: