当前位置:文档之家› 编译原理(3)语法-4(自顶向下语法分析:LL(1)分析法)

编译原理(3)语法-4(自顶向下语法分析:LL(1)分析法)

② 若有X→Y…,且Y∈VN,则将FIRST(Y)中的所有非ε元素(记 为“\{ε}”)都加入到FIRST(X)中; 若有X→Y1Y2…Yk,且Y1~Yi都是非终结符,而Y1~Yi的候选 式都有ε存在,则把FIRST(Yj)(j=1, 2, …, i)的所有非ε元素都加 入到FIRST(X)中; 特别是当Y1~Yk均含有ε产生式时,应把ε也加到FIRST(X)中。
3、若有产生式A →…B,如果存在…Aa…的符号串,可推导得 到…Ba…,因此在这种情况下有FOLLOW(A)⊂FOLLOW(B)
3.3 自顶向下的语法分析
– 关于FIRST与FOLLOW 1、构造FIRST集和FOLLOW集的过程有可能要反复进行多次, 直到每一个非终结符的FIRST集和FOLLOW集都不再增大为止。 2、FIRST集确定了每一个非终结符在扫描输入串时所允许遇到 的输入符号及所应采用的推导产生式(该非终结符所对应的产生 式中的哪一个候选式) 3、FOLLOW集是针对文法中形如“A→ε”这样的产生式的,即 在使用A的产生式进行推导时,面临输入串中哪些输入符号时有 一空字(即ε)匹配而不出错;当然,此时的扫描指针仍指向当前 扫描的输入符号,并不向前推进
重点掌握 LL(1)分析器工作原理 LL(1)分析表的构造 FIRST集合、FOLLOW集合
3.3 自顶向下的语法分析
3.3.2 LL(1)分析法 LL(1)分析法又称预测分析法,是一种不带回溯的非递归自顶 向下分析法。 LL(1)的含义是:第一个L表明自顶向下分析是从左至右扫描 输入串的;第二个L表明分析过程中将用最左推导;“1”表 明只需向右查看一个符号就可决定如何推导(即可知用哪个产 生式进行推导) 类似地,也可以有LL(k)文法,也就是向前查看k个符号才能 确定选用哪个产生式,不过LL(k)(k>1)在实际中极少使用。
(3) 分析表用一个矩阵(或二维数组)M表示,它概括了相应文法 的全部信息。矩阵的每一行与文法的一个非终结符相关联,而 每一列与文法的一个终结符或界符“#”相关联。对M[A, a]来说, A为非终结符,而a为终结符或“#”。分析表元素M[A, a]中的内 容为一条关于A的产生式,表明当A面临输入符号a时,所应该 采用的候选式。
B
B → dB'
B'
B' → bB' B' → ε
[解答] 输入串aadl按控制程序进行的分析过程如表3.2所示。
课本例题3.7
3.3 自顶向下的语法分析
2、LL(1)分析表的构造
– 在表驱动的LL(1)分析器中,除了分析表因文法的不同而异之 外,分析栈、控制程序都是相同的。因此,构造一个文法的表 驱动LL(1)分析器实际上就是构造该文法的分析表。
西北农林科技大学本科教程
第7讲
主讲教师:赵建邦
第三章 语法分析
3.1 文法和语言 3.2 推导与语法树 3.3 自顶向下的语法分析 3.4 自底向上的语法分析 3.5 规范规约的自底向上语法分析方法
本讲目标
第三章《语法分析》 3.3 自顶向下的语法分析 递归下降分析法(上一讲内容) LL(1)分析法
3.3 自顶向下的语法分析
* *
3.3 自顶向下的语法分析
– FIRST集合构造方法
对文法中的每一个非终结符X构造FIRST(X),其方法是连续使 用下述规则,直到每个集合的FIRST不再增大为止。(注:对终 结符a而言,FIRST(‘a’)={a},因而无需构造。)
① 若有产生式 X→a…,且a∈VT,则把a加入到FIRST(X)中; 若存在X→ε,则将ε也加入到FIRST(X)中;
3.3 自顶向下的语法分析
1、表驱动的LL(1)分析器
– LL(1)分析法的基本思想
根据输入串的当前输入符号来惟一确定选用某条规则(产生
式)进行推导;当这个输入符号与推导第一个符号相同时,再取
输入串的下一个符号,继续确定下一个推导应选的规则;如此
下去,直到推导出被分析的输入串为止。
举例:G[A]:A →aBc B → bB | d
3.3 自顶向下的语法分析
– FOLLOW集合构造方法 对文法G[S]的每个非终结符A构造FOLLOW(A)的方法是连续使 用下述规则,直到每个FOLLOW不再增大为止。 ① 对文法开始符号S,置 # 于FOLLOW(S)中(由语句括号“#S#” 中的S# 得到)。 ②若有A→αBβ(α可为空),则将FIRST(β)\{ε}加入到FOLLOW(B) 中;
由F→(E)知FIRST(‘)’) ⊂ FOLLOW(E), 即FOLLOW(E) = {),#};
课本例题3.8
G[E]: E→TE' E'→ + TE' | ε T→FT' T'→*FT' | ε F→(E) | i
③由E→TE' 知FOLLOW(E) ⊂ FOLLOW(E' ), 即FOLLOW(E' ) = {),#};
3.3 自顶向下的语法分析
– 构造分析表M ① 对文法G[S]的每个产生式A→α执行以下②、③步。 ② 对每个终结符a∈FIRST(A),把A→α加入到M[A, a]中,其中 α为含有首字符a的候选式或为惟一的候选式。 ③ 若ε∈FIRST(A),则对任何属于FOLLOW(A)的终结符b,将 A→ε加入到M[A, b]中。 ④ 把所有无定义的M[A, a] 标记为“出错”。
图3-15 LL(1)分析器
1、表驱动的LL(1)分析器
(1) 输入串是待分析的符号串,它以界符“#”作为结束标志。 (注:#∈VT但不是文法符号,是由分析程序自动添加的。)
(2) 分析栈中存放分析过程中的文法符号。分析开始时栈底先 放入一个“#”,然后再压入文法的开始符号;当分析栈中仅 剩“#”,输入串指针也指向串尾的“#”时,分析成功。
课本例题3.8 最后得到文法G[E]的LL(1)分析表如表3.3所示。
表3.3 例3.8的LL(1)分析表
i
+
*
(
)
#
E E→TE'
E→TE'
E'
E'→+TE'
E'→ε E'→ε
T T→FT'
T→ε
T'→*FT'
T'→ε T'→ε
F
F→i
F→(E)
课本例题3.9
例3.9 程序语言中if-else语句的文法G[S]为
M[A, a] 中的产生式右部符号串按逆序逐一压入栈中;如果M[A, a] 中的产生式为A→ε,则只将A自栈顶弹出。
ii.若M[A, a] 中为空,则发现语法错误,调用出错处理程序 进行处理。
1、表驱动的LL(1)分析器
控制程序描述如下:
将“#”和文法开始符依次压入栈中;
把第一个输入符号读入a;
do{
把栈顶符号弹出并放入x中;
if(x∈VT) { if(x==a) {
if(a!=‘#’) 将下一输入符号读入a;
}
else error( ); // 字符串不匹配,语法错误
} else if(M[x,a]=″x→y1y2…yk″) { 按逆序依次把yk、yk−1、…、y1压入栈中; 输出″x→y1y2…yk″; // 显示当前分析所使用的规则
}
else error( );
// 分析表中没有当前产生式,语法错误
} while(x!= ″#″)
课本例题3.7
例3.7 一文法的LL(1)分析表如表3.1所示,试给出输入串aadl的 分析过程。
表3.1 例3.7的LL(1)分析表
a
b
l
d
#
A
A → aA'
A'
A' → ABl
A' → ε
A' → ε
课本例题3.9
G'[S]:S → iESS'| a S' → eS | ε E → b
(2) FIRST集构造: FIRST(S)={i, a};FIRST(S')={e, ε};FIRST(E)={b}。
(3) FOLLOW集构造: ① FOLLOW(S)={#}; ② 由S→…ES… 知FIRST(S)\{ε}⊂FOLLOW(E),即
由E→TE ' 且E ' → ε知FOLLOW(E)FOLLOW(T),即 FOLLOW(T) = {+,),#};
由T→FT ' 知FOLLOW(T)FOLLOW(T‘), 即FOLLOW(T ') = {+,),#};
由T→FT ' 且T ' → ε知FOLLOW(T)FOLLOW(F), 即FOLLOW(F) = {*,+,),#};
– 为了构造分析表M,需要预先定义和构造两族与文法有关的集 合FIRST和FOLLOW
– 关键概念之1:FIRST集合 假定α是文法G[S]的任一符号串(α∈(VT∪VN)*),可定义
FIRST(α) = {a | α * a…, a∈VT}
如果 α * ε,则规定ε ∈FIRST(α)。
也即, FIRST(α)是α的所有可能推导的开头终结符或可能的ε。
G[S]: S → iESeS | iES | a
E → b 其中,e(else)遵从最近匹配原则。试改造文法G[S]并为之构造 LL(1)分析表。
[解答] (1)提取公共左因子后得到文法G‘[S]:
G '[S]: S → iESS' | a
S' → eS | ε
E → b
求出每个非终结符的FIRST集和FOLLOW集。
3.3 自顶向下的语法分析
相关主题