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(Α→β)=Φ
例:
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)文法。
判断步骤:
2 计算FIRST集
3 计算FOLLOW集
4 计算SELECT集
5 分析是否为ll(1)文法
提取左公共因子:
当文法中出现形如A→aβ|aγ的产生式,此时若对A进行语法分析,将会无法区分应该选择哪个分支,也就是出现了局部二义性问题。
解决方法:将产生式A→aβ, A→aγ变换为A→aB,B→β|γ
对文法提取左公共因子后,有可能产生无用产生式,所以需对文法进行重新化简。
也可能存在一些文法不能在有限步内提取完公共因子。
文法提取了左公共因子后,只解决了相同左部产生式右部的FIRST集不相交的问题,只有当改写后的文法不含空产生式,且无左递归时,改写后的文法才是LL(1)文法,否则还要用LL(1)文法的判别方法进行判断。
消除间接左递归的方法:
首先通过非终结符置换,变为直接左递归,然后再消除。
消除文法中一切左递归的方法:
(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→α1|α2…|αk是关于Aj的全部产生式;
end
消除Ai规则的直接左递归;
end;
(3) 化简由(2)得到的文法
消除一切左递归后要求文法满足:
对非终结符号的排序不同,最后得到的文法在形式上可能不同,但它们都是等价文法。消去左递归过程中,要注意保证文法的识别符号不变。