如何分析结果?

时间:2013-06-02 02:43:41

标签: parsing xml-parsing clojure

我正在研究一个使用parsley解析其语法的clojure重构库。 我将欧芹升级到0.9.1,然后一个函数失败。

这是该功能的作用: 假设我们有"(defn a [b] (:foo b))",重构工具将解析争论和地图查找:[b](:foo b)。然后将(:foo b)转换为地图:{b (foo :foo)}并将b中的符号[b]替换为地图的值(foo :foo)。我终于得到了{(foo :foo)}

以下代码用于最后一步:

clojure.walk/postwalk-replace {#net.cgrand.parsley.Node{:tag :atom, :content ["b"]} #net.cgrand.parsley.Node{:tag :map, :content ["{" #net.cgrand.parsley.Node{:tag :atom, :content ["foo"]} #net.cgrand.parsley.Node{:tag :whitespace, :content [" "]} #net.cgrand.parsley.Node{:tag :atom, :content [":foo"]} #net.cgrand.parsley.Node{:tag :whitespace, :content [" "]} "}"]}}
                           #net.cgrand.parsley.Node{:tag :vector, :content ["[" #net.cgrand.parsley.Node{:tag :atom, :content ["b"]} "]"]}

报告:`UnsupportedOperationException无法创建空:net.cgrand.parsley.Node net.cgrand.parsley.Node(parsley.clj:19)

然而,当我打印{#net.cgrand.parsley.Node{:tag :atom, :content ["b"]} #net.cgrand.parsley.Node{:tag :map, :content ["{" #net.cgrand.parsley.Node{:tag :atom, :content ["foo"]} #net.cgrand.parsley.Node{:tag :whitespace, :content [" "]} #net.cgrand.parsley.Node{:tag :atom, :content [":foo"]} #net.cgrand.parsley.Node{:tag :whitespace, :content [" "]} "}"]}}

#net.cgrand.parsley.Node{:tag :vector, :content ["[" #net.cgrand.parsley.Node{:tag :atom, :content ["b"]} "]"]}

然后将它们传递给postwalk:

(clojure.walk/postwalk-replace {{:tag :atom, :content ["b"]}
                            {:tag :map,
                             :content
                             ["{"
                              {:tag :atom, :content ["foo"]}
                              {:tag :whitespace, :content [" "]}
                              {:tag :atom, :content [":foo"]}
                              {:tag :whitespace, :content [" "]}
                              "}"]}}
                           {:tag :vector, :content ["[" {:tag :atom, :content ["b"]} "]"]})

Everythins很好,我得到了我想要的{:content ["[" {:content ["{" {:content ["foo"], :tag :atom} {:content [" "], :tag :whitespace} {:content [":foo"], :tag :atom} {:content [" "], :tag :whitespace} "}"], :tag :map} "]"], :tag :vector}

我的问题是:#net.cgrand.parsley.Node在欧芹中意味​​着什么?为什么我删除这些符号后(使用pprint)问题就消失了。

1 个答案:

答案 0 :(得分:2)

问题是Parsley的节点是记录,而不是常规地图。 #net.cgrand.parsley.Node{...}是此记录类型的文字表示法。记录无法清空(与clojure.core/empty一样),clojure.walk函数依赖于使用empty清空集合,因此clojure.walk函数无法对记录进行操作。

恰好pprint在打印记录时省略了标记 - 它只是将它们打印为常规地图 - 所以如果你回读pprint ed表示,你会得到一张地图,然后可以将其清空,以便将其传递给postwalk

正确的行动方案取决于您希望完成的具体内容。如果你想要实际的Node个实例,你需要编写自己的树步行者(也许适应clojure.walk/walk);如果你对常规地图没问题,你可以编写一个非常简单的树步行者用Parsley输出中的地图替换Node s,然后在变换后的树上使用clojure.walk