软件工程 编译原理 第五章 自顶向下的语法分析方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
PROCEDURE T; BEGIN F;T END PROCEDURE T; IF SYM=‘*’ THEN BEGIN ADVANCE; F;T END;
例:文法G(E):
E→TE E→+TE | T→FT PROCEDURE F; T→*FT | IF SYM=‘i’ THEN ADVANCE F→(E) | i ELSE 对应的递归下降子程序为: IF SYM=‘(’ THEN
文法中不含左公共因子只是LL(1)文法的必要条件。
值得注意的是对文法进行提取左公共因子变换后,有时 会使某些产生式变成无用产生式,在这种情况下必须对文法 重新压缩(或化简) 例3:若文法G的产生式为: (1) S→aSd (2) S→Ac (3) A→aS (4) A→b 对(1)、(2)提取左公共因子 得: S→aS(d|c) 引入新非终结符A′后为: (1) S→aSA′ (2) S→bc (3) A′→d|c (4) A→aS (5) A→b
第5章 自顶向下的语法分析方法
语法分析的作用是识别由词法分析给出 的单词符号序列是否是给定文法的正确句 子(程序)。 目前语法分析常用的方法有: 1、自顶向下(自上而下)分析 2、自底向上(自下而上)分析
5.3非LL(1)文法到LL(1)文法的等价转换
确定的自顶向下分析要求给定语言的文法必
须是 LL(1)形式。然而,不一定每个语言都是 LL(1)文法,对一个语言的非LL(1)文法是否能变
同样分别用(4)、(5)产生式的右部替换(3)中右部的 A、B再提取左公共因子最后结果得: (1) S→aS′ (2) S→dp|eq (3) S′→aS″ (4) S′→dpp|eqq (5) S″→Appp|Bqqq (6) A→aAp|d (7) B→aBq|e
可以看出若对(5)中产生式A、B继续用(6)、(7)产 生式的右部替换,只能使文法的产生式愈来愈多无限 增加下去,但不能得到提取左公共因子的预期结果。
2. 消除左递归
设一个文法含有下列形式的产生式。 直接左递归 1)A→Aβ A∈VN,β∈V* 间接左递归 2)A→Bβ B→Aα A,B∈VN,
α,β∈V*
一个文法是左递归时不能采用自顶向下分析法。
2、消除左递归
(1)直接消除产生式中的左递归:假定关于非终结 符P的规则为:
P→P |
例 考虑文法G(S)
S→Qc|c Q→Rb|b R→Sa|a
令它的非终结符的排序为R、Q、S。 对于R,不存在直接左递归。 把R代入到Q的有关候选后,把Q的规则 变为 Q→Sab | ab | b
例 考虑文法G(S)
S→Qc|c Q→Rb|b R→Sa|a
令它的非终结符的排序为R、Q、S。 Q的规则变为 Q→Sab | ab | b 现在的Q不含直接左递归,把它代入到S 的有关候选后,S变成 S→Sabc | abc | bc | c
PROCEDURE E; BEGIN T;E END; PROCEDURE E; IF SYM=‘+’ THEN BEGIN ADVANCE; T;E END
例:文法G(E):
E→TE E→+TE | T→FT T→*FT | F→(E) | i 对应的递归下降子程序为:
例:若文法G4的产生式为: (1) S→Ap|Bq (2) A→aAp|d (3) B→aBq|e
对(1)提取左公共因子得: S→a(App|Bqq) 再引入新非终符S′结果 用(2)、(3)产生式的右部替换 得等价文法为: (1) S→aS′ (1)中产生式的A、B使文法变 (2) S→dp|eq 为: (3) S′→App|Bqq (1) S→aApp|aBqq (4) A→aAp|d (2) S→dp|eq (5) B→aBq|e (3) A→aAp|d (4) B→aBq|e
其中不以P开头。
可以把P的规则等价地改写为如下的非直接左递归 形式: 左递归变 P→P 右递归 P→P|
一般而言,假定P关于的全部产生式是 P→P1 | P2 | … | Pm | 1 | 2|…|n 其中,每个都不等于,每个都不以P开头 那么,消除P的直接左递归性就是把这些规则改写 成:
消除左递归后得: B→(aBc|d)B′ B′→bcB′|ε 再把原来其余的产生式 A→aB,A→Bb加入,最终 文法为: (1) A→aB (2) A→Bb (3) B→(aBc|d)B′ (4) B′→bcB′|ε 可以检验改写后的文法 不是LL(1)文法。
(3)消除间接左递归的算法
把文法G的所有非终结符按任一种顺序排列成P1, P2,…,Pn;按此顺序执行; II. FOR i:=1 TO n DO BEGIN FOR j:=1 TO i-1 DO 把形如Pi→Pj的规则改写成 Pi→1|2|…|k ; (其中Pj→1|2|…|k是关于Pj的所有规则) 消除关于Pi规则的直接左递归性 END III. 化简由2所得的文法。去除那些从开始符号出发永 远无法到达的非终结符的产生规则。 I.
用产生式(3)、(4)中右部 替换产生式(2)中右部的 A,文法变为: (1) S→aSd (2) S→aSc 显然,原文法G3中非终结符A变成不 (3) S→bc 可到达的符号,产生式(4)、(5)也就 (4) A→aS 变为无用产生式,所以应删除。 (5) A→b
此外也存在某些文法不能在有限步骤内提取完 左公共因子。
P→1P | 2P |… | mP |
(2)消除间接左递归
对于间接左递归的消除需先将间接左递归变为直接左 递归,然后再按a)消除直接左递归。
例:文法G为例: (1) A→aB (2) A→Bb (3) B→Ac (4) B→d 用产生式(1)、(2)的右部 代替产生式(3)中的非终 结符A得到左部为B的产 生式为: (1) B→aBc (2) B→Bbc (3) B→d
例1:若文法G的产生式为: (1) S→aSb (2) S→aS (3) S→ε 请提取文法中的左公因子
对产生式(1)、(2)提取左公因子后得: S→ aS(b|ε) S→ε 进一步变换为文法G′: S→aSA A→b A→ε S→ε
例2:若文法G的产生式为: (1) A→ad (2) A→Bc (3) B→aA (4) B→bB 请提取文法中的隐式左公因子。 对文法G2分别用(3)、(4)的右 部替换(2)中的B,可得: 提取产生式(1)、(2)的左 (1) A→ad 公共因子得: (2) A→aAc A→a(d|Ac) (3) A→bBc A→bBc (4) B→aA B→aA (5) B→bB B→bB
例:文法G(E):
E→TE E→+TE | T→FT T→*FT | F→(E) | i
每个非终结符有对应的子程序的定义, 首先在分析过程中,当需要从某个非终 结符出发进行展开(推导)时,就调用这 个非终结符对应的子程序。
例:文法G(E):
E→TE E→+TE | T→FT T→*FT | F→(E) | i 对应的递归下降子程序为:
左递归 变 右递归
P→1P | 2P | … | nP P→1P | 2P |… | mP |
例 文法G(E): E→E+T | T T→T*F | F F→(E) | i
经消去直接左递归后变成: E→TE E→+TE | P→P1 | P2 | … | Pm | 1 | T→FT 2|…|n T→*FT | P→1P | 2P | … | nP F→(E) | i
例2:若文法G的产生式为: (1) A→ad (2) A→Bc (3) B→aA (4) B→bB 请提取文法中的隐式左公因子。 提取产生式(1)、(2)的左公 引进新非终结符A′,后得 G′为: 共因子得: (1) A→aA′ A→a(d|Ac) (2) A→bBc A→bBc (3) A′→d B→aA (4) A′→Ac B→bB (5) B→aA (6) B→bB
百度文库
1、提取公共左因子 方法:假定关于A的规则是: A→ 1 | 2 | …| n | 1 | 2 | … | m (其中,每个 不以开头)
那么,可以把这些规则改写成 A→A | 1 | 2 | … | m A→ 1 | 2 | … | n
经过反复提取左因子,就能够把每个非终结符(包括 新引进者)的所有候选首符集变成为两两不相交。
例 考虑文法G(S)
S→Qc|c Q→Rb|b R→Sa|a
S变成
S→Sabc | abc | bc | c 消除S的直接左递归后: S→abcS | bcS | cS S→abcS | Q→Sab |ab | b R→Sa|a
例 考虑文法G(S)
S→Qc|c Q→Rb|b R→Sa|a
消除S的直接左递归后: S→abcS | bcS | cS S→abcS | Q→Sab |ab | b R→Sa|a 关于Q和R的规则已是多余的,化简为: S→abcS | bcS | cS S→abcS | (4.4)
注意,由于对非终结符排序的不同,最 后所得的文法在形式上可能不一样。但 不难证明,它们都是等价的。 例如,若对文法(4.3)的非终结符排序选 为S、Q、R,那么,最后所得的无左递 归文法是: S→Qc | c Q→Rb | b R→bcaR | caR |a R (4.5) R→ bca R | 文法(4.4)和(4.5)的等价性是显然的。
由上面所举例子可以说明以下问题:
① 不一定每个文法的左公共因子都能在有限的步骤内 替换成无左公共因子的文法,上面文法G4就是如此。 ② 一个文法提取了左公共因子后,只解决了相同左部 产生式右部的FIRST集不相交问题,当改写后的文法 不含空产生式,且无左递归时,则改写后的文法是 LL(1)文法,否则还需用LL(1)文法的判别方式进行判 断才能确定是否为LL(1)文法。
BEGIN ADVANCE; E; IF SYM=‘)’ THEN ADVANCE ELSE ERROR END ELSE ERROR;
主程序: PROGRAM PARSER; BEGIN ADVANCE; E; IF SYM <>’#’ THEN ERROR END;
对应的递归下降子程序为:
E→TE | BC
PROCEDURE E; BEGIN IF SYM FIRST(TE’) THEN T;E ELSE IF SYM FIRST(BC) THEN B; C ELSE ERROR END;
E→TE
E→+TE | T→FT T→*FT | F→(E) | I 对应的递归下降子程序为:
5.5确定的自顶向下分析
5.5.1、递归下降分析程序 不带回溯的自上而下分析器 分析程序由一组递归过程组成,文法中每个非终 结符对应一个过程;所以这样的分析程序称为递 归下降分析器。(因为文法的定义通常是递归的)

几个全局过程和变量: ADVANCE,把输入串指示器IP指向下一个输 入符号,即读入一个单字符号 SYM,IP当前所指的输入符号 ERROR,出错处理子程序
换为等价的LL(1)形式以及如何变换是我们讨论
的主要问题。由LL(1)文法的定义可知若文法中 含有左递归或含有左公共因子,则该文法肯定不 是LL(1)文法,因而,我们设法消除文法中的左 递归,提取左公共因子对文法进行等价变换。
1、提取公共左因子
若文法中含有形如:A→αβ|αγ的产生式,这导 致了对相同左部的产生式其右部的FIRST集相交, 也就是 SELECT(A→αβ)∩SELECT(A→αγ) ≠ φ ,不满足 LL(1)文法的充分必要条件。
相关文档
最新文档