自顶向下语法分析LL(1)

自顶向下分析法就是从文法的开始符号出发,不断建立直接推导,试图构造一个最左推导序列,最终由它推导出与输入符号串完全匹配(相同)的句子。
从语法树的角度看,自顶向下分析法就是以开始符号为根节点,试图向下构造一棵语法树,其端末结符号串与输入符号串相同。
能使用自顶向下分析技术的文法正是LL(1)文法.

LL(1)文法

LL(1)的含义:第1个L表明自顶向下分析是从左向右扫描输入串,第2个L表明分析过程中将用最左到推倒,1表明只需向右看一个符号便可决定如何推倒即选择哪个产生式(规则)进行推导,类似也可以有LL(k)文法,也就是需要向前查看k个符号才能确定选用哪个产生式。

若文法G[S]为
S->AB
S->bC
A->ε
A->b
B->ε
B->aD
C->AD
C->b
D->aS
D->c

判断别步骤

1.求出能推出ε的非终结符

非终结符SABCD
初值-----
第一次扫描-yy-n
第二次扫描yyynn

2.求first集,非终结符第一个的终结符集合

非终结符中间集最终集
Sfirst(A)-{ε} U first(B) -{ε} U {b} U {ε}{ε, b,a}
A{ε, b}{ε, b}
B{ε, a}{ε, a}
Cfirst(A)-{ε} U first(D) U {b}{a, b,c}
D{a,c}{a,c}

3.求follow集,非终结符跟着的第一个的终结符集合

(1) 对于文法的开始符号 S,置 # 到 FOLLOW(S) 中;
(2)若 A -> αBaβ 是一个产生式,a 为终结符,则把 a加至 FOLLOW(B) 中;
(3)若 A -> αBβ 是一个产生式,则把 FIRST(β) - {ε} 加至 FOLLOW(B) 中;
(4)若 A -> αB 是一个产生式,或 A -> αBβ 是一个产生式,而 β =*> ε, 则把 FOLLOW(A) 加至FOLLOW(B) 中

非终结符规则中间集最终集
S(1),(4 D->aS){#} U follow(D){#}
A(3,4 S->AB), (3 C->AD)first(B)-{ε} U follow(S) U first(D){a,#,c}
B(4 S->AB)follow(S){#}
C(4 S->bC)follow(S){#}
D(4 B->aD),(4 C->AD)follow(B) U follow©{#}

4.求select集,每个式子对应的终结符

产生式中间集最终集
S->ABfisrt(AB) - {ε} U follow(S){a,b,#}
S-bCfirst(bC){b}
A->εfisrt(ε) - {ε} U follow(A){a,#,c}
A->bfisrt(b){b}
B->εfisrt(ε) - {ε} U follow(B){#}
B->aDfisrt(aD){a}
C->ADfisrt(AD) - {ε}{a,b,c}
C->bfisrt(b){b}
D->aSfisrt(aS){a}
D->cfisrt©{c}

LL(1)文法的判别,从上表格最终集中得出
select(S->AB) ∩ select(S->bC) = {b} 不为空,当终结符为S时,讲入符号为b时,不知道选用哪个式子
select(A->ε) ∩ select(A->b) = {}为空
select(B->ε) ∩ select(B->aD)= {}为空
select(C->AD) ∩ select(C->b)= {b}不为空,同上
select(D->aS) ∩ select(D->c)= {}为空

从非LL(1)文法到LL(1)文法的等价转换

由LL(1)文法定义可知,若方法中有直接或间接左递归或者有左公共因子则肯定不是LL(1)文法,因而我们高潮消除文法中的左递归,撮左公共因子进行等价转换。

问题1:左递归问题
若采用自顶向下的语法分析,应消除文法中存在的左递归。

因为左递归的存在,有可能使推导不能结束,分析陷入循环状态。 例如:
A → Aβ (A∈VN , β∈VT*) 直接左递归
A → Bβ B->Aα (A,B∈VN , α,β∈VT*) 间接左递归

左递归还比较好理解,例如:我需要匹配的字符串是 bsd 就需要从左端 b 开始是被,推导时,先用 A -> Aa 推导 AAa,此时不符合条件,但因为还有非终结符,不能结束,而是继续推导。此时就会陷入死循环。

  1. 消除直接左递归

P→Pα1 / Pα2 /…/ Pαn / β1 / β2 /…/βm
其中,αi(I=1,2,…,n)都不为ε,而每个βj(j=1,2,…,m)都不以P开头,将上述规则改写为如下形式即可消除P的直接左递归:
P→β1 P’ / β2 P’ /…/βm P’
P’→α1P’ / α2 P’ /…/ αn P’ /ε
例:
S->Sa
S->b
可以改写为
S->bS’
S’->aS’|ε

  1. 消除间接左递归

消除间接左递归的方法是,把间接左递归文法改写为直接左递归文法,然后用消除直接左递归的方法改写文法。
消除左递归算法:
(1) 把文法G的所有非终结符按任一顺序排列,例如,A1,A2,…,An。
(2) for (i=1;i<=n;i++){
     for (j=1;j<=i-1;j++){
      把形如Ai→Ajγ的产生式改写成Ai→δ1γ /δ2γ /…/δkγ
      其中Aj→δ1 /δ2 /…/δk是关于的Aj全部规则;
      消除Ai规则中的直接左递归;
   }
(3) 化简由(2)所得到的文法,即去掉多余的规则。
例:
A->Ba
A->aB
B->Ac
B->d
首先,令非终结符的排序为A,B。对于A,不存在直接左递归。把A代入到B中的相关规则中得
B->Bbc
B->d|aBc
B存在直接左递归。在消除了B的直接左递归后,得到整个文法为:
B->(aBc|d)B’
B->bcB’|ε
最终得:
A->Ba
A->aB
B->(aBc|d)B’
B->bcB’|ε

问题2:左公共因子问题
若采用自顶向下的语法分析,应消除文法中存在的左公因子。

因为左公因子的存在,使式子select存在不为空集的情况如
A → αβ | αγ
select(A → αβ) ∩ select(A → αγ) 不为空

提取公因式

A→αβ1 |αβ2|αβ3|…|αβn,提取左公因子后变为
A->α(β1|β2|β3|…|βn),再引出非终结符A’
A->αA’
A’->β1|β2|β3|…|βn
例:
S->aSb
S->aS
S->ε
提取左公因式
S->aS(b|ε)
S->ε
进一步变换
S->aSA
A->b|ε
S->ε

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值