This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-05-24
Channels
- # aleph (5)
- # announcements (18)
- # babashka (3)
- # babashka-sci-dev (56)
- # beginners (56)
- # biff (5)
- # calva (27)
- # cider (20)
- # clj-commons (2)
- # clj-kondo (17)
- # cljsrn (18)
- # clojure (41)
- # clojure-europe (24)
- # clojure-nl (1)
- # clojure-serbia (1)
- # clojure-uk (15)
- # clojured (1)
- # clojurescript (40)
- # cursive (39)
- # datahike (2)
- # datalevin (4)
- # datascript (5)
- # emacs (23)
- # events (2)
- # figwheel-main (3)
- # inf-clojure (1)
- # instaparse (23)
- # introduce-yourself (3)
- # jobs (3)
- # jobs-discuss (13)
- # joyride (1)
- # juxt (10)
- # malli (21)
- # nbb (29)
- # off-topic (18)
- # pathom (29)
- # polylith (11)
- # project-updates (1)
- # proletarian (1)
- # rdf (2)
- # re-frame (4)
- # reitit (2)
- # releases (2)
- # remote-jobs (1)
- # shadow-cljs (52)
- # tools-deps (57)
- # xtdb (32)
I'm trying to have mutual recursion with regex schemas and failing pitifully. Any tips?
In this example:
(defn char-range
[from+to]
(let [from (long (first from+to))
to (long (second from+to))]
(m/-simple-schema
{:type ::char-range
:pred (fn [x] (<= from (long x) to))})))
(defn char-seq
[cs]
(into [:cat] (mapv (fn [c] [:= c]) cs)))
(m/parse
(m/schema
[:schema
{:registry
{::digit (char-range "09")
::lower-case (char-range "az")
::upper-case (char-range "AZ")
::letter [:alt ::lower-case ::upper-case]
::number [:+ ::digit]
::var [:cat ::upper-case [:* ::lower-case]]
::boolean [:altn [:true (char-seq "true")] [:false (char-seq "false")]]
::atom [:cat ::lower-case [:* ::letter]]
::term [:altn
[:equality [:schema [:ref ::equality]]]
[:atom ::atom]
[:var ::var]
[:number ::number]
[:boolean ::boolean]
#_[:structure ::structure]
#_[:list ::list]
#_[:string ::string]]
::equality [:cat ::var (char-seq " = ") ::term]
}}
::equality])
(seq "X = Y"))
::equality
succeeds but ::term
doesn'tI'm not sure why but I also find out that you can't have :ref
in seqexp. Is that your problem ?
for some reason you also can't wrap the ::term
in ::equality
with [:schema [:ref ,,]]
What doesn't succeed? What do you expect?
I got [[\X []] [\space \= \space] [:var [\Y []]]]
ho ok
I think it's because in ::term
you altn
only the \space
and not the whole input seq. It tries to match \space
and don't find any entry. I'll try to add an entry to check that
(m/parse
(m/schema
[:schema
{:registry
{::digit (char-range "09")
::lower-case (char-range "az")
::upper-case (char-range "AZ")
::letter [:alt ::lower-case ::upper-case]
::number [:+ ::digit]
::var [:cat ::upper-case [:* ::lower-case]]
::boolean [:altn [:true (char-seq "true")] [:false (char-seq "false")]]
::atom [:cat ::lower-case [:* ::letter]]
::term [:* [:altn
[:equality [:schema [:ref ::equality]]]
[:atom ::atom]
[:var ::var]
[:number ::number]
[:boolean ::boolean]
[:space [:cat [:= \space]]]
[:equals [:cat [:= \=]]]
#_[:structure ::structure]
#_[:list ::list]
#_[:string ::string]]]
::equality [:cat ::var (char-seq " = ") ::term]}}
::term])
(seq "X = Y"))
This "works" => [[:var [\X []]] [:space [\space]] [:equals [\=]] [:space [\space]] [:var [\Y []]]]
Well, you changed the semantics of the parser. An "equals" is defined in the bnf as "atom = term"
I know, that's why I put " around works. I was trying to explain the reason why it doesn't work. Btw you can’t do recursive seqexp in malli actually. If you want to exclusively use Malli to parse, you can replace the ref to ::term with a [:* any?] and call the parser again on that. You can also create your own schema but it’s harder I think.
Don't know, not a malli expert. But I think it's due to technical limitation. Malli explicitely prevent it with ::potentially-recursive-seqex
error, though it is theorically possible.
See https://github.com/metosin/malli/blob/85a948afc13262adb2082ede36ee131bd2b6364d/test/malli/core_test.cljc#L1797-L1800
[:schema {:registry {::ints [:cat int? [:ref ::ints]]
is disallowed.
There’s more info here in this discussion: https://github.com/metosin/malli/pull/317