clojure - 如何在 Clojure 中使用尾递归遍历 AST

标签 clojure functional-programming antlr antlr3 tail-recursion

我有一个 ANTLR3 AST,我需要使用后序深度优先遍历来遍历它,我大致实现了以下 Clojure:

(defn walk-tree [^CommonTree node]
  (if (zero? (.getChildCount node))
    (read-string (.getText node))
    (execute-node
      (map-action node)
      (map walk-tree (.getChildren node)))))))

我想使用 loop...recur 将其转换为尾递归,但我一直无法弄清楚如何有效地使用显式堆栈来执行此操作,因为我需要一个后序遍历。

最佳答案

您可以使用 tree-seq 生成深度优先遍历的惰性序列,而不是生成遍历树并访问每个节点的尾递归解决方案。函数,然后从遍历中的每个对象中获取文本。惰性序列永远不会炸毁堆栈,因为它们存储了在堆中生成序列中的下一项所需的所有状态。它们经常被用来代替这样的递归解决方案,其中 looprecur更难。

我不知道你的树是什么样子,尽管典型的答案看起来像这样。您需要使用“有 child ”“ child 列表”功能

(map #(.getText %) ;; Has Children?      List of Children    Input Tree
     (tree-seq #(> (.getChildCount #) 0) #(.getChildren %) my-antlr-ast))

如果 tree-seq 不适合您的需要,还有其他方法可以从树中生成惰性序列。接下来看 zipper 库。

关于clojure - 如何在 Clojure 中使用尾递归遍历 AST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12371986/

相关文章:

java - 以下 JAVA 谓词的语法

java - 如何显示 ANTLR 树 GUI

mysql - Clojure JDBC : MySQL errors when creating table with composite unique constraint

macros - Clojure 的宏——定义一个名称由参数组成的绑定(bind)

testing - 你怎么能 "parameterize"Clojure Contrib 的测试是?

javascript - 按排序顺序将数组数组减少为数组

haskell - 如何定义基于总和类型的子类型过滤列表的 lambda 函数?

javascript - 简化分页页面列表的生成

parsing - 有多少种方法来构建解析器?

clojure - 如何获取具有统一命名空间键的映射的命名空间?