抽象语法树(AST),也叫引用表达式,是一种把代码表示为数据的方式。
AST 中的每个节点都是一个三元素元组。
# AST representation of:
# 2 + 3
{:+, [], [2, 3]}
第一个元素是原子,表示要执行的操作。第二个元素是关键字列表,也就是元数据。第三个元素是实参列表,里面装着其他节点。整数、原子、字符串这样的字面量在 AST 中直接以自身的形态表示,而不是三元素元组。
把 Elixir 代码转换成 AST,以及把 AST 转换回代码,都是标准库的一部分。在Code模块(例如把包含代码的字符串转换成 AST)和Macro模块(例如遍历 AST 或把它转换成字符串)中,都能找到处理 AST 的函数。
注意,标准库中的所有函数都用 "quoted" 这个名字来表示 AST(它是_引用表达式_的缩写)。
把代码转换成 AST 的特殊形式叫做 quote。它接收一个代码块,并返回它的 AST。
quote do
2 + 3 - 1
end
# => {:-, [], [
# {:+, [], [2, 3]},
# 1
# ]}
把代码表示为 AST 的能力,是 Elixir 元编程的核心。_宏_是编写能生成 Elixir 代码的 Elixir 代码的一种方式,它的工作原理就是返回 AST 作为输出。
AST 的另一个使用场景是静态代码分析,比如 Exercism 自己的工具 Analyzer,也就是那个会在你提交的解答下面留言的小机器人,你可能已经见过它了。