java - 在 Java 对象树上创建的 Clojure zipper 可以在 zip-filter 中工作吗?

标签 java interop clojure antlr

我目前正在将 ANTLR 和 Clojure 粘合在一起,试图在 ANTLR 返回的抽象语法树上创建一个 Clojure zipper 。

AST 是一组非常具有 Java 风格的对象,使用 CommonTree表示层次结构的对象。

我在 CommonTree 上做了一个 zipper ,如下所示:

(defn branch? [tn] (not (zero? (.getChildCount tn))))
(defn children [tn] (.getChildren tn))
(defn make [tn children] (doto (CommonTree. tn)
                           (.addChildren children)))

(defn zip-parse [f] (z/zipper branch? children make (parse f)))

(我不能 100% 确定以这种方式制作 CommonTree 节点是否可行。我还没有深入到验证它的程度......)

我这样使用这些函数:

(def zip-ast (parse testfile))

到目前为止,还不错。这确实有效。我可以使用“向下”、“向右”、“向左”和“向上”功能进行导航。当我尝试使用 zip-filter 库定位特定标记时出现问题:

(defn token [loc] (-> loc z/node .getToken .getText))

(defn token= [tokenname]
  (fn [loc]
    (filter #(and (z/branch? %) (= tokenname (token %)))
            (if (zf/auto? loc)
              (zf/children-auto loc)
              (list (zf/auto true loc))))))

(defn java->
  [loc & preds]
  (zf/mapcat-chain loc preds #(cond (string? %) (token= %))))

这是从 Chouser 的漂亮 xml-> 函数公然复制的。不幸的是,它根本行不通。在 zip-filter 内部,函数“auto”在对象中添加或删除元数据。除了,普通的旧 Java 对象不能有元数据

我是不是找错了树?或者(更有可能),我对 zip-filter 的理解不够好,无法复制它吗?

最佳答案

Zippers 存储 branch?、children 和 make 函数作为 loc 上的 meta 包装节点,似乎 auto 正在向对象周围的 loc 包装器( vector )添加或删除元数据,而不是对象本身。所以,我认为这不是问题。

您能否详细解释一下什么是“行不通”?

branch? 函数是一个看起来很可疑的地方(这让我对自定义 zipper 感到困惑)。请注意,您在 token= 中的第一个 and 条件会检查 branch? - 如果 token 没有子项,则它不会在 中匹配token=,这可能会令人惊讶。分支?真正说明一个节点是否可能有子节点,所以有时你想在那里返回 true,即使它实际上没有子节点。除此之外,我没有看到任何明显的东西。

注意:在java->中,由于只有一个选项,可以简化匿名函数。如果它始终是一个字符串,那么您可以只用 token= 替换整个匿名函数。或者,如果您需要处理非字符串大小写并返回 nil,您可能需要 (when (string? %) (token= %))

实际上,我过去曾沿着不同的路线解决过几乎相同的问题。不确定这是否有帮助,但以防万一...

我构建了一个 Antlr 语法,它生成了我想在 Clojure 中作为树进行遍历和修改的输出。我最终想到的解决方案是:

  • Antlr 语法 ->
  • Antlr 树语法(按摩,语言不可知论)->
  • 要生成的 Antlr 字符串模板(特定于 Clojure)->
  • 作为字符串的 Clojure 数据结构 ->
  • 将 Clojure 数据结构读入嵌套树(为我们记录,但可以是任何内容)

这样做的一个好处是 Antlr Java 代码不直接依赖于 Clojure 代码(仅以传入的字符串的格式),这使得 Clojure 代码仅依赖于生成的 Java 代码。这在编译项目时稍微简化了依赖结构(我想你也已经做到了)。另一个好处是文法和树文法与语言无关,因此您可以从相同的文法创建 Clojure 和/或 Java 和/或其他目标(我实际上并没有这样做)。

关于java - 在 Java 对象树上创建的 Clojure zipper 可以在 zip-filter 中工作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4911345/

相关文章:

.net - .NET 垃圾收集器的 stop-the-world 效果是否会停止或延迟非托管线程和计时器回调的执行?

clojure - 当谓词为 false 时需要花一段时间来包含最后一项

clojure - core.async go block 是否自行停放,或者是否存在 'scheduler' ?

java - 我正在 selenium 自动化中创建页面对象模型框架,并且面临 java 空指针异常

java - 无法通过 servlet 连接 mysql;访问被拒绝

java - 从 Excel 文件读取空单元格时出现异常

interop - FHIR 互操作平台选择

java - 混合 Kotlin + Java 与 Maven, Unresolved reference

clojure - 如何合并 clojure 中向量集合内的 HashMap ?

java - 使用 Integer.parseInt 将 String 转换为 Int 不起作用