在编辑抽象语法树(AST) 的时候, 我们经常需要遍历整个结构, elixir 标准库中提供了两种遍历方式.
举个例子, 有这样一个 AST:
quote do
add(1, 2)
end
quote 后的数据结构是这样:
{:add, [], [1, 2]}
用图像表示的话, 大概就是这样, 有很明显的层级关系:
Prewalk
prewalk 就是以从外层到内层的顺序, 进行遍历. 注意最后返回的元组里, 第二个参数才是我们的 acc.
iex(5)> Macro.prewalk(ast, [], fn
...(5)> x, acc ->
...(5)> {x, acc ++ [x]}
...(5)> end
...(5)> )
{{:add, [], [1, 2]},
[{:add, [], [1, 2]}, 1, 2]}
postwalk 正相反, 是从内向外遍历.
iex(6)> Macro.postwalk(ast, [], fn
...(6)> x, acc ->
...(6)> {x, acc ++ [x]}
...(6)> end
...(6)> )
{{:add, [], [1, 2]},
[1, 2, {:add, [], [1, 2]}]}