编译原理——自上而下的语法分析

语法分析的功能:

 语法分析方法的分类:

(1)自上而下(自顶而下)分析法:从开始符号出发,进行最左推导,或从根开始,构造推导树。(回溯分析法属于不确定的自上而下的语法分析方法,而递归下降分析法和预测方法都属于确定的自上而下的语法分析法)

(2)自下而上(自底而上)分析法:从输入串开始,直至文法开始符号。

下面来介绍回溯分析法:

实例:

S→xAy

A→ab|a

输入串为xay,说明分析过程

分析:从开始符号开始,进行左推导。如图所示:

 推导之后,如右图所示,该串为xaby,显然,与题目输入串xay是不一致的,因此需要回溯,回溯得到的结果为:

 回溯分析法实际上是一种试探的方法,其效率是非常低的。特别是当匹配失败后再多次试探后,逐级回溯的开销是令人难以忍受的。上面,我们来分析出现回溯的原因。

回溯出现的原因:

1.回溯——公共左因子的存在(A→ab1/ab2)

2.含有左递归引起的回溯(直接左递归和间接左递归)

 ①从开始符开始,但是开始符S有两个产生式,但是串第一个字符是b,首先我们选第二个产生式,如一图所示,但是图一的结果和我们的结果不一致,所以需要回溯。回溯到前一步就是选产生式那一步。

②回溯之后,选第一个产生式,由于第一个产生式存在左递归,加上结果所需要的串第一个字符为b,所以选择第一个产生式之后,再选择第二个产生式,如图2所示,显然,结果也是错误的,需要回溯到上一步。

③回溯之后,选择第一个产生式之后,再选择第一个产生式,最后再选择第二个产生式。结果正确。 

由此可知,一旦出现错误,一步一步去回溯,效率是非常低的。

3.由于ε产生式引起的回溯

  ①从开始符S开始,但是开始符S有两个产生式,但是串第一个字符是a,首先我们选第一个产生式。出现非终结符A,但是A有两个产生式,串第二个字符是b,我们选第一个产生式,如一图所示,显然结果是错误的,需要回溯到上一步。

②回溯到上一步,即回到选A产生式那一步,我们刚刚选择第一个产生式是错误的,所以我们选择第二个产生式,接着还有一个非终结符S,加上结果串最后一个字符为b,所以我们选择第二个产生式,如图二所示。结果正确。

由此可知,一旦出现错误,一步一步去回溯,效率是非常低的。

解决回溯的办法:

1.提取公共左因子

产生式A→ab1|ab2|...|abn

将公共左因子a提取出来,变成:

A→aB

B→b1|b2|...|bn

例如:

 2.消除直接左递归(变成右递归)

一般地,A→Aa1|Aa2|...|Aan|b1|b2|...|bn

变成右递归:

A→b1F|b2F|...|bnF

F→a1F|a2F|...|anF|ε

例如:

 3.消除间接左递归(先把间接左递归变成直接左递归,最后再消除直接左递归)

例如:

 ①→②间接左递归转换为直接左递归

②→③消除直接左递归

间接左递归算法:

1.将文法G的所有非终结符按任一顺序排列,设为A1....An

2.执行下面的算法,消除可能的左递归

for(int i=1;i<=n;i++){
    for(int j=1;j<=i-i;j++){
        把一个形如Ai→Ajα的产生式改写成为Ai→δ1α|δ2α|...|δnα|;
        (其中,Aj→δ1|δ2|...|δn是Aj的所有产生式)
        消除Aj产生式的直接左递归
}
}

3.化简:删除多余产生式,即在从文法开始符号的任何推导都不会出现的非终结符的产生式。

举个例子:

(1)首先,有三个非终结符 S Q R,可以按SQR排序,或者RQS排序。我们就以按RQS排序为例,RQS设为A1A2A3.  

(2)接下来,进入算法

①当i=1时,无任何操作。R→Sa|a

②当i=2时(A2),j=1(A1),这时可以理解为A2和A1存在关系,将A1(R)带入A2(Q)得Q→Sab|ab|b,该式子不存在直接左递归。注:一直是Ai→Aj的形式

③当i=3时(A3),j=2(A2),这时可以理解为A3和A2存在关系,将A2(Q)带入A3(S)得

S→Rbc|bc|c,j因为要遍历循环,当i=3时(A3),j=1(A1),将A1(R)也带入,最后的结果为S→Sabc|abc|bc|c,该式子存在直接左递归,所以我们要消除直接左递归。得到最后结果为:

S→abcB|bcB|cB

B→abcB|ε

最后的结果,用蓝色标出,但是前面两个蓝色为多余的产生式,删掉。

最后得:

S→abcB|bcB|cB

B→abcB|ε

文法产生语言的语言为:(abc|bc|c)(abc)*。

练习:

首先,先提去公共左因子。 如下图所示:

其次,第三个产生式有直接左递归,因此我们需要消除直接左递归。 如下图如示:

接着,第一个产生式和第三个产生式存在间接左递归。SBAP设为A1A2A3A4 ①当i=1,无操作②当i=2,j=1时,无操作③当i=3,j=2,无操作,当i=3,j=1时,将S带入A得A→ABbcP|bcbcP|dP④当i=4,j=3,无操作,当i=4,j=3,无操作,当i=4,j=2,无操作,当i=4,j=1,无操作。结果如下图所示:

最后,第三个产生式存在直接左递归,所以我们需要消除左递归,如下图所示:

 

 创作不易,点个关注吧!!!

  • 26
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值