



编译器经常需要访问AST节点的各个部分,如1.1节所述。从3.10版本开始,Python提供了match特性来访问各个部分的值。参考示例如下:
在上面的示例中,match形式检查AST(1.1)是否为二进制操作符,并将其各个部分绑定到三个模式变量(child1、op和child2)上。一般来说,每个case子句包含一个 模式 和一个 处理体 。模式被递归地定义为以下形式之一:模式变量;类名后跟着类的构造函数及其每个参数的模式;或者是其他文字,如字符串或列表。每个case后的处理体可以包含任意的Python代码。模式变量可以在处理体中使用,例如语句print(op)中的op。
match形式可以包含几个子句,如下面的函数leaf,当一个 L Int 的节点是AST中的叶子时,它会识别出来。match过程按照次序进行几个子句的处理,检查模式是否与输入的AST匹配,第一个匹配的子句的处理体将会被执行。以下代码的右侧显示了几个AST的leaf的输出:
在构造match表达式时,我们参考语法定义来确定希望匹配哪个非终结符,然后确保:该非终结符的每种选择都有一个匹配的情形,每种情形中的模式对应于语法规则的相应右侧。以leaf函数中的match为例,根据图1.2中所示的 L Int 语法, exp 非终结符有5个备选项,因而对应的match项有5种情形,每种情形下的模式对应于语法规则的右侧。例如,模式BinOp(e1, Add(), e2)对应于右侧的BinOp( exp , Add(), exp )。在将语法转换为模式时,需用所选择的模式变量(如e1和e2)替换 exp 等非终结符。