假设,我们实现了一个默认将二元运算表达式以右结合的方式解析的 parser,例如,此 parser 将该条表达式字符串:

a + b * c / d

解析成结构如下的表达式树:

Operator["+", a, Operator["*", b, Operator["/", c, d]]]

它的形状如下图所示:

截屏2023-01-27 上午1.28.07.png

我们希望将它转变成左结合的,也就是说,a 和 b 先以加号结合,这样结合的结果再和 c 以 * 号结合,这样结合的结果再和 d 以除号结合,怎样快速实现呢?

我们这样实现该转换函数:

rightToLeft[tree_] := 
  ReplaceRepeated[
    tree,
    {
      Operator[op1_, x_, Operator[op2_, y_, z_]] -> 
      Operator[op2, Operator[op1, x, y], z]
    }
]

转换效果如下:

截屏2023-01-27 上午1.31.13.png

无论是从表达式上看,还是它的图示上看,可以说正是我们想要的效果。

我们想再把它给转回来,也就是说从左结合的转回又结合的,怎么办呢?

同样,也可以几行代码轻松实现一个函数搞定:

leftToRight[tree_] := 
 ReplaceRepeated[
  tree, {Operator[op1_, Operator[op2_, x_, y_], z_] -> 
    Operator[op2, x, Operator[op1, y, z]]}]

效果如下:

截屏2023-01-27 上午1.33.08.png

在 Wolfram 语言中这两件事能这么方便地办到,是因为它提供了强大的模式匹配和表达式转换功能。