Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (require 'clojure.set)
- (require ['clojure.string :as 'string])
- (declare 'lex-table)
- (declare 'parse-table)
- (declare 'parse-single-token)
- ;; Parser tables to load
- ;;(load-file "clojure/infix2-table.clj")
- (load-file "english.clj")
- (defmacro dbg[x]
- `(let [x# ~x]
- (println "dbg:" '~x "=" x#)
- x#))
- (defmacro applyp [p & x]
- ;; apply a predicate macro to a list, like 'and' or 'or',
- ;; because I don't know the proper way to do it
- `(eval (list* '~p ~@x)))
- (defn ntrue? [n & x]
- ;; Count the number of truths
- (cond (<= n 0) true
- (empty? x) false
- :else (apply ntrue?
- (if (first x)
- (- n 1)
- n)
- (rest x))))
- (defn opify-vec [v]
- ;; match up lexed bits with the actual op names
- (some #(when (first %) %)
- (map-indexed #(vector %2 (nth (keys lex-table) %1)) (rest v))))
- (defn replace-word [w]
- (if (= :word (second w))
- (vector (first w) (check-trie (first w) dict))
- w))
- (defn lexify [s l-table]
- ;; Build a vector of lexed tokens
- (let [pat (re-pattern (str "(" (string/join ")|(" (vals l-table)) ")"))]
- (map replace-word
- (map opify-vec (re-seq pat s)))))
- (defn is-compound? [e p-table]
- ;; Is the token a parser token?
- (contains? p-table e))
- (defn is-simple? [e p-table]
- ;; Is the token a lexer token?
- (not (is-compound? e p-table)))
- (defn parse-token-vector [l-vec tok-entry p-table]
- ;; Take the remainder of a sentence a vector of tokens and return the parsings
- ;; (dbg l-vec)
- (let [tok-vec (first tok-entry)
- tok-fun (second tok-entry)
- ans (reduce
- (fn [old-res new-tok]
- (if (old-res :parse?)
- (merge-with #(concat %2 %1)
- (parse-single-token (get old-res :rest) [new-tok] p-table)
- {:value (old-res :value)})
- {:parse? false :exit :token}))
- {:parse? true :rest l-vec :value []}
- tok-vec)]
- (if (get ans :parse?)
- (assoc ans :value (vector (tok-fun (get ans :value))))
- ans)))
- (defn parse-single-token [l-vec token-vec p-table]
- ;; Take the remainder of a sentence and a vector with a token in it, return the parsings
- ;;(dbg l-vec)
- (let [cur-tok (first token-vec)]
- (cond (and (empty? l-vec) (nil? cur-tok)) {:parse? true :rest [] :exit :finished}
- (and (empty? l-vec) (not (nil? cur-tok))) {:parse? false :exit :run-out}
- (and (not (empty? l-vec)) (nil? cur-tok)) {:parse? true :rest l-vec}
- (is-simple? cur-tok p-table) (if (= cur-tok (second (first l-vec)))
- {:parse? true :rest (rest l-vec) :value (vector (ffirst l-vec))}
- {:parse? false :exit :wrong-simpleton})
- :else
- (let [init-p (map #(parse-token-vector l-vec % p-table)
- (get p-table cur-tok))
- parsings (filter #(get % :parse?) init-p)
- fin (filter #(empty? (get % :rest)) parsings)]
- (cond (zero? (count parsings)) {:parse? false :exit :no-compounds}
- (not (empty? fin)) (first fin)
- :else (first parsings))))))
- (defn parse [s]
- (let [ans (parse-single-token (lexify s lex-table) (vector (first parse-table)) (second parse-table))]
- (if (and (ans :parse?)
- (zero? (count (ans :rest))))
- (first (get ans :value))
- nil)))
Add Comment
Please, Sign In to add comment