Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java对象树上创建的Clojure拉链能否在zip筛选器中工作?_Java_Interop_Clojure_Antlr - Fatal编程技术网

在Java对象树上创建的Clojure拉链能否在zip筛选器中工作?

在Java对象树上创建的Clojure拉链能否在zip筛选器中工作?,java,interop,clojure,antlr,Java,Interop,Clojure,Antlr,我目前正在将ANTLR和Clojure粘在一起,试图在ANTLR返回的抽象语法树上创建Clojure拉链 AST是一组非常Java风格的对象,使用对象表示层次结构 我在CommonTree上做了一个拉链,如下所示: (defn branch? [tn] (not (zero? (.getChildCount tn)))) (defn children [tn] (.getChildren tn)) (defn make [tn children] (doto (CommonTree. tn)

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

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

我在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)))
(我不能100%确定以这种方式制作CommonTree节点是否有效。我还没有做足够的工作来验证它…)

我使用以下函数:

(def zip-ast (parse testfile))
到目前为止,一切顺利。这确实有效。我可以使用“向下”、“向右”、“向左”和“向上”功能导航。当我尝试使用zip筛选器库查找特定令牌时,出现了问题:

(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筛选器中,函数“auto”添加或删除对象中的元数据。除此之外,普通的旧Java对象不能有元数据


我找错树了吗?或者(更可能的是),我对zip筛选器的理解还不足以复制它吗?

Zipper存储分支、子项,并在包裹节点的loc上将函数作为meta,而auto似乎正在向对象周围的loc包装(向量)添加或移除meta,而不是对象本身。所以,我认为这不是问题

你能解释一下什么“就是不起作用”吗

分支?
功能是一个看起来可疑的地方(这让我被定制的拉链绊倒了)。请注意,您在
令牌=
中的第一个
条件检查
分支?
-如果令牌没有子项,它在
令牌=
中将不匹配,这可能令人惊讶。分支机构?表示节点是否可能有子节点,因此有时您希望返回true,即使它实际上没有子节点。除此之外,我没有看到任何明显的变化

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

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

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

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

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

token=中第一个条件的捕获良好。这是我的错误,复制我不完全理解的代码。java->函数最终将支持其他条件,匿名函数的退化形式是因为我去掉了其他谓词来理解这个问题。总的来说,“只是不起作用”是当auto试图在CommonTree对象上使用meta执行时,我得到一个ClassCastException。with meta仅适用于IObj(即Clojure对象)的实现者。还可以使用Antlr“编译”成表示Clojure数据结构的字符串。。。哇!酷。我想。我可以看到这将如何减少Antlr的AST对象和Clojure函数之间的阻抗失配。不知怎么的,从旧金山到西雅图,还是感觉像是从芝加哥飞过来的。你能发布堆栈跟踪的相关部分吗?我猜上面的自动呼叫可能来自
儿童
?对不起<代码>儿童自动
我是说?这是我看到的唯一在树节点上调用auto而不是loc的地方。IIRC,定制Antlr AST树节点非常容易。也许你可以创建一个节点类型,或者是一个带meta的IObj,或者有一个额外的映射,你可以在其中存储meta并破解zip过滤器来处理它。仔细想想,我的拉链功能似乎有问题。我在名称空间中定义了“branch?”和“children”,忽略了zip/branch?还有拉链/儿童?功能。我希望我的函数被调用,但是zip中的函数被调用,从loc中解包对象并用对象调用我的函数。