编译原理-第四章 语法分析
合集下载
编译原理语法分析(3)_ 习题

来消除左递归。由此,将产生式B→Bb|d改造为 B→dB′ B′→bB′| ε
其次,应通过提取公共左因子的方法来消除G[A]中的回 溯,即将产生式A→aABl|a改造为 A→aA′ A′→ABl | ε
最后得到改造后的文法为 G[A′]:A→aA′ A′→ABl | ε B→dB′ B′→bB′| ε
S ( L) L, S S ( L)
S a
图4-5 句型(S,(a))的语法树
(2) 由图4-5可知: 短语:S、a、(a)、S,(a)、(S,(a)); 直接短语:a、S; 句柄:S; 素短语:素短语可由图4-5中相邻终结符之间的优 先关系求得,即:
#⋖ (⋖,⋖ (⋖a⋗)⋗)⋗# 因此,素短语为a。
D
D
TL
TL
int a L′
int L , c
, b L′
L, b
, c L′
a (a)
(b)
图4-6 两种文法为int a,b,c构造的分析树 (a) 文法G(D); (b) 文法G′(D)
3.9 考虑文法G[S]: S→(T) | a+S | a T→T,S | S
消除文法的左递归及提取公共左因子,然后对每 个非终结符写出不带回溯的递归子程序。
优先关系表构造方法: ① 对P→…ab…或P→…aQb…,有ab; ② 对P→…aR…而b∈FIRSTVT(R),有a⋖b; ③ 对P→…Rb…而a∈LASTVT(R),有a⋗b。 解之无①。 由②得:E→…+T,即+⋖FIRSTVT(T),有+⋖*,+⋖i;
T→…*P,即*⋖FIRSTVT(P),有*i。 由③得:E→E+…,即LASTVT(E)⋗+,有+⋗+,*⋗+, i⋗+;
编译原理 第4章1

4.2.2 文法的左递归性和回 溯的消除
第二种情况: 文法中相同左部的规 则,其中某一右部能推出ε串,例如, 文法G: A→ Bx B→ x |ε 其非终结符B有两个右部,第二个右 部能推导出ε串且两个右部左端第一 个符号不相同,但在分析符号串 W=x 时出现回溯。
4.2.2 文法的左递归性和回 溯的消除
FIRST(α) SELECT(A→ α) = FIRST(α)/{ε}∪FOLLOW (A) * 若αε
* 若α / ε
LL(1)文法的判断条件
例 设有文法G[A]: A→aB | d B→bBA | ε
SELECT(A→aB ) = FIRST(aB) = { a } SELECT(A→d ) = FIRST(d) = { d }
LL(1)文法的判断条件
为了建立LL(1)文法的判断条件,需引 进三个相关集: FIRST集
FOLLOW集
SELECT集
LL(1)文法的判断条件
(1) 设α是文法G的任一符号串,定义文 法符号串α的首符号集合。 * FIRST(α) = { a | α a…且 a∈V }
T
* ε ,则规定 ε∈ FIRST(α) 若α
4.2.2 文法的左递归性和回 溯的消除
2. 回溯的消除 在自上而下分析过程中,由于回 溯,需要推翻前面的分析,包括已做 的一大堆语义工作,重新去进行试探, 这样大大降低了语法分析器的工作效 率,因此,需要消除回溯。
4.2.2 文法的左递归性和回 溯的消除
我们分析发现引起回溯的原因是: 在 文法中,当某个非终结符A有多个候选式时: A → α1 | α2 | α3 |∙∙∙∙∙∙| αn
LL(1)文法的判断条件
S → aAb A → de | d ∵ SELECT(A→de)= FIRST(de)={d} SELECT(A→d)= FIRST(d)={d} ∴ SELECT(A→de)∩SELECT(A→d) ≠Φ
编译原理第四章

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的后随终结符号来匹 配
《编译原理教程》第四章语义分析和中间代码生成

控制流分析和数据流分析案例
总结词
控制流分析和数据流分析是编译器设计中两种重要的 语义分析技术。
详细描述
在控制流分析案例中,我们以一个具有条件语句和循环 的程序为例,分析其控制流图(Control Flow Graph, CFG)。CFG是一个有向图,用于表示程序中各个基本块 之间的控制流程关系。通过CFG,编译器可以检测到潜 在的程序错误,如死代码和无限循环。在数据流分析案 例中,我们使用数据流方程来跟踪程序中变量的值在执 行过程中的变化。我们以一个简单的程序为例,该程序 包含一个变量在函数调用后被修改的情况。通过数据流 分析,我们可以确定变量的最新值,以便在后续的语义 分析中使用。
定义
三地址代码是一种中间代码形式,它由一系列的三元组操作数和 操作符组成。
特点
三地址代码具有高度规范化,易于分析和优化,且易于转换成目 标代码。
常见形式
常见的三地址代码有三种基本形式,即加法、减法和赋值。
循环优化
定义
循环优化是指在编译过程中,对循环结构进行优化, 以提高目标代码的执行效率。
常见方法
将源程序分解成一个个的词素或标记。
语法分析
根据语言的语法规则,将词素或标记组合成一个个的语句或表达式。
语义分析
对语法分析得到的语句或表达式进行语义检查,确保其语义正确。
中间代码生成
基于语义分析的结果,生成中间代码。
02
语义分析技术
类型检查
类型检查是编译过程中对源代码进行语义分析的重要环节,其主要目的是 确保源代码பைடு நூலகம்类型安全。
常见的循环优化方法包括循环展开、循环合并、循环 嵌套等。
优化效果
通过循环优化,可以减少循环的次数,提高程序的执 行效率。
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
编译原理 第四章自顶向下语法分析法

若b不∈FIRST(αi),其中i=1~n,则语法错,转出错处理。这样就避免了分析过程的回溯。
若文法的任一非终结符号,其规则右部的各个选择所能推出的终结符号串的头符号集合不满足两两相交的条件时,那么,要构造一个不带回溯的自顶向下的语法分析程序,需要采取什么措施呢?一般可采取改写文法的办法来解决。
(三)改写文法当文法不满足,可改写文法
对每一文法符号X∈V计算FIRST(X)。
(a)若X∈VT,则FIRST(X)={x}
(b)若X∈VN,且有产生式X→a…,a∈FIRST(X)。
(c)若X∈VN,X→ε,则ε∈FIRST(X)。
(d)若X∈VN,Y1,Y2,…,Yi都∈VN,而有产生式X→Y1Y2…Yn。当Y1,Y2,…,Yi-1都 ε时,(其中1≤i≤n),则FIRST(Y1)-{ε},FIRST(Y2)-{ε},…,FIRST(Yi-1)-{ε},FIRST(Yi)都包含在FIRST(X)中。
二、存在问题及解决办法
(一)左递归问题
自顶向下分析法只有规则排列得合适时,才能正确工作。该法的一个基本缺点是不能处理具有左递归的文法。如下所示。
如:直接左递归和间接左递归
无法确定语法树的终止,
清除直接左递归的较好方法是改
为右递归
如:S→Sa|b改为
S→bS′
S′→aS′|ε
一般情况下,直接左递归的形式可为:
为了自上而下地构造w的语法树,我们首先按文法的识别符号产生根结点S,并让指示器IP指
向输入串的第一符号c。然后,用S的规则(此处左部为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是否还有别的选择。
若文法的任一非终结符号,其规则右部的各个选择所能推出的终结符号串的头符号集合不满足两两相交的条件时,那么,要构造一个不带回溯的自顶向下的语法分析程序,需要采取什么措施呢?一般可采取改写文法的办法来解决。
(三)改写文法当文法不满足,可改写文法
对每一文法符号X∈V计算FIRST(X)。
(a)若X∈VT,则FIRST(X)={x}
(b)若X∈VN,且有产生式X→a…,a∈FIRST(X)。
(c)若X∈VN,X→ε,则ε∈FIRST(X)。
(d)若X∈VN,Y1,Y2,…,Yi都∈VN,而有产生式X→Y1Y2…Yn。当Y1,Y2,…,Yi-1都 ε时,(其中1≤i≤n),则FIRST(Y1)-{ε},FIRST(Y2)-{ε},…,FIRST(Yi-1)-{ε},FIRST(Yi)都包含在FIRST(X)中。
二、存在问题及解决办法
(一)左递归问题
自顶向下分析法只有规则排列得合适时,才能正确工作。该法的一个基本缺点是不能处理具有左递归的文法。如下所示。
如:直接左递归和间接左递归
无法确定语法树的终止,
清除直接左递归的较好方法是改
为右递归
如:S→Sa|b改为
S→bS′
S′→aS′|ε
一般情况下,直接左递归的形式可为:
为了自上而下地构造w的语法树,我们首先按文法的识别符号产生根结点S,并让指示器IP指
向输入串的第一符号c。然后,用S的规则(此处左部为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是否还有别的选择。
第四章 语法分析2
5
§4.3 自底向上语法分析
一、简单优先文法分析法 1. 与文法有关的一些关系定义 2. 构造文法关系传递闭包 和自反传递闭包 3. 文法优先关系概念 4. 文法优先关系的构造 5. 简单优先文法 6. 简单优先文法分析算法 二、算符优先分析法 1. 算符优先关系概念 2. 算符优先文法 3. 算符优先关系的构造方法 4. 最左素短语 5. 算符优先分析算法 三、优先函数及其构造 1.优先函数定义 2.优先函数矩阵的构造 3.利用优先函数矩阵进行语法分析 四、LR分析法 1. LR分析法一般概述 2. LR分析器工作原理 3. LR(0)分析表构造 4. SLR(1)分析表构造 5. LR(1)分析表构造 6. LALR分析表构造 五、二义性文法的应用 1.问题的提出 2.二义性文法分析表的构造
21
一、简单优先文法分析法
设文法G[A] A∷=Af|B, B∷=DdC|De,
C∷=e,
D∷=Bf
L={(A,A),(A,B),(B,D),(C,e),(D,B)} 根据关系L的值,可作出它的布尔矩阵 BL 如下所示:
A B C BL = D e d f A B C D e d f 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
11
一、简单优先文法分析法
下面我们定义与任何文法有关的几个关系。 (1)V上关系L 设V为已知文法的有穷字汇表,U是任一非终结符,V上 关系L可定义为U L S当且仅当存在规则 U∷=S… 其 中S可以是终结符或非终结符。 或表示成 L={(U,S)|US…,S(VT∪VN )}
编译原理Part4语法分析
ห้องสมุดไป่ตู้
同步符号集的选择
把FOLLOW(A)中的所有符号放入非终结符A的同步符号集。 如果我们跳读一些输入符号直至出现FOLLOW(A)中的同步 符号,把A从栈中弹出来,这样就可能使分析继续下去。 对于非终结符A来说,只用FOLLOW(A)作为它的同步符号 集是不够的。例如,如果分号作为语句的终结符,那么作为 语句开头的关键字就可能不在产生表达式的非终结符的FOL LOW集合中。这样,在一个赋值语句后少一个分号就可能 导致作为下一个语句开头的关键字被跳过
如果非终结符A的所有候选首符集两两不相交,即A的任何 两个不同候选αi和αj
FIRST(αi) ∩FIRST(αj)=Φ
那么当要求A匹配输入串时,A就能根据它所面临的第一个 输入符号a,准确的指派某一个候选前去执行任务。这个候 选就是那个终结首符集含a的α。
消除回溯、提取左因子
提取左因子的方法
假定A的规则是: A→δβ1 |δβ2 | … |δβn |γ1 |γ2 | … |γm
自顶向下分析的简单例子
假定文法G[S],以及输入串x*y(记为α)。
S→xAy
A→**|*
初始化:
S
x*y
IP
第一步扩展
S
x*y
x
A
y
IP
自顶向下分析的简单例子
假定文法G[S],以及输入串x*y(记为α)。
S→xAy
第二步扩展:
S
A→**|*
x*y
x
A
y
IP
**
回溯 S
x*y
x
A
y
IP
*
自顶向下分析方法的特点
通用的语法分析方法,用来分析任何文法,生成编译器时效率 太低 编译器使用的语法分析方法—处理文法的一些子类
同步符号集的选择
把FOLLOW(A)中的所有符号放入非终结符A的同步符号集。 如果我们跳读一些输入符号直至出现FOLLOW(A)中的同步 符号,把A从栈中弹出来,这样就可能使分析继续下去。 对于非终结符A来说,只用FOLLOW(A)作为它的同步符号 集是不够的。例如,如果分号作为语句的终结符,那么作为 语句开头的关键字就可能不在产生表达式的非终结符的FOL LOW集合中。这样,在一个赋值语句后少一个分号就可能 导致作为下一个语句开头的关键字被跳过
如果非终结符A的所有候选首符集两两不相交,即A的任何 两个不同候选αi和αj
FIRST(αi) ∩FIRST(αj)=Φ
那么当要求A匹配输入串时,A就能根据它所面临的第一个 输入符号a,准确的指派某一个候选前去执行任务。这个候 选就是那个终结首符集含a的α。
消除回溯、提取左因子
提取左因子的方法
假定A的规则是: A→δβ1 |δβ2 | … |δβn |γ1 |γ2 | … |γm
自顶向下分析的简单例子
假定文法G[S],以及输入串x*y(记为α)。
S→xAy
A→**|*
初始化:
S
x*y
IP
第一步扩展
S
x*y
x
A
y
IP
自顶向下分析的简单例子
假定文法G[S],以及输入串x*y(记为α)。
S→xAy
第二步扩展:
S
A→**|*
x*y
x
A
y
IP
**
回溯 S
x*y
x
A
y
IP
*
自顶向下分析方法的特点
通用的语法分析方法,用来分析任何文法,生成编译器时效率 太低 编译器使用的语法分析方法—处理文法的一些子类
编译原理 第四章语义分析和中间代码生成
综合属性用于“自下而上”传递信息。 由相应分析树中结点的分支结点属性计算得到。
产 生 式 L E 语 义 规 则 Print(E.val) E.val:=E1.val+T.val E.val:=T.val T.val:=T1.val F.val T.val:=F.val F.val:=E.val F.val:=digit.lexval
几种常见的中间语言
b.三元式的记录结构为:(op,arg1,arg2) 例:求赋值语句a=b*(c+d)的三元式代码: 首先写出这个赋值语句的三地址代码语句为: t1=c+d t2=b*t1 a=t2 再根据三地址代码语句写出三元式代码为: ①(+,c,d) ②(*,b,①) ③(=,a,②)
几种常见的中间语言
例:
id
+ * id id
语法树只反映句型的结构,忽略了推导句型的过程。
几种常见的中间语言
2.逆波兰表示法 a.表达式的逆波兰表示: ①若E是变量或常数,则表示为:E ②若为E1 op E2形式,且 op为二元运算符,则表示为:E1E2op ③若为op E1形式,且 op为一元运算符,则表示为:E1op ④若为(E)形式,则表示为:E 例:a*(b+c)可看成E op (E op E),可写成abc+* (-a)*b+c*d 可写成ab*cd*+
表达式文法
E→T+T| T or T T → n | b
E → T1 + T2 { T1.type = int T2.type= T1.type E.type :=int} E → T1 or T2 { T1.type = bool T2.type= T1.type E.type :=bool} T → n { T.type := int} T → b { T.type := bool}
编译原理作业解析——第四章语法分析[xiwang]
第八次作业P143 4(1)5 P144 6(1)(2) 9
解答:
(1)构造FIRST集: FIRST(E’)={+, ε} FIRST(F’)={*, ε} FIRST(E)=FIRST(T)=FIRST(F)=FIRST(P) ={ (,a,b,∧) FIRST(T’)={ (,a,b, ε,∧} 构造FOLLOW 集: 规则一 #∈FOLLOW(E) FOLLOW(E)={#}
F’→*F’ F’ →ε T’ →T T→FT’ F→PF’ P →b F’ →ε
第八次作业P143 4(1)5 P144 6(1)(2) 9
步骤 分析栈 余留输入串 所用的产生式 15 #E’T’ +b# T’ →ε 16 #E’ +b# E’→+E 17 #E+ +b# 18 #E b# E→TE’ 19 #E’T b# T→FT’ 20 #E’T’F b# F→PF’ 21 # E’T’F’P b# P →b 22 # E’T’F’b b# 23 # E’T’F’ # F’ →ε 24 # E’T’ # T’ →ε 25 #E’ # E’→ε 26 # # 成功 所以符号串a*b+b是该文法的句子;
第七次作业:P142 1(1)(4) P143 2(2)
解答:
先采用‚重复法‛: E::=T{AT} T::=T{MF} F::=(E) | i A::=+ | M::=* | / 再采用“改写法”: E::=TE’ E’::= ATE’ | ε T::=FT’ T’::=MFT’ | ε F::=(E) | i A::=+ | M::=* | /
第八次作业P143 4(1)5 P144 6(1)(2) 9