将另一个Clojure程序作为S表达式列表读取
假设磁盘上有一个非常简单的将另一个Clojure程序作为S表达式列表读取,clojure,Clojure,假设磁盘上有一个非常简单的.clj文件,其中包含以下内容: (def a 2) (def b 3) (defn add-two [x y] (+ x y)) (println (add-two a b)) 从单独程序的上下文中,我想将上面的程序作为S表达式列表来阅读,”((def a2)(def b3)…(添加两个ab)) 我想这样做的一个方法是1。使用(io/file file name.clj)上的slurp生成包含文件内容的字符串,2。将该字符串传递给Clojure代码的解析器,然后执行
.clj
文件,其中包含以下内容:
(def a 2)
(def b 3)
(defn add-two [x y] (+ x y))
(println (add-two a b))
从单独程序的上下文中,我想将上面的程序作为S表达式列表来阅读,”((def a2)(def b3)…(添加两个ab))
我想这样做的一个方法是1。使用(io/file file name.clj)
上的slurp
生成包含文件内容的字符串,2。将该字符串传递给Clojure代码的解析器,然后执行3。将解析器生成的序列注入一个列表(即,(插入到“()解析代码)
)
然而,这种方法似乎有点笨拙,而且容易出错有人知道更优雅和/或更惯用的方式来将Clojure文件作为S表达式列表来读取吗?
更新:根据评论部分的反馈,我决定在实际的源文件上使用aphyr尝试我提到的方法,如下所示:
=> (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\n (:gen-class)\n (:require [clj-antlr.core :as antlr]))\n\n(def foo 42)\n\n(defn parse-program\n \"uses antlr grammar to \"\n [program]\n ((antlr/parser \"src/grammars/Clojure.g4\") program))\n\n\n(defn -main\n \"I don't do a whole lot ... yet.\"\n [& args]\n (println \"tlc is tcl\"))\n"}
nil
是否有人知道如何将此输出转换为最初预期的S表达式列表?也就是说,如何从使用clj antlr解析的结果中压缩有效的Clojure代码/数据?您需要类似的东西吗
(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)))
你需要这样的东西吗
(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)))
请检查是否还没有回答您的问题。@PiotrekBzdyl感谢您指出前面的问题。我自己永远也不会发现这一点。当我有时间的时候,我会根据潜在客户提交答案,但是你可以自己提交。由于前面的问题似乎有点悬而未决,我暂时不提我的问题。这种方法对我来说似乎非常简单。为什么你认为它“笨拙且容易出错”?@OlegTheCat我认为信任内核之外的解析器处理任意代码似乎是乐观的。如果你觉得不一样,我会很乐意分享我的代码,一旦我考虑表上的选项。另外,如果您知道一个值得信任的解析器,请共享一个。@PiotrekBzdyl上一篇文章中接受的答案似乎没有按预期工作:例如,在(slurp“sample.clj”)的结果上调用定义的函数,安全地读取字符串,似乎只返回代码的第一行(def a 2)。请,检查是否还没有回答您的问题。@PiotrekBzdyl感谢您指出前面的问题。我自己永远也不会发现这一点。当我有时间的时候,我会根据潜在客户提交答案,但是你可以自己提交。由于前面的问题似乎有点悬而未决,我暂时不提我的问题。这种方法对我来说似乎非常简单。为什么你认为它“笨拙且容易出错”?@OlegTheCat我认为信任内核之外的解析器处理任意代码似乎是乐观的。如果你觉得不一样,我会很乐意分享我的代码,一旦我考虑表上的选项。另外,如果您知道一个值得信任的解析器,请共享一个。@PiotrekBzdyl上一篇文章中接受的答案似乎没有按预期工作:例如,在(slurp“sample.clj”)的结果上调用已定义的函数read string safe似乎只返回代码的第一行(def a 2)。