8.第四章自顶向下的语法分析(1)
编译原理-四章自顶向下语法分析法

第四章自顶向下语法分析方法语法分析是编译过程的核心部分。
语法分析的任务是:按照文法,从源程序符号串中识别出各类语法成份,同时进行语法检查,为语义分析和代码生成作准备。
执行语法分析任务的程序称为分析程序。
也称为语法分析器,它是编译程序的主要子程序之一。
在第二章中我们已经介绍过。
通过语法分析可建立起相应的语法树。
按语法树的建立方法,我们将语法分析方法分成两大类,即自顶向下分析和自底向上分析。
下面,我们先介绍自顶向下分析。
本章重点:自顶向下分析、LL(1)分析第一节自顶向下分析方法一、带回溯的自顶向下分析算法这是自顶向下分析的一般方法,即对任一输入符号串,试图用一切可能的方法,从识别符号出发,根据文法自上而下地为输入串建立一棵语法树。
下面用一个简单例子来说明这种过程:假定有文法G[S]:S→cAdA→ab|a 以及输入串w=cad为了自上而下地构造w的语法树,我们首先按文法的识别符号产生根结点S,并让指示器IP指c的规则(此处左部为S的规则仅有一条)( a)(b)(c)图3-1-1图3-1-1a。
我们希望用S的子结从左至右匹配整个输入串w。
首先,此树的最左子结是终结符c为标志的子结,它和输入串的第一个符号相匹配。
于是,我们就把IP调整为指向下一输入符号a,并让第二个子结A去进行匹配,非终结符A有二个选择,我们试着用它的第一个选择去匹配输入串,于是把语法树发展为图3-1-1b。
子树A的最左子结和IP所指的符号相符,然后我们再把IP调为指向下一符号d并让A的第二个子结进入工作。
但A 的第二个子结为终结符号b,与IP当前指的符号d不一致。
因此,A宣告失败。
这意味着A的第一个选择此刻不适用于构造w的语法树。
这时,我们应该回头(回溯)看A是否还有别的选择。
为了实现回溯,我们一方面应把A的第一个选择所生长的子树注销掉;另一方面,应把IP恢复为进入A时的原值,也就是让它重新指向第二输入符号a。
现在我们试探用A的第二个选择,即考虑生成图3-1-1c的语法树。
第4章 自顶向下语法分析方法PPT课件

例4.7 文法G2[A]: A→ad A→Bc B→aA B→bB
1.化为: 2.化为: 3.化为:
A→ad A→a(d|Ac) A→aA'
A→aAc A→bBc A→bBc
A→bBc B→aA
A'→d
B→aA B→bB
A'→Ac例4.8
第1个“L”指的是由左向右地处理输入。 第2个“L”指的是它为输入串描绘出一个最左推导。 括号中的数字1意味着它只需向右看1个符号便可决
定如何推导即选择哪个产生式(规则)进行推导。
4.2 LL(1)文法的判别
求出能推出ε的非终结符 计算FIRST集 计算FOLLOW集 计算SELECT集 判别是否是LL(1)文法
Y到1F..YIRi-S1 T*(X))中,则;把特F别IR是S,T若(Y所j)有中的的F所IR有S非T(Y元j ,素都加
j=1,2,…,K)均含有,则把加到FRIST(X)中.
用关系图法求文法符号的FIRST集(自学)
3.计算FOLLOW集
根据定义计算 1.对于文法的开始符号S,置#于FOLLOW(S) 中; 2.若A→αBβ是一个产生式,则把 FIRST(β)-{}加至FOLLOW(B)中; 3.若A→αB是一个产生式,或A→αBβ是一个产
第一次扫描
是是
否
第二次扫描 是
否
2.计算FIRST集
根据定义计算 1.若XV,则FIRST(X)={X} 2.若XVN,且有产生式Xa…, a∈ V,则 a∈FIRST(X);若X也是一条产生式,则 ∈FIRST(X). 3.若XY…是一个产生式且YVN,则把FIRST(Y) 中的所有非元素都加到FIRST(X)中;若X Y1Y2…YK 是一个产生式,Y1,Y2,…,Yi-1都是非终结 符,而且对于任何j,1≤j ≤i-1,FIRST(Yj)都含有(即
第四章 自顶向下的语法分析-LL(1)

张晶
2011.3
第四章 自顶向下的语法分析
• 4.1 自顶向下语法分析概述 • 4.2 三个重要的集合 • 4.3 递归下降语法分析方法 • 4.4 LL(1)语法分析方法
4.4 LL(1)语法分析方法
LL(1)语法分析方法的主要思想 LL(1)文法 LL(1)分析表 LL(1)分析驱动程序 LL(1)分析程序的自动生成器
(5) T’ * F T’
(6) T’ (7) F (E) (8) F i
{*}
{),+, # } {(} {i}
T’ (6) (5)
F
(9) F n
{n}
4.4 LL(1)语法分析方法
LL(1)语法分析方法的主要思想 LL(1)文法 LL(1)分析表 LL(1)分析驱动程序
如何建立LL(1)分析表?
对于任意的一个LL(1)文法G = (VN, VT, S, P)
VT = {a1, …, an}
VN = {A1, …, Am} LL(Ai, aj) = Ai , 如果ajpredict(Ai ) LL(Ai, aj) = error(), 如果aj 不属于Ai的任何一条产生式 的预测符集
*fmq 开关说明
*define 常数定义部分 *terminals 终极符定义部分 *productions 由空格隔开的若干 (可以是零个)选 择开关
first打印FIRST集合 follow打印FOLLOW集合 parstable打印分析动作表 vocab打印文法符号
text/binary输出表以文本/ <常数名> <无符号整数> 二进制形式表示
LL(1)方法的主要思想
第4章 自顶向下的语法分析

6
分析中出现的问题2:回溯问题
从各种可能的选择中随机挑选一种, 并希望它是正确的。 如果以后发现它是错误的,必须退 回去,再试另外的选择这种方式称为回 溯。 回溯代价极高,效率很低。
7
在自上而下的分析方法中如何选择使 用哪个产生式进行推导? 假定要被替换的最左非终结符号是B, 且有n条规则:B→A1|A2|…|An,那么如何 确定用哪个右部去替代B? 从文法的开始符号出发,如何根据当前 的输入符号(单词符号)唯一地确定选用哪 个产生式替换相应非终结符往下推导,或构 造一棵相应的语法树。
8
§4.2 FIRST和FOLLOW集合的构造
9
例1:输入串w=pccadd是否是合法的句子?
G:S→pA|qB A→cAd|a B→dB|b
S=>pA=>pcAd=>pccAdd=>pccadd 总结:本题中对于一个非终结符,存在若干 个候选式,即产生式形如:P→α1|α2|……|αn 每个候选式的第一个字符都是终结符, 且都不相同。这时可直接选用与当前输入符 号相同的那个候选式来替换P。
42
3. 若X为一非终结符,则查分析表M。 若M[X,a]中为A—产生式,将A自栈 顶弹出,将产生式右部符号串按逆序逐 一推入栈中;当产生式为A时,则只将 A→ε弹出即可。若M[X,a]中为空,则调 用出错处理程序。
43
算法实现
当前字符匹 配成功。 要对栈顶的 非终结符进 行替换。
44
初始化
注意一 定要逆 序入栈。
48
49
通过表4-9可以看到,每个非终结符对应 产生式的各个候选式的交集如下:
可以验证,此文法是LL(1)文法。
50
递归下降语法分析程序如下:
第四章 自顶向下的分析

G[S]:
S→AB|bC 已求出能推出ε的非终结符集为 {A,B,S} A→b|ε B→aD|ε C→AD|b D→aS|c
– ε可能是First 集合的元素,但绝不会出现在 Follow 集合中 – 非终结符、终结符的符号串、非终结符的符 号串都存在First集合, 而Follow 集合仅为非 终结符而定义 – Follow集合的定义运算在产生式的 “右边”, 而 First集合的定义运算在产生式的“左边”
4 按照LL(1)文法的定义判别
3 LL(1) 文法的定义
LL(1) 文法
一个文法是 LL(1) 文法,则需要满足下面 的条件: 每一个产生式 A->α1|α2|…|αn 对于所有 i 和 j,1≤i,j ≤ n,i≠j, First(αi) ∩First(αj) = Φ 对于每一个非终结符 A ,如果 First(A) 中包含ε, 则First(A) ∩Follow(A) = Φ
4.2 LL(1) 文法的判别
LL(1) 文法的判别分为四步: 计算能推出ε的非终结符集 计算每一个产生式的右边串α的 FIRST(α) 集合 计算每个非终结符A的FOLLOW(A) 集合 按照LL(1)文法的定义识别
1. 2. 3.
4.
1计算能推出ε的非终结符集
可空的 当存在一个推导A=>*ε 时,非终结符 A 称作 是可空的。 算法
初值 第一次 第二次
非终结符集 S {A,B} {A,B,S} {A,B,S}
第4章 自顶向下语法分析方法

结论
• 不一定每个文法的左公共因子都能在有限 的步骤内替换成无左公共因子的文法。 • 一个文法提取了左公共因子后,只解决了 相同左部产生式右部的FIRST集不相交问 题,当改写后的文法不含空产生式,且无 左递归时,则改写后的文法是LL(1)文法, 否则还需用LL(1)文法的判别方式进行判断 才能确定是否为LL(1)文法。
2.化为: S→aS(d|c) S→bc A→aS A→b
3.化为: S→aSA' S→bc A'→d A'→c A→aS A→b
结果中A是不可达到的符号。
• 例:文法G4[S] 为: S→Ap|Bq A→aAp|d B→aBq|e
1.化为: S→aApp|aBqq|dq|eq A→aAp|d B→aBq|e
调用返回
• 定义:一个上下文无关文法是LL(1)文法的 充要条件是: 对每个非终结符A的两个不同产生式A→α 和A→β,满足 SELECT(A→α)∩SELECT(A→β)=Φ * 其中α,β不同时能 ε
LL(1)文法的含义:
• 第一个L表示:自顶向下分析是从左向右扫 描输入串。 • 第二个L表示:分析过程中将用最左推导。 • 1表示:只需向右看一个符号便可决定如何 推导(即选择哪个产生式进行推导)。 • 类似也可以有LL(K)文法:需向前查看K个 符号才可确定选用哪个产生式。
S→AB S→bC A→ε A→b B→ε B→aD C→AD C→b D→aS D→c
FIRST(S)=(FIRST(A)-{ε})∪FIRST(B){ε})∪{ε}∪{b}={a,b,ε}
FIRST(A)={b, ε} FIRST(B)={a, ε} FIRST(C)={a,b,c} FIRST(D)={a,c}
4第四章 自顶向下语法分析法1

两类预测分析算法: (1)递归下降分析(recursive-descent parsing)很常 用,且最适合于手写的分析程序最为适合。 (2)LL(1)分析( LL(1) parsing)中第1个“L”指由左向 右地处理输入;第2个“L”指利用最左推导进行分析;括 号中的数字1仅向前查看一个符号进行预测分析。LL(k)分 析利用向前查看k个符号进行预测分析。
+
/\
+5
/\
34 构造过程: (1)对每个运算都实施语法树的生成 (2)对每个递归函数加上当前语法树树根的返回
syntaxTree exp ( )
{
syntaxTree temp, newtemp;
temp = term ( ) ;
while (token == ‘+’ || token = ‘-’){
• 请编写以下表达式文法的递归下降分析程序。
exp → exp addop term | term addop → + | term → term mulop factor | factor mulop → * factor → ( exp ) | number
识别factor → ( exp ) | number的递归下降子程序如下: void factor( ) {
G[E]={E→E+T|T, T→T*F|F, F→(E)|i },
符号串i+i*i自顶向下的分析过程:
• 自顶向下的分析程序有两类: (1)预测分析程序(predictive parser)试图利用超前 查看一个或多个记号来预测出该选择哪条规则。 (2)回溯分析程序(backtracking parser)则试着分析 所有的可能输入,当一种可能失败时就要求输入中备份任 意数量的字符。
编译技术-第4章-语法分析(一)

自顶向下分析 自底向上分析
自顶向下分析算法的基本思想为:
若Z + S 则 S L(G[Z]) 否则 S L(G[Z])
G[Z]
主要问题: ➢ 左递归问题 ➢ 回溯问题
▪ 主要方法: • 递归子程序法 • LL分析法
自底向上分析算法的基本思想为:
第四章 语法分析
• 语法分析的功能、基本任务 • 自顶向下分析法> • 自底向上分析法>
复习:第一章 概述
编译过程是指将高级语言程序翻译为等价的目标程 序的过程。 习惯上是将编译过程划分为5个基本阶段:
词法分析 语法分析 语义分析、生成中间代码 代码优化 生成目标程序
4.1 语法分析概述
功能:根据文法规则,从源程序单词符号串中识别出语法 成分,并进行语法检查。
若有规则:U∷=x|xy 则可以改写为:U∷=x(y|ε) 注意:不应写成U∷=x(ε|y)
使用提因子法,不仅有助于消除直接左递归,而且有 助于压缩文件的长度,使我们能更有效地分析句子。
规则二
若有文法规则:U∷=x|y|……|z|Uv
其特点是:具有一个直接左递归的右部并位于最后, 这表明该语法类U是由x或y……或z其后随有零个 或多个v组成。
若Z + S
G[Z]
则 S L(G[Z]) 否则 S L(G[Z])
主要问题: ➢ 句柄的识别问题
▪ 主要方法: • 算符优先分析法 • LR分析法
4.2 自顶向下分析
4.2.1 自顶向下分析的一般过程
给定符号串S,若预测是某一语法成分,则可根据该 语法成分的文法,设法为S构造一棵语法树, 若成功,则S最终被识别为某一语法成分,即
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
A→ab|a
?句子cad是该文法定义语言的句子
当需要用A派生 时,无法根据输 入符号a唯一的 确定A的候选式
34
c a
A
2015-3-29
候选式的确定与回溯(Backtracking)
给定文法S→cABd A→ab|ε
S S c A B d ε
B→a
?句子cad是该文法定义语言的句子
C
E If a≠0 then if S
T S(非最长) C
E a>0 then S b=1 S else b=-1
三、重要问题——二义性及其消除
S→TS|CS C→if E then T →CS else
S
S
S T (最长) T (最长) C C S
C
C
if E then if E then S else if E then S else if E then S
发现不匹配,需 要回退(回溯)
S x A y
S xAy
x**y
匹配成功
2015-3-29
S
x A y
7
三、重要问题——回溯
x * * y
xAy x*y
发现不匹配,需要回退
S
S x A y
x * * y
S
xAy x**y
匹配成功
S
x A y
2015-3-29
8
三、重要问题——二义性及其消除
E → E + T| T T → T * F|F F → ( E )|id E→ T E’
E ’→ + T E ’| ε
T→ F T’ T’→* F T’|ε F→ ( E )|id
2015-3-29
21
例: 间接左递归的消除
S→Ac|c
A→Bb|b B→Sa|a 将B的定义代入A产生式得:A→Sab|ab|b 将A的定义代入S产生式得: S→Sabc|abc|bc|c 消除直接左递归: S→abcS’|bcS’|cS’ S’→abcS’|ε 删除“多余的”产生式:A→Sab|ab|b和 B→Sa|a 结果: S→abcS’|bcS’|cS’ 2015-3-29 S’→abcS’|ε
E→E+E|E-E|E*E|E/E|(E)|id 对 同 一 句 子存 在两棵语法分析树,哪个是对的?
E E
E
id
Байду номын сангаас
+ E
id
E
* E id
E E
id + E
*
E
id
2015-3-29
id
9
三、重要问题——二义性及其消除
二义性文法 E→E+E|E-E|E*E|E/E|(E)|id 非二义性文法 E→E+T|E-T|T T→T*F|T/F|F F→(E)|id 改造方法:引入语法变量,使文法含有更多的信息
当需要用A派生 时,因为A→ε 使得无法根据输 入符号a唯一的 确定A的候选式
35
c A B d a
2015-3-29
b
a
E→E+T|E-T|T|-E T→T*F|T/F|F F→F↑P|P P→(E)|id|const|FUN(L) FUN→ abs | sin | cos | ln | log | exp | sqrt L→E|E,L
VN={E,T,F,P,FUN,L} VT={id,const,+,-,*,/,(,), \,, abs,sin,cos,log,ln,exp,sqrt} S= E 2015-3-29 19
EE+E a1+E a1+E*E a1+a2*E a1+a2*a3
EE+E E+E*E E+E*a3 二义性(先天二义性语言、二义性文法) E+a2*a3 a1+a2*a3
2015-3-29 6
三、重要问题——虚假匹配
S xAy
输入串x**y
S→xAy A→**|* x*y
E
a>0 then
M
b=1 else
M
b=-1
按照“改造2”构造的语法树
S→TS|CS C→if E then T →CS else
C S
S T(最长)
C
E
If a≠0 then
E
if a>0 then
S
b=1
S
else b=-1
按照“改造2”构造的语法树
S→TS|CS C→if E then T →CS else
22
消除左递归的一般方法
对产生式组
A→Aα1|Aα2|…|Aαn|β1|β2|…|βm
用如下产生式组替换
Aβ1 B|β2 B |…|βm B Bα1 B|α2 B |…|αn B|ε 其中:B为新变量,相当于A’
消除左递归的算法见P70的算法
为非终结符编号,再采用代入法将间接左递归变 为直接左递归,消除直接左递归
11
一个句子有两棵不同的语法树
S S E E S If a≠0 then if a>0 then b=1 else S S E If a≠0 then if E S S a>0 then b=1 else b=-1 S b=-1
三、重要问题——二义性及其消除
1.重写文法
S→U|M U→if E then S U→if E then M else U M→if E then M else M|other S→TS|CS C→if E then T →CS else 2015-3-29
2015-3-29
10
三、重要问题——二义性及其消除
再例:If语句 S→if E then S S→if E then S else S S→other 设执行下列语句前b=0, If a≠0 then if a>0 then b=1 else b=-1 当a=1时,b=1;当a=-1时,执行后b=-1 If a≠0 then if a>0 then b=1 else b=-1 当a=1 时,b=1;当a=-1时,执行后b=0 2015-3-29
自动机识别语言
自顶向下
算符优先分析法
Bottom Up LR(0)、SLR(1)[LR(1)、LALR]
2015-3-29 4
自底向上
4.2 自顶向下分析面临的问题与CFG 的改造
一、自顶向下的分析 从文法的开始符号出发,寻求所给的输入符 号串的最左推导 从树根S开始,构造所给输入符号串的语法树 例:G为:S→xAy A→**|*,输入串:x**y
三、重要问题——左递归及其消除
无法根据左递归文法进行自顶向下的分析 A a1a2……ai……an 直接左递归
A Aα
当前变量
输入指针
(栈顶、最左变量)
间接左递归 A+Aα
左递归的消除方法
将A→Aα
2015-3-29
|β 替换为A→β A′ 和 A′→α A′|ε
20
例:表达式文法直接左递归的消除
2015-3-29
32
候选式的确定与回溯(Backtracking)
给定文法S→cAd A→ab|e S c A e d 当需要用A派生时, 可以根据输入符号e唯 一的确定A的候选式
33
?句子ced是该文法定义语言的句子
2015-3-29
候选式的确定与回溯(Backtracking)
给定文法S→cAd
第 4章 自顶向下的语法分析 ( 1)
语法分析(Syntax Analysis) 文法的改造问题 自顶向下(Top Down)的分析 推导(Derivation)
2015-3-29 1
4.1 语法分析的任务
语法分析(Syntax Analysis)
检查扫描器输出的单词序列是否符合该语 言的文法(句子),并分析组成此句子的语法 成分 Parser Syntax Analyzer
2015-3-29 24
三、重要问题——提取左因子
将形如
A→αβ1|αβ2|…|αβm |γ1|γ2|… | γp
的规则改写为
A→αA' |γ1|γ2|… | γp和 A'→β1|β2|…|βm
结果:
S→ if E then SS’|other S'→ε|else S
2015-3-29
S→TS|CS|other C→if E then T →CS else
E → T E’ E ’→ + T E ’| ε T → F T’ T’→ * F T’|ε F → ( E )|id
候选式的确定与回溯(Backtracking)
给定文法S→cAd A→ab|e S c a A b d 出现一次虚假的匹配, 并且立即发现cad不是 合法句子
?句子cad是该文法定义语言的句子
对于不同的文法,可用不同的分析方法
多用于编译的手工实现 多用于编译的自动生成
27
LR文法 ── LR分析法
2015-3-29
4.3 自顶向下的分析方法
基本思想
寻找输入符号串的最左推导 试图根据当前输入单词确定使用哪个产生式
基本过程
从S出发,构造输入符号串(Token)的最左派生 从根开始,按与最左推导相对应的顺序,构造 输入符号串(Token)的语法分析树