Compiler 学习值Parsing(2)

三:Ambiguity:

上一次结尾时候提到ambiguity,在left most推导过程中出现了两种parse tree。

     E                                                        E

-> E + E                                                /    \

-> E * E + E                                        E   +  E

-> id * E + E                                     /   \        |

-> id * id + E                                 E   *  E     id

-> id * id + id                                |        | 

                                                    id       id

同时我们又可以这么构建:

   E                                                      E
-> E * E                                             /   \
-> E * E + E                                     E  *  E
-> id * E + E                                     |   /   \
-> id * id + E                                  id  E  +  E
-> id * id + id                                       |     |

                                                           id    id

这篇的主要目的是介绍一种解决ambiguity的方法,之所以有两种推到方式的原因是我们在替换non-terminal的时候很多选择,我们可以选择乘法,可以选择加法,当然我们可以说必须先选择排在左边的替换规则,如果该规则不适用,再往右边选择。但是这种规则会带来其它问题,这里主要不是介绍这种方法。

一个更常用的方法是重写规则,体现出优先级:

我们将 E -> E + E | E * E | (E) | id的规则改写为

E -> E' + E | E'                             (1)

E' -> id * E' | id | (E) * E' | (E)        (2)

这里分离了+和*的规则, 第一个规则是我们可以可以最终得到 E' + E' + E' + ... + E', 第二个规则可以使我们得到(单看前两个production) id' * id * id * id * ... * id;

这样使得加法规则必然是在乘法规则的外围,或者说multiply binds more tight than plus rule. 从上面的例子可以看出,优先级高的运算符在树的更低层。

除了优先级之外还有结合性来解决解决ambiguity。

所以这里我们是通过重写规则来解决ambiguity问题,这同样也是一种非常non-trivial的工作,规则更难懂,而且并不是所有事情都可以用优先级解决的。所以大多数Parser都采用一些disambiguity mechanisms。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值