编译原理-自顶向下分析法思路梳理

自顶向下分析三个问题:
1、无左递归
2、无二义性
3、提取左公因子

为什么要定义LL(1)文法?

因为我们要自顶向下分析,适用于产生式的推导规则。

但是问题来了,我们如何确定使用哪个产生式去推导呢?

我们可以使用回溯,挨个尝试产生式。这就是递归下降的语法分析。

但是,效率太低了,怎么办?

我们在输入串中peek一个输入字符,如果我们能根据这个符号确定要使用哪个产生式去推导,就万事大吉了。
这时,如果我们使用递归下降的技术是尾递归的,可以接受。
如果我们能根据下一个字符确定使用哪个产生式,这个BNF就是LL(1)的。

现在的问题是,我们如何定量的描述我们的文法是不是LL(1)的呢?

需要引入First集。
我们要根据我们的产生式算出每个产生式的first集。这样,我们就可以根据产生式的first集确定使用哪个产生式。
如果我们的每一个非终结符号的所有产生式的first集都不相交,我们就能轻松的选择出下一步要使用的产生式。这时,我们的这个文法就是LL(1)的。

但是如果我们的产生式的fisrt集中有空怎么办?

这时,我们要通过这个产生式的fisrt集判断使用那个产生式就很困难了。 因为,我们可以使用任意遍产生出空的产生式。

那我们怎么选择呢?

显然,让我们做出选择的信息是不够的,怎么办?
我们需要引入Follow集。

因为,如果某个产生式能产生出空,那么我们peek的下一个字符,就可能是这个空产生式的下一个字符。所以,我们还要计算Follow集。

至此,我们已经可以描述我们的文法是否是LL(1)的了。
对于文法中所有具有相同左部的产生式A-> a | b;
(1) First(a) 交 First(b) = 空。
(2) 如果a=>空,First(b) 交 Follow(A) = 空。
(3) 如果b=>空,First(a) 交 Follow(A) = 空。

那么就到实现环节了!

我们如果高效的实现一个自顶向下分析程序?

预测分析法
现在要模拟我们手写推导的方式了。

思考我们手写推导时,当我们推导到中间某步时,我们的格局是一个最右句型。

首先,我们要记录当前的最右句型,我们采用什么数据结构呢?

思考我们推导时,总是选择最左边的非终结符号选择产生式进行推导,推导后依然推导最左非终结符号,思考我们拓展的方向,发现总是在左边删除一个非终结符,加入一个产生式,这不就是一个栈的结构吗!!!
所以,我们可以利用栈来保存我们当前的格局(最右句型) 栈中保存这个最右句型。
其实,这就是一个PDA呀(学过形式语言与自动机的同学会发现他们之间的相似性)
我们还要解决选择产生式的问题:即根据First和Follow集确定预测分析表
最后:
我们只需要根据读入输入符号,和栈顶的符号,查预测分析表,得到要用的产生式,压栈。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值