This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-06-13
Channels
- # babashka (7)
- # babashka-sci-dev (3)
- # beginners (29)
- # biff (16)
- # calva (2)
- # clojars (1)
- # clojure (50)
- # clojure-austin (5)
- # clojure-europe (29)
- # clojure-france (8)
- # clojure-nl (3)
- # clojure-uk (3)
- # clojured (10)
- # clojurescript (19)
- # code-reviews (3)
- # core-async (22)
- # cursive (5)
- # data-science (11)
- # datalevin (1)
- # datomic (10)
- # eastwood (4)
- # helix (4)
- # introduce-yourself (2)
- # jobs (1)
- # jobs-discuss (1)
- # joyride (6)
- # leiningen (4)
- # london-clojurians (2)
- # lsp (82)
- # malli (7)
- # meander (12)
- # minecraft (3)
- # nbb (14)
- # off-topic (52)
- # podcasts-discuss (3)
- # portal (3)
- # re-frame (32)
- # reagent (9)
- # releases (2)
- # shadow-cljs (95)
- # tools-deps (14)
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.
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".
(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 ""]]]]
(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]))