编译原理 第四章 语法分析
31
4.3.1
FIRST 和 FOLLOW 集
First集的定义 对于α∈(VT∪VN)* 定义:α的首符号集
FIRST(α)={a|α*a…,a∈VT *}
32
求文法非终结符的FIRST集方法
1) 对X为终结符,则FIRST(X)={X} ; 2) 对X∈VN,则FIRST(X): {a|X→a…∈P}; FIRST(X)= X→εP
2
第四章
语法分析
递归子程序法
从根开始,逐 步为某语句构 造一棵语法树
语法分析方法
文法产生语 言
自顶向下 预测分析法(LL(1)) 算符优先分析法
相反,将一句 子归约为开始 符号
Top Down
自动机识别语言
自底向上
Bottom Up LR(0)、SLR(1)[LR(1)、LALR]
假定文法是压缩的:即删除了单位产生式和无用产生式。
1 2 3 4
position initial rate
… … …
temp1 := inttoreal(60) temp2 := id3 *temp1 temp3 := id2 +temp2 id1 := temp3
代码优化器
temp1 := id3 *60.0 id1 := id2 + temp1
E’ T’ ε
id
id
* F T’ id ε
id + id * id的最左推导再现 E TE’ FT’E’ idT’E’ idE’ id+TE’ id+FT’E’ id+idT’E’ id+id*FT’E’ id+id*idT’E’ id+id*idE’ id+id*id E →TE’ T →FT’ F →id T’→ε E’→+TE’ T →FT’ F →id T’→*FT’ F →id T’→ε E’→ε
E’→ + T E’|ε
T→ F T’ T’→* F T’|ε F→ ( E )|id
18
例: 间接左递归的消除
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’ 19 S’→abcS’|ε
23
(8)常用文法与分析方法
LL文法和 LR 文法都是CFG的子集(无二义性)
可用不同的文法来描述同一语言 LL文法 ── 递归下降分析法、预测分析法
对于不同的文法,可用不同的分析方法
LR文法 ── LR分析法
LL 文法多用于编译的手工实现 LR 文法多用于编译的自动生成
24
36
FOLLOW集的定义
例 文法 G (1) S→aBC (2) B→bC (4) B→ ε (5) C→c 请分析句子ada。
文法S→Say|* 与它的句子*ayay
S *
*ayay SSay
不对!
Sayay
Sayayay
一个无限 循环!
9
……
Sayay……ayay
(2)存在问题
例 CFG:简单算术表达式的文法(语法)
E→E+T|E-T|T T→T*F|T/F|F F→(E)|id VN={E,T,F,P,FUN,L} VT={id,+,-,*,/,(,)} S=E
(1)自顶向下的分析 从文法的开始符号出发,寻求所给的输入符 号串的一个最左推导。 从树根S开始,构造所给输入符号串的语法树 例:G为:S→xAy A→**|*,输入串:x**y
SxAy S x
x**y
A
y
6
输入串x**y
(2)存在问题
【1】回溯 x * * y
S→xAy A→**|*
20
(6)解决回溯问题-提取左因子
例:if语句的原始文法
S→ if E then S |if E then S else S |other
影响分析:遇到 if 时难以 判断用哪一个产生式进行 匹配(推导) 存在左因子 if E then S
21
左因子提取方法
将形如
A→αβ1|αβ2|…|αβn |γ1|γ2|… | γm
4.3 自顶向下的入符号串的最左推导 试图根据当前输入单词判断使用哪个产生式
基本过程
从根开始,按与最左推导相对应的顺序,构 造输入符号串(Token)的分析树
25
例1:表达式文法G: E → T E’ E’→ + T E’|ε T → F T’ T’→ * F T’|ε F → ( E )|id 对于句子: id + id * id , 按照最左推导过程, 构造分析树
S xAy x*y
S
xAy x**y
匹配成功
S x A y
发现不匹配,需要回退
x * * y
S x A y
7
存在回溯的原因
文法中每个非终结符A的产生式右部称为 A的候选式,如果有多个候选式左端第一 个符号相同,则语法分析程序无法根据 当前输入符号选择产生式,只能试探。
8
(2)存在问题
【2】左递归问题
FIRST(id)={id}
35
求FIRST(α) 的算法
令α= X1…Xn
初值
FIRST(α)= FIRST(X1)-{ε}; k=1; 循环 while ε∈FIRST(Xk)&k<n do FIRST(α)= FIRST(α)∪(FIRST(Xk+1)-{ε}) ; K=k+1; 结束处理 if k=n&ε∈FIRST(Xk) then FIRST(α)=FIRST(α)∪{ε}
每个else与前面最近的没有配对的then配对,即:出现在then 和else之间的语句必须是配对的
15
按照改造后的文法构造的语法树
M→if E then M else M|other
S U S M
E
If a≠0 then if
E
a>0 then
M
M
b=1 else b= -1
(5)消除左递归
{a|X→a…∈P}∪{ε}; X→ε∈P
33
3)对X∈VN,重复如下过程,直到所有FIRST集不变 若 X→Y…∈P ,且 Y∈VN, 则 FIRST(X)= FIRST(X)∪(FIRST(Y)-{ε}); 若 X→Y1…Yn∈P,且Y1...Yi-1*ε, 则 对k=1到i-1: FIRST(X)= FIRST(X)∪(FIRST(Yk)-{ε}) ; 若 Y1...Yn*ε, 则 FIRST(X)=FIRST(X)∪{ε} 。
(1)候选式的确定与回溯
给定文法S→cAd
S c a A b d
A→ab|a
S c A a d
?句子cad是该文法定义语言的句子
产生式(候选式)的选择与回溯(Backtracking):当要进行关于某个语法 变量的推导时,希望能够根据当前符号确定候选式。如果有几个候选式 (右部)左端第一个符号相同,则分析程序无法根据当前输入符号选择 29 产生式,只能试探。
10
(3)重要概念回顾
推导: αAβαγβ (依据:A→γ) 最左(Left-most)推导——最左分析 左句型 最左推导对应最右归约 最右(Right-most)推导——最右分析 规范推导、规范句型(右句型) 最右推导对应最左归约(规范归约) 二义性(先天二义性语言、二义性文法)
第四章 语法分析
1
回顾 一个语句的翻译
position:= initial + rate * 60
词法分析器
id 1 := id 2 + id 3 * 60
语法分析器
:= id 1 id 2 id 3
语义分析器
+ * 60
:=
符号表
id 1 id 2
+ * id 3 inttoreal 60
中间代码生成器
例2:给定文法G: S→cAd A→ab|a 对于句子cad,是否为 该文法定义语言的句 子?
26
E
T F T’ + ε F E’ T
id + id * id 最左推导与语法树的生成对
1、E→TE’ 2、T→FT' 3、F→id 4、T'→ε 5、E'→+TE’ 6、T→FT’ 7、F→id 8、T'→*FT’ 9、F→id 10、T'→ε 11、E'→ε
无法根据左递归文法进行自顶向下的分析 A a1a2……ai……an 直接左递归
A Aα
当前变量
输入指针
(栈顶、最左变量)
间接左递归 A+Aα 左递归的消除方法 将A→Aα|β替换为A→βA′
和 A′→αA′|ε
17
例:表达式文法直接左递归的消除
E → E + T|T T → T * F|F F → ( E )|id E→ T E’
3
主要内容
4.1 4.2 4.3 4.4 4.5 4.6 4.7
语法分析的功能 自顶向下分析面临的问题与CFG的改造 自顶向下的分析方法 预测分析器(LL(1)分析器) 自底向上分析 LR(Left-Right)分析法 LR(1)分析
编译原理-第4章 语法分析--习题答案
第4章语法分析习题答案1.判断(1)由于递归下降分析法比较简单,因此它要求文法不必是LL(1)文法。
(× )LL(1)文法。
(× )(3)任何LL(1)文法都是无二义性的。
(√)(4)存在一种算法,能判定任何上下文无关文法是否是LL(1) 文法。
(√)(× )(6)每一个SLR(1)文法都是LR(1)文法。
(√)(7)任何一个LR(1)文法,反之亦然。
(× )(8)由于LALR是在LR(1)基础上的改进方法,所以LALR(× )(9)所有LR分析器的总控程序都是一样的,只是分析表各有不同。
(√)(10)算符优先分析法很难完全避免将错误的句子得到正确的归约。
(√)2.文法G[E]:E→E+T|TT→T*F|FF→(E)|i试给出句型(E+F)*i的短语、简单短语、句柄和最左素短语。
答案:画出语法树,得到:短语: (E+F)*i ,(E+F) ,E+F ,F ,i简单短语: F ,i句柄: F最左素短语: E+F3.文法G[S]:S→SdT | TT→T<G | GG→(S) | a试给出句型(SdG)<a的短语、简单短语、句柄和最左素短语。
答案:画出语法树,得到:短语:(SdG)<a 、(SdG) 、SdG 、G 、a简单(直接)短语:G 、a句柄:G最左素短语:SdG4.对文法G[S]提取公共左因子进行改写,判断改写后的文法是否为LL(1)文法。
S→if E then S else SS→if E then SS→otherE→b答案:提取公共左因子;文法改写为:S→if E then S S'|otherS'→else S|E→bLL(1)文法判定:① 文法无左递归② First(S)={if,other}, First(S')={else, }First(E)={b}Follow(S)= Follow(S')={else,#}Follow(E)={then}First(if E then S S')∩First(other)=First(else S)∩First( )=③First(S')∩Follow(S')={else}不为空集故此文法不是LL(1)文法。
编译原理第四章
S→aAb A→c A′
A′ →d|
n
A→α A′ A′ →β 1|β 2|…|β
n
不确定的自顶向下
转化
确定的自顶向下
问题: 回溯 左递归
解决问题: 提取左因子 消除左递归算法
例教材4.2 : SaBC B bC|dB Cc|a 分析句子adbca
思考: BAf|Be 选哪个? 计算Af 和Be 首终结符是 什么?
S S(L) LSL ’ L’ε
)
a
Sa LSL ’
a
A
b
【例4.1】 分析acb 是否句子? G[S]: S→aAb A→cd|c
S · 3. 选第一个Acd推导 a b-d不匹配(失败) c d S · a A c b A b
思考: 为何有 回溯
4.回溯 即砍掉A的子树 改选A的第二右部 Ac 匹配
(1)推导过程是一个不断试探的过程,出现回溯(回退并使用其他候选式试探)
S S
b S
① ②
a
S
b
a
S
S a
③
a
S
S a
a
b
思考:为何 有死循环
(2)陷入死循环
分析时可能出现: (1) 回溯 原因:推导过程中有多个侯选式可供选择 ,并根据所面临 的输入符号不能准确的确定所要选择时,就可能出现回溯。 例4.1
(2) 死循环。例4.2:在没有对当前输入符号匹配就进入处理 S的过程,无法确定什么时候才用Sb替换, 造成死循环. 原因: 左递归
1 3
=>acS
4
=>acaA =>acaA =>aca
1 4 4
当用A ε , A用ε代替,可以通过A的后随终结符号来匹 配
国开电大 编译原理 实验4:语法分析实验报告
国开电大编译原理实验4:语法分析实
验报告
1. 实验目的
本实验的目的是研究和掌握语法分析的原理和实现方法。
2. 实验内容
本次实验主要包括以下内容:
- 设计并实现自顶向下的LL(1)语法分析器;
- 通过语法分析器对给定的输入串进行分析,并输出相应的分析过程;
- 编写测试用例,验证语法分析器的正确性。
3. 实验步骤
3.1 设计LL(1)文法
首先,根据实验要求和给定的语法规则,设计LL(1)文法。
3.2 构建预测分析表
根据所设计的LL(1)文法,构建预测分析表。
3.3 实现LL(1)语法分析器
根据预测分析表,实现自顶向下的LL(1)语法分析器。
3.4 对输入串进行分析
编写程序,通过LL(1)语法分析器对给定的输入串进行分析,并输出相应的分析过程和结果。
3.5 验证语法分析器的正确性
设计多组测试用例,包括正确的语法串和错误的语法串,验证语法分析器的正确性和容错性。
4. 实验结果
经过实验,我们成功设计并实现了自顶向下的LL(1)语法分析器,并对给定的输入串进行了分析。
实验结果表明该语法分析器具有较好的准确性和容错性。
5. 实验总结
通过本次实验,我们对语法分析的原理和实现方法有了更深入的了解。
同时,我们也学会了如何设计并实现自顶向下的LL(1)语
法分析器,并验证了其正确性和容错性。
这对于进一步研究编译原理和深入理解编程语言的语法结构具有重要意义。
6. 参考资料
- 《编译原理与技术》
- 课程实验文档及代码。
编译原理-第4章+语法分析
5
二、语法分析方法
语法分析方法很多,但能够产生计算机程 序并能得到广泛应用的主要有两大类,按 照生成语法树的顺序,分别称为自顶向下 和自底向上分析方法。
6
1.自顶向下语法分析方法
(1)递归下降分析法 (2)LL(1)分析法
7
2.自底向上语法分析方法
(1)简单优先分析法 (2)算符优先分析法 (3)LR分析法
其中全程变量ch中存放了当前输入字符; ERROR 为出错信息 , 表示源程序中语法有错。当 输入符号遇选择项为ε 时,就自动认为获得了 匹配。
42
4)对于符号串x=y1y2…ym,如果yi∈VT,
则P(yi)为 IF ch=yi THEN READ(ch) ELSE ERROR 这就是说,如果当前文法中的符号与输入 符号匹配,则继续读入下一个字符至 ch 中; 否则表明源程序有错。
8
§4.2
自顶向下语法分析
一、消除左递归 二、消除回溯 三、递归下降分析法 四、LL(1)分析法
9Байду номын сангаас
一、消除左递归
(1)问题的提出 在自顶向下分析过程中,假定现在轮到要用非终结 符U去匹配输入串, 而在文法中第一条规则是 U∷=U… 这样会产生什么问题呢?
10
若文法具有间接左递归,即有 U +U … 那么,也会发生上述问题。
16
A
A β α 等价 α α A‟ A‟ A‟ A‟ ε
A A
A β βααα α
α α
βααα
17
就一般而言,关于A的规则具有下面形式: A∷=Aα 1|Aα 2|…|Aα n|β 1|β 2|…|β 这时可改写成如下形式: A∷=A(α 1|α 2|…|α n|) |β
ppt编译原理4章444
4.3 确定的自顶向下分析思想
一、算法思想: 文法特点: (1)每个产生式的 对于任一输入符号串,从文法的识别符号出发,根据 右部都由终结符号开始;(2) 当前的输入符号,唯一的确定一个产生式,用产生式的右 两个产生式若左部相同,则 部的符号串替代相应的非终结符往下推导,或构造一棵语 其右部以不同的终结符号开 始;(3)无空产生式U 法树。若能推导出输入串或构造语法树成功则输入串是句 子,否则不是。 S 二、举例: (1)文法G[S]: SpA |qB AcAd|a 输入串 w=pccadd 对应最左推导:
4.5 非LL(1)文法转换为LL(1)文法
对某个语言来说其文法不一定是LL(1)文法,而非LL(1) 文法将无法采用确定的自顶向下分析方法进行分析,但我 们可以通过对文法进行等价变换,在有些情况下使其成为 LL(1)文法。 一、提取左公共因子: 设文法中有Uxy|xw( UVN, x,y,wV*)形式的产生式,从 而导致了: First(xy)First(xw)=First(x)Ф 因而使: Select(Uxy) Select(Uxw) Ф 1.方法:若有产生式Uxy|xw|…|xz , 则提取左公共因 若在y,w,…,z中仍然有左公 子并用EBNF表示为: Ux(y|w|…|z) 共因子,可以再次提取。 注意,若有:Uxy|x 再引入另一个非终结符号V,将产生式变为: 则提取后:Ux(y|) UxV V y|w|…|z
2.举例: 设有产生式:S→if B then S1 else S2 | if B then S1 其中,S表示两种类型的条件语句。 提取公因子,改成: S→if B then S1 ( else S2 | ) 引入非终结符号R: S→if B then S1 R R→else S2 |ε 文法中,if , then, elseVT
编译原理课件第四章
中间代码生成的过程和方法
过程
中间代码生成是将源代码转换为中间表示形式的过 程,可以使用三地址码等中间代码表示。
方法
中间代码生成可以应用常见的优化技术,如常量折 叠、公共子表达式消除等。
编译优化的基本原理和技术
基本原理
编译优化的基本原理包括消除冗余、提高并行度和改进数据局部性等。
技术
编译优化的常用技术有指令调度、循环优化和内函数等。
编译原理课件第四章
在这一章中,我们将介绍编译原理课件中的第四章内容。我们将探讨编译器 前端和后端的概念,以及它们各自的任务和流程。
编译器前端和后端
1
编译器后端
2
编译器后端负责中间代码生成、代码优 化和目标代码生成等任务。
编译器前端
编译器前端负责词法分析、语法分析和 语义分析等任务。
语法分析器的作用和原理
1 作用
语法分析器用于分析源代码的语法结构,并生成抽象语法树。
2 原理
语法分析器使用文法规则和语法分析算法进行解析,如LL(1)分析和LR分析。
语法制导翻译的概念和实现
概念
语法制导翻译是在语法分析的同时进行翻译,通过 语法规则和语义动作实现。
实现
语法制导翻译可以使用语义动作和符号表等技术来 实现语义分析和中间代码生成。
编译原理_第4章_第3节_LR分析法63页PPT文档
❖ 采用自底向下语法分析方法,在分析过程中的每一步,都会面 对两个关键问题:
(1)如何确定句柄 (2)找出的句柄应规约到哪一个非终结符
解决方法:(移进-规约法) (1)引入一个先进后出的符号栈来存放符号,按照顺序把当前
输入符号入栈(移进),然后查看栈顶符号串是否形成一个句柄。 (2)形成一个句柄时,便对此句柄直接规约,把它代替为相
(s0 s1…sms, #X1X2…Xmai, ai+1…an#)
(2) Action[sm, ai]=rn: {Aβ},且s=Goto[sm-|β|, A],则三元式变为:
(s0 s1…sm-|β|s, #X1X2…Xm-|β|A, aiai+1…an#) (3) Action[sm, ai]=acc,宣布接受,三元式不再变化。 (4) Action[sm, ai]=err,报错,三元式不再变化。
A c
d
3
EaA•
Ac•A A•d A•cA
d Ad•
4A c
5
6 AcA•
例:识别acd
状态栈 0 02
024 0245 0246 023
01 0
活前缀栈 当前符号
#
a
#a
c
#ac
d
#acd
#
#acA
#
#aA
#
#E
#
#S
#
输入串 cd# d# #
0
E
S•E E•aA
a
1
SE•
2 Ea•A A•d A•cA
A c
d
3
EaA•
Ac•A A•d A•cA
d Ad•
4A c
5
6 AcA•
编译原理课件chapter4
三地址代码的生成
总结词
三地址代码是一种常见的中间代码形式,它由一系列的三元 式组成,每个三元式包含一个操作符和两个操作数。
详细描述
三地址代码的生成是编译过程中的一个重要步骤,它通过对 源代码进行语法分析和语义分析,将高级语言转换为一系列 的三元式。这些三元式表示了源代码中的运算和数据传输操 作,可以进一步转换为目标代码。
常见的寄存器分配算法包括基于 图的方法、线性扫描算法和遗传
算法等。
目标代码的生成
01
02
03
04
目标代码的生成通常涉及指令 选择、指令调度和代码优化等
步骤。
指令选择是根据中间代码选择 合适的目标指令的过程,需要 考虑指令集架构、语义等约束
。
指令调度是为了确定指令的执 行顺序,以充分利用处理器资
源并提高指令级并行度。
为了能够处理连续输入的字符流,词 法分析器需要使用一个输入缓冲区来 存储尚未处理的字符。
设计状态转换图
根据正则表达式的规则,可以设计出 一个状态转换图,用于描述如何将输 入的字符转换为相应的词法单元。
词法分析器的实现
编写词法分析器程序
根据状态转换图和输入缓冲区的处理 逻辑,可以编写出相应的词法分析器 程序。
循环展开
将循环体多次执行,减 少循环次数,提高程序
运行效率。
循环优化
通过优化循环结构,减 少循环次数,提高程序
运行效率。
函数内联
将函数调用替换为函数 体中的代码,减少函数
调用的开销。
循环优化
01
02
03
04
循环展开
将循环体多次执行,减少循环 次数,提高程序运行效率。
循环合并
将多个循环合并为一个循环, 减少循环次数,提高程序运行
编译原理 Chapter 4
码生成 支持语言的演化和迭代
3
语法分析器的作用
• 基本作用
– 从词法分析器获得词法单元的序列,确认该序列是否 可以由语言的文法生成
– 对于语法错误的程序,报告错误信息 – 对于语法正确的程序,生成语法分析树 (简称语法树)
• 通常并不真的生产这棵语法分析树
4
语法分析器的分类
• 通用语法分析器
– 可以对任意文法进行语法分析 – 效率很低,不适合用于编表示形式
– 根结点的标号时文法的开始符号 – 每个叶子结点的标号是非终结符号、终结符号或ε – 每个内部结点的标号是非终结符号 – 每个内部结点表示某个产生式的一次应用
• 内部结点的标号为产生式头,结点的子结点从左到右是产生 式的体
• 树的叶子组成的序列是根的文法符号的一个句型 • 一棵语法分析树可对应多个推导序列,但每颗分
18
词法分析和语法分析的比较
阶段
输入
输出
描述体系
词法分析 源程序符号串 词法单元序列 正则表达式
语法分析 词法单元序列 语法树 上下文无关文法
19
上下文无关文法和正则表达式 (1)
• 上下文无关文法比正则表达式的能力更强
– 所有的正则语言都可以使用文法描述 – 但是一些用文法描述的语言不能用正则表达式描述
| other open_stmt if expr then stmt
编译原理 第4章 语法分析—自顶向下分析
例 S::=aABbcd|ε,A::=ASd|ε,B::=SAh|eC|ε,
C::=Sf|Cg|ε,求此文法的每一个非终结符号的
FOLLOW集。
解:FOLLOW(S)={#}∪FIRST(d) ∪(FIRST(Ah)-{ε}) ∪FIRST(f)
={#}∪{d}∪{a,d,h}∪{f} = {a,d,h,f,#}
4)若对于一切1≤i≤n,ε∈FIRST(Xi),则将ε符号加 进FIRST(α)。
例4-1(P62) 有文法: E→TE′ E′→+TE′ E′→ε T→FT′ T′→*FT′ T′→ε F→(E)|i 求文法中非 终结符号以及各 产生式右部符号 串的FIRST集。
解:该文法的非终结符号有E、E′、 T、T′和F。 FIRST(E)=FIRST(TE′) =FIRST(FT′E′)={ ( ,i } FIRST(+TE′)={ + } FIRST(ε)={ε} FIRST(E′)=FIRST(+TE′) ∪FIRST(ε)={+ ,ε} FIRST(T)=FIRST(FT′)={ ( ,i } FIRST(*FT′)={ * } FIRST(T′)=FIRST(*FT′) ∪FIRST(ε)={* ,ε} FIRST((E))={ ( } FIRST(i)={ i } FIRST(F) =FIRST((E)) ∪FIRST(i)={( ,i}
分析法算符优先分析法简单优先分析法优先分析法自底向上带回溯递归下降分析法分析法不带回溯自顶向下语法分析lr回溯示例41p61自顶向下的分析方法就是从文法的开始符号出发按最左推导方式向下推导试图推导出要分析的输开始符号输入符号串自底向上的分析方法从输入符号串开始按最左归约方式向上归约到文法的开始符号
