编译原理之ll(1)文法判断和左递归问题

LL(1)文法名称中第一个L表示自顶向下分析是从左向右扫描输入串,
第二个L表示分析过程中将用最左推导,
括号中的1表示每进行一步推导,只需要向前查看一个输入符号便能确定当前所应选用的产生式。

文法G是LL(1)的,当且仅当对于G的每个非终结符Α的任何两个不同产生式
Α→α,Α→β均满足下面条件(其中α和β不能同时推出ε):
1、FIRST(α)∩FIRST(β)=Φ
2、假若β=>*ε,那么FIRST(α)∩FOLLOW(A)=Φ

SELECT集的定义
对于上下文无关文法产生式Α→α, A∈VN ,α∈V,
1、若α!⇒ε,则SELECT(Α→α)=FIRST(α)
2、若α⇒ε,则SELECT(Α→α)=(FIRST(α)-{ε})∪FOLLOW(Α)
上下文无关文法是LL(1)文法的充要条件可以描述为:
对每个非终结符A的两个不同产生式Α→α,Α→β
满足(SELECT(Α→α)∩SELECT(Α→β)=Φ

例:

  • S→aA
  • S→d
  • A→bAS
  • A→ε

Select(S→aA)={a};
Select(S→d)={d};
Select(A→bAS)={b};
Select( A→ε}={a, d, #};
Select(S→aA)∩ Select(S→d)=Φ
Select(A→bAS)∩ Select(A→ε)=Φ
故文法G是LL(1)文法。

判断步骤:

  1. 求出能推出ε的非终结符
  2. 计算FIRST集
  3. 计算FOLLOW集
  4. 计算SELECT集
  5. 根据LL(1)文法的等价条件进行判断



判断ll(1)文法的算法:
1 求出能推出ε的非终结符:首先建立一个以文法的非终结符个数为上界的一维数组,记录对应非终结符能否推出ε.
计算能推出ε的非终结符步骤如下:

  1. 将数组X[ ]中对应每一非终结符的标记置初值为“未定”。
  2. 扫描文法中的产生式。
    • 删除所有右部含有终结符的产生式,若这使得以某一非终结符为左部的所有产生式都被删除,则将数组中对应该非终结符的标记值改为“否”,说明该非终结符不能推出ε。
    • 若某一非终结符的某一产生式右部为ε ,则将数组中对应该非终结符的标志置为“是”,并从文法中删除该非终结符的所有产生式。
  3. 扫描产生式右部的每一符号
    • 若所扫描到的非终结符号在数组中对应的标志是“是”则删去该非终结符,若这使产生式右部为空,则对产生式左部的非终结符在数组中对应的标志改为“是”,并删除该非终结符为左部的所有产生式。
    • 若所扫描到的非终结符号在数组中对应的标志是“否”,则删去该产生式,若这使产生式左部非终结符的有关产生式都被删去,则把在数组中该非终结符对应的标志改成“否”。
    • 重复3,直到扫描完一遍文法的产生式,数组中非终结符对应的特征再没有改变为止。

2 计算FIRST集
3 计算FOLLOW集
4 计算SELECT集
5 分析是否为ll(1)文法



当文法中含有左递归或左公共因子时,该文法肯定不是LL(1)文法。

提取左公共因子:
当文法中出现形如A→aβ|aγ的产生式,此时若对A进行语法分析,将会无法区分应该选择哪个分支,也就是出现了局部二义性问题。
解决方法:将产生式A→aβ, A→aγ变换为A→aB,B→β|γ

对文法提取左公共因子后,有可能产生无用产生式,所以需对文法进行重新化简。
也可能存在一些文法不能在有限步内提取完公共因子。
文法提取了左公共因子后,只解决了相同左部产生式右部的FIRST集不相交的问题,只有当改写后的文法不含空产生式,且无左递归时,改写后的文法才是LL(1)文法,否则还要用LL(1)文法的判别方法进行判断。



消除左递归:

  1. 直接左递归: A→Aβ,其中A ∈VN, β∈V*。
  2. 间接左递归: A→Bβ, B→ Aα,其中A,B ∈ VN, α,β∈V*
  3. 一般左递归: A⇒*Aα,其中A ∈ VN, α∈V*

消除直接左递归: 把直接左递归改为右递归
形如:P→Pα|β 其中α非ε, α,β不以P开头
改为:P→βQ,Q→αQ|ε

消除间接左递归的方法:
首先通过非终结符置换,变为直接左递归,然后再消除。

消除文法中一切左递归的方法:
(1) 以某种顺序将文法非终结符排列A1 ,A2 …An
(2)

for i:=1 to n do    
begin 
    for j:=1 to i-1 do   
    begin
        用Ai→α1r|α2r…|αkr 对形如Ai→Ajr的规则进行替代,
        其中Aj→α12…|αk是关于Aj的全部产生式;
    end
    消除Ai规则的直接左递归; 
end;

(3) 化简由(2)得到的文法

消除一切左递归后要求文法满足:

  1. 无回路(A⇒+A)
  2. 无空产生式

对非终结符号的排序不同,最后得到的文法在形式上可能不同,但它们都是等价文法。消去左递归过程中,要注意保证文法的识别符号不变。

你可能感兴趣的:(编译原理)