我目前正在将ANTLR和Clojure结合起来,尝试创建一个Clojure拉链,经过ANTLR返回的抽象语法树。
AST是一套非常Java风格的对象,使用CommonTree对象表示层次结构。
我按照以下方式在CommonTree上创建了拉链:
到目前为止,一切都很顺利。这确实有效。我可以使用“向下”,“向右”,“向左”和“向上”功能进行导航。问题出现在我尝试使用zip-filter库定位特定令牌时:
这是从Chouser的漂亮的xml->函数中拙劣地复制而来。不幸的是,它并不起作用。在zip-filter内部,“auto”函数会向对象添加或删除元数据。除了“纯老Java对象不能有元数据”之外。
我是在错误的方向上努力吗?还是(更有可能的是),我没有足够理解zip-filter就复制它?
AST是一套非常Java风格的对象,使用CommonTree对象表示层次结构。
我按照以下方式在CommonTree上创建了拉链:
(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)))
我不确定用这种方式创建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就复制它?
auto
上面的调用可能来自children
? - Alex Millerchildren-auto
吗?这是我唯一看到自动调用树节点而不是 locs 的地方。如果我没记错的话,定制 Antlr AST 树节点非常容易。也许你可以创建一个节点类型,它要么是带有元数据的 IObj,要么有一个额外的映射,你可以在其中存储元数据并且修改 zip-filter 来处理它。 - Alex Miller