This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-10
Channels
- # beginners (15)
- # boot (15)
- # cider (6)
- # cljs-dev (231)
- # cljsjs (1)
- # cljsrn (26)
- # clojure (147)
- # clojure-argentina (1)
- # clojure-dev (8)
- # clojure-germany (1)
- # clojure-italy (26)
- # clojure-russia (2)
- # clojure-spec (83)
- # clojure-uk (154)
- # clojurescript (123)
- # conf-proposals (3)
- # core-async (5)
- # cursive (26)
- # datascript (21)
- # datomic (120)
- # emacs (2)
- # graphql (9)
- # hoplon (195)
- # instaparse (16)
- # jobs-discuss (1)
- # leiningen (8)
- # luminus (8)
- # lumo (7)
- # off-topic (17)
- # om (7)
- # om-next (3)
- # parinfer (121)
- # pedestal (5)
- # planck (13)
- # re-frame (11)
- # reagent (21)
- # ring-swagger (2)
- # spacemacs (28)
- # uncomplicate (3)
- # unrepl (7)
- # untangled (34)
- # vim (5)
Hi! In Instaparse, how do I specify operator precedence... I tried ordered choice, but it doesn't do what I want. Simple example:
(def tp (insta/parser "
s = expression
<expression> = binop / integer
integer = #'[0-9]+'
<binop> = times / plus
times = expression <'*'> expression
plus = expression <'+'> expression"
:auto-whitespace whitespace))
parser> (tp "5 + 3 * 7")
[:s [:times [:plus [:integer "5"] [:integer "3"]] [:integer "7"]]]
I have seen solutions that distinguish between add-expression and mul-expression, but that doesn't scale very well for more operatorsOrdered choice only works when considering parses available at a given position, not when ranking this parse here over another parse over there.
So in your example, your binop / integer
was making it try 5 + 3
before 5
I don't think ordered choice is the best tool for "order of operations"... I'll send you another example in a sec
@mrchance check out the arithmetic expr parser in https://github.com/engelberg/instaparse#transforming-the-tree
notice how no ordered choice is necessary, because the grammar is structured so that the order of operations follows naturally
hm, ok, but my impression is that would get unwieldy when there is more operators. I'll give it a try though, I don't have that many ๐
perhaps. not sure.
Hereโs a potentially more elegant way of expressing it (not sure if this actually works):
expr = add-sub
add-sub = mul-div (('+' | '-') mul-div)*
mul-div = term (('*' | '/') term)*
term = number | <'('> add-sub <')'>
@mrchance no, it would end up as [:expr [:add-sub [:mul-div "1" "*" "2"]]]