Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (require ['clojure.string :as 'string])
- (def state-machine
- [
- (fn [c] (case c
- (\a \b) (get state-machine 1)
- "Error 1"))
- (fn [c] (case c
- (\b) (get state-machine 1)
- (\c) (get state-machine 2)
- "Error 2"))
- (fn [c] (case c
- (\d) (get state-machine 3)
- "Error 3") )
- (fn [c] (case c
- :end "Win"
- "Error 4"))
- ])
- (defn state-machine-driver [v machine]
- (loop [fun (get machine 0) st v]
- (println (first st))
- (let [ans (fun (first st))]
- (cond (empty? st) (fun :end)
- (string? ans) ans
- :else (recur ans (rest st))))))
- ;; I think this needs to be a macro because the case statement can only take compile-time
- ;; constants and I think I need a macro to write them in
- ;; Of course, I'm a noob. I could be wrong
- (defmacro make-sm-func [idx or-list self-list star-list]
- (if (empty? star-list)
- `#(case %
- ~or-list (get ~state-machine (inc ~idx)) ;; (a|b)c*d, this would be at, say, c* and us choosing (\d) to go on
- ~self-list (get ~state-machine ~idx) ;; (a|b)c*d, this is where we pick more c instead of going to (\d)
- "Error")
- `#(case %
- ~star-list (get ~state-machine (inc ~idx)) ;;In (a|b)c*d, this is (\c) going on to the '(\c)' state
- ~or-list (get ~state-machine (+ 2 ~idx)) ;; In (a|b)c*d, this will be (\a \b) for (a|b)
- ~self-list (get ~state-machine ~idx) ;; We picked a (\c) and this is the option for more (\c)
- "Error")))
- (defn get-parenth [r depth prefix]
- (let [fc (first r)]
- (println fc r depth prefix)
- (case fc
- nil :error
- \( (recur (rest r) (inc depth) (conj prefix fc))
- \) (if (= depth 0)
- (conj prefix \) )
- (recur (rest r) (dec depth) (conj prefix fc)))
- (recur (rest r) depth (conj prefix fc)))))
- (defn get-command [re]
- ;; Obviously this is really ugly
- (if (empty? re)
- [:empty []]
- (if (= \( (first re))
- (let [a (let [exp (get-parenth (rest re) 0 [\(])]
- (if (keyword? exp)
- :error
- (subvec exp 1 (- (count exp) 1))))
- b (nth re (+ 2 (count a)))
- re-tail (drop (+ (count a) 3) re)]
- (cond (= \* b) [:star a re-tail]
- (= \| b) [:or a re-tail]
- :else [:concat a re-tail]))
- (let [a (vector (first re))
- b (nth re 1)
- re-tail (rest re)]
- (cond (= \* b) [:star a re-tail]
- (= \| b) [:or a re-tail]
- :else [:concat a re-tail])))))
- (defn make-regex [re]
- (let [comm (get-command re)
- fc (first comm)]
- (cond (empty? fc) (make-terminal fc)
- (parenth? fc) (make-regex (contents fc))
- (starred? fc) (make-none+ fc)
- (concat? fc) (make-concat fc)
- (or? fc) (make-or fc)
- :else "Unknown error")))
- ;; (...)
- ;; a* highest priority
- ;; ab medium priority
- ;; a|b lowest priority
- ;;
Add Comment
Please, Sign In to add comment