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.