まず第一に、信頼されていないデータ ソースから直接 clojure コードを読み取ってはいけません。代わりに、EDN または別のシリアル化形式を使用する必要があります。
そうは言っても、Clojure 1.5以降、文字列を評価せずに安全に読み取る方法があります。read-string を使用する前に、 read-eval var を false にバインドする必要があります。Clojure 1.4 以前では、Java コンストラクターの呼び出しによって副作用が発生する可能性がありました。これらの問題はその後修正されました。
コード例を次に示します。
(defn read-string-safely [s]
(binding [*read-eval* false]
(read-string s)))
(read-string-safely "#=(eval (def x 3))")
=> RuntimeException EvalReader not allowed when *read-eval* is false. clojure.lang.Util.runtimeException (Util.java:219)
(read-string-safely "(def x 3)")
=> (def x 3)
(read-string-safely "#java.io.FileWriter[\"precious-file.txt\"]")
=> RuntimeException Record construction syntax can only be used when *read-eval* == true clojure.lang.Util.runtimeException (Util.java:219)
リーダーマクロについて
ディスパッチ マクロ (#) とタグ付きリテラルは、読み取り時に呼び出されます。その時点までにこれらの構成はすべて処理されているため、Clojure データにはそれらの表現はありません。私の知る限り、Clojure コードの構文ツリーを生成する方法はありません。
その情報を保持するには、外部パーサーを使用する必要があります。独自のカスタム パーサーを作成するか、Instaparse や ANTLR などのパーサー ジェネレーターを使用できます。これらのライブラリのいずれかの完全な Clojure 文法を見つけるのは難しいかもしれませんが、EDN 文法の 1 つを拡張して、追加の Clojure フォームを含めることができます。簡単なグーグルでClojure構文のANTLR文法が明らかになりました。必要に応じて欠落している構造をサポートするように変更できます。
ソース コード自体に関する情報を保持する必要がある Clojure ツール用に作成されたライブラリであるSjacketもあります。あなたがやろうとしていることにはぴったりのようですが、個人的には経験がありません。テストから判断すると、パーサーでリーダー マクロがサポートされています。