As an example of how to use intaparse to parse arithmetic expressions 
(among other things), you might be interested in this 
notebook 
https://mybinder.org/v2/gh/bhugueney/binder-test/master?filepath=Clojure.ipynb

On Saturday, August 18, 2018 at 2:02:25 PM UTC+2, ckry...@gmail.com wrote:
>
> Hi, 
> I am ne to Clojure, and trying to make arithmetic simplifier
> so it can take string in for `1x + 3y -4x + 8 -1y` and return "-3x + 2y +8"
> Currently, I am stuck with a `make-ast` function, where load-string loads.
> it can't load string with variables. 
>
> (def precedence '{* 0, / 0
>                   + 1, - 1})
>
> (def ops {'* *
>           '+ +
>           '- -
>           '/ /})
>
> (defn order-ops
>   "((A x B) y C) or (A x (B y C)) depending on precedence of x and y"
>   [[A x B y C & more]]
>   (let [ret (if (<=  (precedence x)
>                      (precedence y))
>               (list (list A x B) y C)
>               (list A x (list B y C)))]
>     (if more
>       (recur (concat ret more))
>       ret)))
>
> (defn add-parens
>   "Tree walk to add parens.  All lists are length 3 afterwards."
>   [s]
>   (clojure.walk/postwalk
>    #(if (seq? %)
>       (let [c (count %)]
>         (cond (even? c) (throw (Exception. "Must be an odd number of forms"))
>               (= c 1) (first %)
>               (= c 3) %
>               (>= c 5) (order-ops %)))
>       %)
>    s))
>
> (defn make-ast
>   "Parse a string into a list of numbers, ops, and lists"
>   [s]
>   (-> (format "'(%s)" s)
>       (.replaceAll , "([*+-/])" " $1 ")
>       load-string
>       add-parens))
>
>
> (defn simplify-seq
>   "Simplify sequence of vars"
>   [s]
>   (println s)
>   )
>
> (def eval-ast
>   (partial clojure.walk/postwalk
>            #(if (seq? %)
>               ;(simplify-seq %)
>               (let [[a o b] %]
>                 ((ops o) a b))
>               %)))
>
> (defn evaluate [s]
>   "Parse and evaluate an infix arithmetic expression"
>   ;(eval-ast (make-ast s))
>   (def ast (make-ast s))
>   (println ">>> DEBUG AST:" ast)
>   (let [res (eval-ast ast)]
>     (println ">>> DEBUG res:" res )))
>
>
> (defn -main
>   "Read from STDIN"
>   [& args]
>   ;
>   ;(loop [i 0]
>   ;  (when (< i n)
>   ;    (def a (read-line))
>   ;    (def new (split a #"\s+"))
>   ;    (println ( + (Integer/parseInt (get new 0)) (Integer/parseInt (get new 
> 1)) ))
>   ;    (recur (inc i))
>   ;    ))
>
>   (loop [input (read-line)]
>     (if (= ":done" input)
>       (println (evaluate input))
>       (recur (read-line)))))
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to