一、知识点总结
(1)一旦发现该非终结符的某个候选式与输入串相匹配,就用这个候选式去扩展语法树,并返回“真”值;
(2)该候选式和输入串不匹配,则保持原来的语法树和IP值不变(IP回溯),并返回“假”值
2>回溯的不确定性问题
3>虚假匹配的问题
4>不能准确地确定输入串中出错的位置
5>效率低
P→Pα1|Pα2|…|Pαm|β1|β2|…|βn,
消除P的直接左递归性就是把这些规则改写成:
P’→α1P’| α2P’|…|αmP’| ε
S→Qc|c
Q →Rb|b
R →Sa|a
把R带入到Q中有关的候选式:
Q →Sab|ab|b
现在Q同样不含直接左递归,把它带入S的有关候选式:
S →Sabc|abc|bc|c
将文法中所有如下形式的产生式:
Pi →Pjγ|β1|β2|…|βn
Pj→δ1|δ2|δ3|…|δk
改写成:
Pi →δ1γ|δ2γ|δ3γ|…|δkγ|β1|β2|…|βn
P→Pα1|Pα2|...|Pαm|β1| β2|...| βn
消除P的左递归
P→ β1P'| β2P'|...| βnP'
P'→ α1 P'| α2 P'|...|αm P'| ε
3>化简改写后的文法,即去除那些从开始符号出发却永远无法到达的非终结符的产生规则。
最终得到无左递归的文法。
消除回溯的关键在于定义First集:令文法G是不含左递归的文法,对G的非终结符的候选α,定义它的开始符号(终结首符)集合:

如果非终结符A的任意两个候选式αi和αj的开始符号集满足FIRST(αi)∩FIRST(αj)=Φ,则A可以根据所面临的第一个输入符号,准确地指派一个候选式α去执行任务,α是那个FIRST集含a的候选式,即 a ∈FIRST(α)。
A→δβ1|δβ2|…|δβn|γ1| γ2|…|γm
其中每个γ不以δ开头
那么把这些产生式改写为:
A→δA’ |γ1| γ2|…|γm
A’→β1|β2|…|βn
当一个文法不含左递归,并且满足每个非终结符的所有候选首符集两两不相交的条件,如果空字符属于某个非终结符的候选符号集,那么问题就比较复杂,此时需要引入follow集,

特别地,如果S-->…A,则#∈FOLLOW(A)
FOLLOW(A)集合是所有句型中出现在紧接A之后的终结符号或#所组成的集合
当非终结符A面临输入符号a,且a不属于A的任意候选式的FIRST集但A的某个候选式的FIRST集包含ε时,只有当a∈FOLLOW(A),才可能允许A自动匹配
(1)文法不含左递归
(2)对于文法中每一个非终结符A的各个产生式的候选式的FIRST集两两不相交。即,若
A→α1|α2|…|αn
则 FIRST(αi)∩FIRST(αj)=Φ (i≠j)
(3)对于文法中的每个非终结符A,若它的某个候选首符集包含ε,则
FIRST(A)∩FOLLOW(A)=Φ
如果一个文法G满足以上条件,则称该文法G为LL(1)文法(第1个L代表从左到右扫描输入串,第2个L代表最左推导,1表示分析时每一步只看1个符号)
这个分析程序由一组(可能的)递归程序组成,
每个过程对应文法的一个非终结符。
这样一个分析程序称为递归下降分析器。
对文法的每一个非终结符都编一个分析程序
当根据文法和当时的输入符号预测到要用某个非终结符去匹配输入串时,就调用该非终结符的分析程序。
LL-自左向右扫描、自左向右的分析和匹配输入串。
分析过程表现为最左推导的性质。
(1)若X=a=#,分析成功,停止。E匹配输入串成功.
(2)若X=a≠#,把X推出栈,再读入下一个符号。
(3)若X∈Vn,查分析表M
a) M[X,a]= X→UVW
则将X弹出栈,将UVW压入
注:U在栈顶 (最左推导)
b) M[X, a] = error 转出错处理
c) M[X, a] = X-〉ε ---a为X的后继符号
则将X弹出栈 (不读下一符号)
继续分析。
预测分析表的构造:
first表的构造:
若X终结符,则FIRST(X)={X}若X为非终结符,且有X->a …的产生式,则把a加入到FIRST(X)中;
若X->Y…是一个产生式,且Y为非终结符,则把FIRST (Y)-ε加入到FIRST(X)中;
若X->Y1Y2Y3….YK,是产生式, Y1Y2Y3….Yi-1是非终结符,而且ε属于 FIRST (Yj)(1<=j<=i-1),则把FIRST (Yj)-ε加入到FIRST(X)中;如果ε属于所有的FIRST (Yj),则ε加入到FIRST(X)中
follow表的构造:
若A->αBβ, 则把FIRST (β)-ε加入到FOLLOW(B)中,
若A->αB 是一个产生式,或 A->αBβ是一个产生式,而β-> ε,则把FOLLOW(A)加入到FOLLOW(B)中
预测分析表的构造
对每个终结符a,如果a属于FIRST(α),则把该产生式写入到M[A,a]
若ε属于FIRST(α),则对任何b属于FOLLOW(A), 把该产生式加入到M[A,b]
所有无定义的M[A,a]标上出错标志
当栈顶的终结符与当前的输入符不匹配
非终结符A处于栈顶,面临的输入符号为a, 但分析表中M[A,a]为空
错误恢复的方法:
将FOLLOW(A)设为同步符号
将FIRST(A)加入到同步符号
如果非终结符产生空串,可以自动匹配,以推迟检测到错误的时间。
如果栈顶是终结符,当出错时,直接将栈顶出栈


第一张是第一遍做的,写follow集的时候总是出错,原因是对follow集的定义不熟悉,预测分析表也不太会,还有就是LL(1)型文法的判断,第二张图片是后来又做了一遍。第一遍做完以后又看了遍课本,还是要上课好好听的,不然看课本也是看不明白的。血的教训啊!