Reading another Clojure program as a list of S-Expressions
假设我的磁盘上有一个非常简单的
1 2 3 4 | (def a 2) (def b 3) (defn add-two [x y] (+ x y)) (println (add-two a b)) |
从单独的程序的上下文来看,我想将以上程序作为S-Expressions
我想一种解决方法包括1.在
但是,这种方法似乎笨拙且容易出错。有谁知道一种更优雅和/或更惯用的方式将Clojure文件读取为S表达式列表吗?
更新:根据评论部分的反馈,我决定尝试使用aphyr的clj-antlr在实际源文件中提到的方法,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | => (def file-as-string (slurp (clojure.java.io/file"src/tcl/core.clj"))) => tcl.core=> (pprint (antlr/parser"src/grammars/Clojure.g4" file-as-string)) {:parser {:local #object[java.lang.ThreadLocal 0x5bfcab6"java.lang.ThreadLocal@5bfcab6"], :grammar #object[org.antlr.v4.tool.Grammar 0x5b8cfcb9"org.antlr.v4.tool.Grammar@5b8cfcb9"]}, :opts "(ns tcl.core\ (:gen-class)\ (:require [clj-antlr.core :as antlr]))\ \ (def foo 42)\ \ (defn parse-program\ \"uses antlr grammar to \"\ [program]\ ((antlr/parser \"src/grammars/Clojure.g4\") program))\ \ \ (defn -main\ \"I don't do a whole lot ... yet.\"\ [& args]\ (println \"tlc is tcl\"))\ "} nil |
有谁知道如何将此输出转换为原本打算的S表达式列表?也就是说,如何用clj-antlr的解析结果来压缩有效的Clojure代码/数据?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | (import '[java.io PushbackReader]) (require '[clojure.java.io :as io]) (require '[clojure.edn :as edn]) ;; adapted from: http://stackoverflow.com/a/24922859/6264 (defn read-forms [file] (let [rdr (-> file io/file io/reader PushbackReader.) sentinel (Object.)] (loop [forms []] (let [form (edn/read {:eof sentinel} rdr)] (if (= sentinel form) forms (recur (conj forms form))))))) (comment (spit"/tmp/example.clj" "(def a 2) (def b 3) (defn add-two [x y] (+ x y)) (println (add-two a b))") (read-forms"/tmp/example.clj") ;;=> [(def a 2) (def b 3) (defn add-two [x y] (+ x y)) (println (add-two a b))] ) |
你需要这样的东西吗?
1 2 3 4 5 6 7 8 | (let [exprs (slurp"to_read.clj")] ;; adding braces to form a proper list (-> (str"(" (str exprs")")) ;; read-string is potentially harmful, since it evals the string ;; there exist non-evaluating readers for clojure but I don't know ;; which one are good (read-string) (prn))) |