CS143 6、7. 自顶向下和自底向上的语法分析

现在理解得还不是很好,先去做PA3,在做作业的过程中加深理解。

错误处理

在语法分析阶段,我们要检查程序中的语法是否正确,如果有错误,需要一些方法报错,以及越过错误点继续检查。

下面是几个错误处理方法

恐慌模式

最简单同时也是使用最多的方法。

当遇到一个错误时,我们跳过一些输入字符,直到遇到指定的字符(串)后从该处继续检查,这些指定的字符需要人为设置,通常称为同步字符(synchronizing token)。

错误产生式

在产生式集合中加入可以推导出常见错误的产生式,这样,在推导过程中会导出错误的字符串,此时我们就知道产生了错误,就可以基于此给出错误信息。

局部和全局纠正

当错误产生时,在错误点修改(增删改)尽可能少的字符,以使程序正确,这个方法目前仅具理论价值。

Abstract Syntax Tree

AST是语法分析树的简化版本,如:

可以被如下AST代替:

自顶向下的语法分析

在自顶向下的分析中,我们要从开始符开始,如果通过推导得到了输入串,那么说明没有语法错误,并且在这个过程中我们也生成了语法分析树,如果不能推导出,则程序有语法错误。

有两种方法,第一种说白了,就是普通的深度搜索算法,其中会发生回溯,开销较大,不常用,而第二种是不会发生回溯的搜索,比较常用,结果都是给出一个字符串的最左推导或报错。

带回溯的深度搜索算法

对于当前的公式,从左到右对每个非终结符的可能推导一个一个尝试,直到找到结果(返回答案),或发现不匹配(回溯),如果所有可能都无法匹配,那么报错。

左递归

如果存在 S → S a ∣ b S\rightarrow Sa|b SSab这种右侧的第一个符号为非终结符的表达式,可能会发生无限递归的情况,称为左递归,为了消除这种无线递归,将这种表达式重写为 S → b ∣ A S\rightarrow b|A SbA A → a A A\rightarrow aA AaA,更复杂的情况需要更一般化的处理。

不带回溯的预测算法

通过查看目标字符串中的下一个字符,可以指导我们选择哪一个产生式进行推导,从而避免了繁琐的回溯过程。在这里需要使用LL(k)语法。

LL(k)语法

LL(k)语法是产生式的另一种书写方式,下面的产生式:

可以写成:

即将公式右侧以相同字符开始的部分合并,这样,每次对于相同的字符,仅有一种选择,就可以避免回溯的发生。

First(a)

从上面的LL(k)语法看出,我们需要知道从一个字符可以推导出的首个字符有哪些。

将从a可以推出的字符串的首字符的集合记为First(a)

First(a)的方法:

  • a为终结符,则First(a) = {a}
  • a为非终结符,且有 a → Y 1 Y 2 . . . Y n a\rightarrow Y_1Y_2...Y_n aY1Y2...Yn,对于任意 i ∈ [ 1 , n ] i \in [1,n] i[1,n],若有 Y 1 Y 2 . . . Y i − 1 ⇒ ∗ ϵ Y_1Y_2...Y_{i-1} \Rightarrow ^* \epsilon Y1Y2...Yi1ϵ,则 F i r s t ( Y i ) ⊆ F i r s t ( a ) First(Y_i) \subseteq First(a) First(Yi)First(a),即 F i r s t ( Y i ) First(Y_i) First(Yi)的元素都可以计入 F i r s t ( a ) First(a) First(a)
  • 如果有 a → ϵ a\rightarrow \epsilon aϵ,则将 ϵ \epsilon ϵ加入。
Follow(a)

龙书P 130。

自底向上的语法分析

与前面的方法相反,在这里,我们从输入串开始,通过反向推导产生式,最后如果得到开始符,说明没有语法错误,否则报错。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值