假设,我们实现了一个默认将二元运算表达式以右结合的方式解析的 parser,例如,此 parser 将该条表达式字符串:
a + b * c / d
解析成结构如下的表达式树:
Operator["+", a, Operator["*", b, Operator["/", c, d]]]
它的形状如下图所示:
我们希望将它转变成左结合的,也就是说,a 和 b 先以加号结合,这样结合的结果再和 c 以 * 号结合,这样结合的结果再和 d 以除号结合,怎样快速实现呢?
我们这样实现该转换函数:
rightToLeft[tree_] :=
ReplaceRepeated[
tree,
{
Operator[op1_, x_, Operator[op2_, y_, z_]] ->
Operator[op2, Operator[op1, x, y], z]
}
]
转换效果如下:
无论是从表达式上看,还是它的图示上看,可以说正是我们想要的效果。
我们想再把它给转回来,也就是说从左结合的转回又结合的,怎么办呢?
同样,也可以几行代码轻松实现一个函数搞定:
leftToRight[tree_] :=
ReplaceRepeated[
tree, {Operator[op1_, Operator[op2_, x_, y_], z_] ->
Operator[op2, x, Operator[op1, y, z]]}]
效果如下:
在 Wolfram 语言中这两件事能这么方便地办到,是因为它提供了强大的模式匹配和表达式转换功能。