Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns lec.parser
- (:require [clojure.string :as cs]))
- (def valid-chars (set "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"))
- (def operators (set "&|>=+"))
- (def char->operator {\& :and, \| :or, \> :implies, \= :iff, \+ :xor})
- (defn- section
- "Must be used with a string that starts with '(', and will return
- a vector of what is inside of that clause, and whats after.
- (section '(a & (b | c)) > d' ) => ['a & (b | c)', ' > d']"
- [xs]
- (-> (fn [[n acc xs]]
- (case (first xs)
- \( [(inc n) (conj acc (first xs)) (rest xs)]
- \) (if (= n 1) [(dec n) acc (rest xs)]
- [(dec n) (conj acc (first xs)) (rest xs)])
- [n (conj acc (first xs)) (rest xs)]))
- (iterate [1 [] (rest xs)])
- (->> (drop-while (comp not zero? first))
- (first)
- (rest))))
- (defn parse
- "For parsing logic formulas like: !(a & b) > ((c + b) | (a = d))
- (Input mus not have spaces) to something like:
- [[:not ['a' :and 'b']] :implies [['c' :xor 'b'] :or ['a' :iff 'd']]]"
- [xs]
- (cond
- (not (some operators xs)) ; Just a literal
- (if (= \! (first xs))
- [:not (apply str (rest xs))]
- (apply str xs))
- (= (take 2 xs) '(\! \()) ; negation of a nested expression
- (let [[a b] (section (rest xs))]
- (if (empty? (filter (partial not= \)) b))
- [:not (parse a)]
- [[:not (parse a)] (char->operator (first b)) (parse (rest b))]))
- (= \( (first xs)) ; nested expression
- (let [[a b] (section xs)]
- (if (empty? (filter (partial not= \)) b))
- (parse a)
- [(parse a) (char->operator (first b)) (parse (rest b))]))
- :else
- (let [[a b] (split-with (comp not operators) xs)]
- [(parse a) (char->operator (first b)) (parse (rest b))])))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement