Parsing 如何解析结果?

Parsing 如何解析结果?,parsing,xml-parsing,clojure,Parsing,Xml Parsing,Clojure,我正在研究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.parsl

我正在研究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[:content[]{:tag:whitespace,:content[']}]}

然后将它们传递到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"]} "]"]})
一切都很好,我得到了我想要的
{:content
["["
{:内容
["{"
{:content[“foo”],:tag:atom}
{:content[“”],:tag:whitespace}
{:content[“:foo”],:tag:atom}
{:content[“”],:tag:whitespace}
"}"],
:tag:map}
"]"],
:tag:vector}


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

问题是欧芹的节点是记录,而不是常规映射。
#net.cgrand.parsley.Node{…}
是这种记录类型的文字符号。记录不能清空(与
clojure.core/empty
)一样,
clojure.walk
函数依赖于使用
empty
清空集合,因此
clojure.walk
函数无法对记录进行操作

在打印记录时,
pprint
恰好忽略了标记——它只是将记录作为常规映射打印出来——因此,如果您读回
pprint
ed表示,您将得到一个映射,然后可以将其清空,这样您就可以将其传递到
postwark


正确的操作过程取决于您希望完成的具体内容。如果您想要实际的
节点
实例,您需要编写自己的树漫游器(可能需要修改
clojure.walk/walk
);如果您对常规映射没有问题,您可以编写一个非常简单的树遍历器,用欧芹输出中的映射替换
节点
s,然后在转换后的树上使用
clojure.walk

这很有意义。似乎我必须编写自己的树遍历器,因为库到处都使用节点实例。谢谢。
(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"]} "]"]})