递归的预测分析法
-
- 例子:
-
- 注意:这里SELECT集中因为(4)、(7)推导出空串,所以需要进行特别分析。其他产生式都较为简单可以直接得出
-
-
上图是对整个(1)进行匹配
-
- 对(2)进行匹配
-
- 对 进行匹配
-
- 对 进行匹配
-
- 对 进行匹配
-
- 对进行匹配
-
-
- 例子:
非递归的预测分析法
-
非递归的预测分析不需要为每个非终结符编写递归下降过程,而是根据预测分析表构造一个自动机,也叫表驱动的预测分析
-
- 以有穷自动机相似,但是下推自动机(多了一个栈)起着记忆的作用。比如类似例子中的,有穷自动机是不能处理 L L L等式,但是下推自动机可以利用栈进行处理。
-
-
上图中的输出组合起来就是最左推导
-
具体过程
-
首先 E E E 对应 剩余输入的 i d id id ,查预测分析表,可知$ E$ 遇到 i d id id时, 结果为 E — — > T E , E——>TE^{,} E——>TE,,输出结果
-
此时栈为 T E , TE^{,} TE,,查预测分析表,可知$ T$ 遇到 i d id id时, 结果为 T — — > F T , T——>FT^{,} T——>FT,,输出结果
-
此时栈为 F T , E , FT^{,}E^{,} FT,E,,查预测分析表,可知$ F$ 遇到 i d id id时, 结果为 F — — > i d F——>id F——>id,输出结果 i d id id终结符。剩下输入为 + i d ∗ i d +id*id +id∗id。对 + + +进行重复以上步骤
注:遇到空串时,剩余输入不变换,继续进行匹配
-
-
-
-
表驱动的预测分析法
-
递归的预测分析法vs.非递归的预测
-
-
递归方法:
- 需要为文法分析的每个过程编写一个递归下降过程,所以规模较大
- 使用产生式的右边来编写程序,所以较为直观
- 高深度的调用需要从递归子程序进行连接,这样会影响效率
- 根据右边产生式生成,较难自动生成
-
非递归方法:
- 自动机的方式生成,容易自动生成
-
-
-
预测分析法实现步骤
- 构造文法
- 改造文法:消除二义性、消除左递归、消除回溯
- 求每个变量的 F I R S T FIRST FIRST集和 F O L L O W FOLLOW FOLLOW集,从而求得每个候选式的 S E L E C T SELECT SELECT集
- 检查是不是 LL(1) 文法。若是, 构造预测分析表
- 对于递归的预测分析,根据预测分析表为每一个非终结符编写一个过程;对于非递归的预测分析,实现表驱动的预测分析算法
预测分析中的错误处理
- 预测分析中的错误检测
- 栈顶的终结符和当前输入符号不匹配
- 栈顶非终结符与当前输入符号在预测分析表对应项中的信息为空
- 恐慌模式
-
忽略输入中的一些符号,直到输入中出现由设计者选定的同步词法单元(synchronizing token)集合中的某个词法。
- 同步词法单元的目的分析器一直搜索下去,提高效率
- 其效果依赖于同步集合的选取。集合的选取应该使得语法分析器能从实际遇到的错误中快速恢复
- 例如可以把FOLLOW(A)中的所有终结符放入非终结符A的同步记号集合
-
如果终结符在栈顶而不能匹配,一个简单的办法就是弹出此终结符
-
- M [ A , a ] M[A,a] M[A,a] 中 M M M表示为预测分析表, A A A表示为栈顶非终结符, a a a当前输入符号
-
- ①中 E E E 匹配到 + + + 时,两者不匹配,忽略输入符号 + + +
- ②中, F F F 匹配到 + + + 时,是 synch同步符号 ,忽略 F F F
-
语法分析_2 要点
-
-
- 当为非终结符时,递归调用 X j X_j Xj调用的过程