语法分析是编译过程的核心部分。它的任务是在词法分析识别出单词符号串的基础上,分析并判定程序的语法结构是否符合语法规则。
1、语法分析器
语法分析器的工作本质上就是按文法的产生式,识别输入符号串是否为一个句子。
判断方法:自上而下的分析、自下而上的规约
本章主要介绍自上而下分析法。
2、自上而下分析
自上而下分析的主旨是对任何输入串,试图用一切可能的办法,从文法开始符号(根结)出发,自上而下的为输入串建立一棵语法树。或者说,为输入串寻找一个最左推导。
自上而下分析面临的问题:
1、文法的左递归问题。2、回溯的不确定性,要求我们将已经完成工作推倒从来。3、虚假匹配的问题。4、不能准确地确定输入串中出错的位置。5、效率低。
3、LL(1) 分析法
【1】(消除直接左递归的方法)
设有产生式:P→Pα1|Pα2|…|Pαm|β1|β2|…|βn,其中每个βi不以P开头,每个αi不为ε
消除P的直接左递归性就是把这些规则改写成: P→β1P’|β2P’|…|βnP’ P’→α1P’| α2P’|…|αmP’| ε
【2】(消除间接左递归的方法)
(1) 将间接左递归改造为直接左递归。将文法中所有如下形式的产生式:
Pi →Pjγ|β1|β2|…|βn Pj→δ1|δ2|δ3|…|δk
改写成: Pi →δ1γ|δ2γ|δ3γ|…|δkγ|β1|β2|…|βn
(2)消除直接左递归
P→ β1P'| β2P'|...| βnP' P'→ α1 P'| α2 P'|...|αm P'| ε
(3)化简改写后的文法,即去除那些从开始符号出发却永远无法到达的非终结符的产生规则。
【3】(消除回溯)
定义FIRST集:令文法G是不含左递归的文法,对G的非终结符的候选α,定义它的开始符号(终结首符)集合:
特别地,如果α=》ε,则ε∈FIRST(α)。
如果非终结符A的任意两个候选式αi和αj的开始符号集满足FIRST(αi)∩FIRST(αj)=Φ,则A可以根据所面临的第一个输入符号,准确地指派一个候选式α去执行任务,α是那个FIRST集含a的候选式,即 a ∈FIRST(α)。
提取公共左因子:
假设A的产生式为:A→δβ1|δβ2|…|δβn|γ1| γ2|…|γm,其中每个γ不以δ开头,那么把这些产生式改写为: A→δA’ |γ1| γ2|…|γm A’→β1|β2|…|βn。
反复提取左因子(包括对新引进的非终结符,例如A’)。
【4】(FOLLOW集)
对文法G的任何非终结符A,定义它的后继符号集合:
特别地,如果S=*》…A,则#∈FOLLOW(A)。
FOLLOW(A)集合是所有句型中出现在紧接A之后的终结符号或#所组成的集合。
当非终结符A面临输入符号a,且a不属于A的任意候选式的FIRST集但A的某个候选式的FIRST集包含ε时,只有当a ∈FOLLOW(A),才可能允许A自动匹配。
【5】(不带回溯的自上而下分析的文法条件(LL(1)文法))
(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个符号)。
4、递归下降分析程序构造
当一个文法满足LL(1)条件时,我们就可以构造一个不带回溯的自上而下分析程序,这个分析程序由一组(可能的)递归程序组成,每个过程对应文法的一个非终结符。这样一个分析程序称为递归下降分析器。
具体做法:对文法的每一个非终结符都编一个分析程序。当根据文法和当时的输入符号预测到要用某个非终结符去匹配输入串时,就调用该非终结符的分析程序。
5、预测分析程序
预测分析表的构造:
1. FIRST(X)
1)若X终结符,则FIRST(X)={X}
2)若X为非终结符,且有X->a …的产生式,则把a加入到FIRST(X)中;
3)若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)中
2. FOLLOW(X)
1)对于文法的开始符,置#于FOLLOW(S)中
2)若A->αBβ, 则把FIRST (β)-ε加入到FOLLOW(B)中,
3)若A->αB 是一个产生式,或 A->αBβ是一个产生式,而β-> ε,则把FOLLOW(A)加入到FOLLOW(B)中
3. 预测分析表的构造
对文法G的每个产生式, A->α,进行下面的处理
1)对每个终结符a,如果a属于FIRST(α),则把该产生式写入到M[A,a]
2) 若ε属于FIRST(α),则对任何b属于FOLLOW(A), 把该产生式加入到M[A,b]
3)所有无定义的M[A,a]标上出错标志
结论:一个文法G的预测分析表不含多重入口,当且仅当该文法是LL(1)
6、错误恢复
跳过输入串中的一些符号,直到遇到同步符号。遇到同步符号时,将符号栈顶的非终结符出栈。将FOLLOW(A)设为同步符号。将FIRST(A)加入到同步符号。如果非终结符产生空串,可以自动匹配,以推迟检测到错误的时间。如果栈顶是终结符,当出错时,直接将栈顶出栈。
课后习题:
小结:
每一章在最后反思的时候总会发现自己在学习中存在的不足。这一章题目中的知识点集中在求FIRST集,FOLLOW集以及预测分析表,虽然有关知识学到了,但是真正到自己运用来做题的时候还是有些“坎坷”,这也是对知识掌握不熟练的表现。虽然对这一章进行了总结,但是还要抽一些时间再看回顾一下所学知识。