Hi! I have an instaparse parser for ini files (specifically intended for AWS configs). It understands kv pairs in with in section headers, and kv pairs without a section header, but I’m trying to figure out if I can write both in 1 (or at least 2 minimally duplicative) meander expression.
Grammar 🧵
ini = body section*.
section = header (eol body)?.
header = "[" wsp name wsp "]" wsp comment?.
name = #"[\w ]+(?<! )"
body = (kv? wsp comment? eol)* (kv wsp comment?)?
kv = key wsp "=" wsp val.
key = #"[\w ]*(?<! )"
val = #"[\w ]*(?<! )"
comment = #"#.*".
wsp = "(\t| )*".
eol = "(\r|\n|\r\n)".
blank-line = wsp comment? eol.
comment = #"#.*".
wsp = #"( |\t)*".
eol = #"\R".Example parses 🧵
(def no-section
(i/ini-parser "x=1"))
[:ini
[:body
[:kv [:key "x"] [:wsp ""] "=" [:wsp ""] [:val "1"]] [:wsp ""]]]
(def empty-section
(i/ini-parser "[x]"))
[:ini
[:body]
[:section
[:header "[" [:wsp ""] [:name "x"] [:wsp ""] "]" [:wsp ""]]]]
(def empty-section-with-newline
(i/ini-parser "[x]\n"))
[:ini
[:body]
[:section
[:header "[" [:wsp ""] [:name "x"] [:wsp ""] "]" [:wsp ""]]
[:eol "\n"]
[:body]]]
(def one-section-with-one-kv
(i/ini-parser "[xyzzy]\nx = 1"))
[:ini
[:body]
[:section
[:header "[" [:wsp ""] [:name "xyzzy"] [:wsp ""] "]" [:wsp ""]]
[:eol "\n"]
[:body [:kv [:key "x"] [:wsp " "] "=" [:wsp " "] [:val "1"]] [:wsp ""]]]]
(def one-section-with-two-kvs
(i/ini-parser "[xyzzy]\nx = 1\ny = 2"))
[:ini
[:body]
[:section
[:header "[" [:wsp ""] [:name "xyzzy"] [:wsp ""] "]" [:wsp ""]]
[:eol "\n"]
[:body
[:kv [:key "x"] [:wsp " "] "=" [:wsp " "] [:val "1"]]
[:wsp ""]
[:eol "\n"]
[:kv [:key "y"] [:wsp " "] "=" [:wsp " "] [:val "2"]]
[:wsp ""]]]]
(def two-sections
(i/ini-parser "[xyzzy]\nx = 1\n[iddqd]\ny=2"))
[:ini
[:body]
[:section
[:header "[" [:wsp ""] [:name "xyzzy"] [:wsp ""] "]" [:wsp ""]]
[:eol "\n"]
[:body
[:kv [:key "x"] [:wsp " "] "=" [:wsp " "] [:val "1"]]
[:wsp ""]
[:eol "\n"]]]
[:section
[:header "[" [:wsp ""] [:name "iddqd"] [:wsp ""] "]" [:wsp ""]]
[:eol "\n"]
[:body [:kv [:key "y"] [:wsp ""] "=" [:wsp ""] [:val "2"]] [:wsp ""]]]]Meander code I have 🧵
Can you give an example of what you want the output to look like?
Also, sorry for the lag! I’ve had a wacky week.
(defn get-kvs
[ini-parse]
(m/search
ini-parse
[:ini
[:body . _ ...] ;; <= below body rule can occur here too
&
(m/scan
[:section
[:header & (m/scan [:name ?h])]
. _ ...
[:body & (m/scan [:kv [:key ?k] [:wsp _] "=" [:wsp _] [:val ?v]])]
. _ ...])]
[?h ?k ?v]))basically this works great for finding [?header ?key ?value] pairs, and I can find kvs in the section headerless body, but I’m trying to see if I can extract both
I assume the way to write this is recursively
@lvh When I get a free moment I'll take a look at this. 👍