【发布时间】:2016-10-12 23:28:36
【问题描述】:
假设我在磁盘上有一个非常简单的.clj 文件,其内容如下:
(def a 2)
(def b 3)
(defn add-two [x y] (+ x y))
(println (add-two a b))
从单独程序的上下文来看,我想将上述程序作为 S-Expressions 的列表阅读,'((def a 2) (def b 3) ... (add-two a b)))。
我想这样做的一种方法涉及 1. 在 (io/file file-name.clj) 上使用 slurp 来生成包含文件内容的字符串,2. 将该字符串传递给 Clojure 代码的解析器,以及 3. 注入生成的序列由解析器发送到一个列表(即(into '() parsed-code))。
但是,这种方法似乎有点笨拙且容易出错。 有人知道将 Clojure 文件作为 S-Expressions 列表读取的更优雅和/或惯用的方法吗?
更新:根据 cmets 部分的反馈,我决定尝试使用 aphyr 的 clj-antlr 在实际源文件中提到的方法,如下所示:
=> (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-Expressions 列表?也就是说,如何从使用 clj 解析的结果中压缩有效的 Clojure 代码/数据-antlr?
【问题讨论】:
-
请检查stackoverflow.com/a/24576026/597473 是否还没有回答您的问题。
-
@PiotrekBzdyl 感谢您指出之前的问题。我自己永远也不会发现。当我有时间时,我会根据线索提交一个答案,但你可以自己做。由于之前的问题似乎有点悬而未决,所以我将暂时留下我的问题。
-
这种方法对我来说似乎很简单。为什么你认为它“笨拙且容易出错”?
-
@OlegTheCat 我想在任意代码上信任来自核心外部的解析器似乎是乐观的。如果您不这么认为,一旦我考虑了桌面上的选项,我将很乐意分享我的代码。另外,如果你知道的话,请分享一个值得信赖的解析器。
-
@PiotrekBzdyl 上一篇文章中接受的答案似乎没有按预期工作:例如,在 (slurp "sample.clj 的结果上调用定义的函数 read-string-safely ") 似乎只返回代码的第一行,(def a 2)。
标签: clojure