编译原理-四章自顶向下语法分析法
编译原理-第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)文法。
编译原理-四章自顶向下语法分析法
第四章自顶向下语法分析方法语法分析是编译过程的核心部分。
语法分析的任务是:按照文法,从源程序符号串中识别出各类语法成份,同时进行语法检查,为语义分析和代码生成作准备。
执行语法分析任务的程序称为分析程序。
也称为语法分析器,它是编译程序的主要子程序之一。
在第二章中我们已经介绍过。
通过语法分析可建立起相应的语法树。
按语法树的建立方法,我们将语法分析方法分成两大类,即自顶向下分析和自底向上分析。
下面,我们先介绍自顶向下分析。
本章重点:自顶向下分析、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章习题
(4)构造它的递归下降分析程序。
procedure T ; begin
if sym= ˊ(ˊ or sym= ˊaˊ or sym= ˊbˊ or sym= ˊ∧ˊ then T else if sym= ˊ*ˊ then error end;
(3)该文法不含左递归,而且每一个 非终结符的各个产生式的候选首符集两 两不相交。
FIRST(A)= {a}
FOLLOW(A)={d, #}
FIRST (A) = { ε, a} FOLLOW(A)={d, #}
FIRST(B) = {d} FOLLOW(B )={e}
FIRST(B) = {ε ,b} 法G ’
(S): S → a∣∧∣(T) T → ST ’ T’ → ,ST’ | ε
其中:过程advance把输入串指示器IP调至指向下一个输入 符号;sym是指IP当前所指的那个输入符号;error为出错诊 断处理程序。
(2)经改写后的文法是否是LL(1)的?给出它的预测分析表。
else error end else error end;
4.2 试消除下面文法G[A] 中的左递归,并提取公共左因子, 判断改写后的文法是否为LL(1)文法?
A→aABe∣a
B→Bb∣d
解: (1)首先消除左递归
A→aABe∣a B →dB B →bB | ε (2)提取公共左因子 A → aA A → ABe | ε B → dB B →bB | ε
证明:对于具有形如A|的产生式有: A → ABe | ε B →bB | ε
编译原理 语法分析(2)_ LL(1)分析法1
自底向上分析法
LR分析法的概念 LR分析法的概念 LR(0)项目族的构造 LR(0)项目族的构造 SLR分析法 SLR分析法 LALR分析法 LALR分析法
概述
功能:根据文法规则 文法规则, 源程序单词符号串 单词符号串中 功能:根据文法规则,从源程序单词符号串中
识别出语法成分,并进行语法检查。 识别出语法成分,并进行语法检查。
9
【例】文法G[E] 文法G[E] E→ E +T | T 消除左递归 T→ T * F | F F→(E)|i 请用自顶向下的方法分析是否字 分析表 符串i+i*i∈L(G[E])。 符串i+i*i∈L(G[E])。
E→TE’ E’→+TE’|ε T →FT’ T’→*FT’|ε F→(E)|i
编译程序组织结构
表 处 理
前
端 中
源 程 序
词 法 分 析
语 法 分 析
语 义 分 析
间 代 码 生 成
中 后 目 端 间 标 代 代 码 码 优 生 化 成
目 标 程 序
错 误 处 理
第4章 语法分析
自顶向下分析法
递归子程序法(递归下降分析法) 递归子程序法(递归下降分析法) LL(1)分析法 LL(1)分析法
通常把按LL(1)方法完成语法分析任务的程序叫LL(1)分析程序或者LL(1)分析器。 通常把按LL(1)方法完成语法分析任务的程序叫LL(1)分析程序或者LL(1)分析器。 LL(1)方法完成语法分析任务的程序叫LL(1)分析程序或者LL(1)分析器
输入串
一、分析过程
#
此过程有三部分组成: 此过程有三部分组成: 分析表 总控程序) 执行程序 (总控程序) 分析栈) 符号栈 (分析栈)
编译原理第4章 语法分析——自上而下分析
17
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
分析输入串x*y(记为)。
x*y
S
IP x A y **
18
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
分析输入串x*y(记为)。
x*y
S
IP x A y **
19
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
(4.3)
虽没有直接左递归,但S、Q、R都是左递归的
SQcRbcSabc
一个文法消除左递归的条件
丌含以为右部的产生式
丌含回路
PP
30
例 文法G(S): S→Qc|c Q→Rb|b R→Sa|a
(4.3)
虽没有直接左递归,但S、Q、R都是左递归的
SQcRbcSabc
Q
Q
ⅹ
S
R
S→Qc|c Q→Rb|b R→Sa|a
35
例 考虑文法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)
36
注意,由于对非终结符排序的丌同,最 后所得的文法在形式上可能丌一样。但 丌难证明,它们都是等价的。
分析输入串x*y(记为)。
x*y
S
IP
15
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
分析输入串x*y(记为)。
编译原理语法分析-自顶向下
实例分析
1
子规则匹配
根据语法规则,递归地匹配输入的源代码,构建语法树。
2
构建语法树
通过逐步匹配子规则,将语法树逐渐构建起来,形象地表示复杂的程序结构。
3
解释分析结果
对语法树进行解释,执行语义分析和生成中间分析方法,通过递归嵌套和预测分析,将复杂的源代码转换成易于处理的 语法树。
自顶向下分析算法
1 概述
自顶向下分析算法从目标语言的最高级别规则开始,逐步向下查找并匹配规则,构建语 法树。
2 递归下降分析
递归下降分析是自顶向下分析的一种常见方法,它通过递归调用子规则来分析输入的源 代码。
3 LL(1)分析
LL(1)分析是一种基于预测的自顶向下分析方法,它使用一个预测分析表来确定下一步要 采取的动作。
编译原理语法分析-自顶 向下
语法分析是编译器的重要组成部分,它负责将输入的源代码转换成语法树以 进行后续分析和解释。本节将介绍自顶向下的语法分析算法及其挑战。
语法分析概述
1 什么是语法分析
语法分析是编译器的第二个阶段,负责验证 输入的源代码是否符合语言的规范语法。
2 为什么需要语法分析
语法分析可以检查和纠正源代码中的语法错 误,以确保程序的正确性和可读性。
问题和挑战
1 二义性文法
当文法存在多个解释时,会导致语法分析的 困扰和歧义。需要通过合适的方法解决二义 性。
2 左递归文法
左递归文法会导致递归下降分析算法进入无 限循环,需要通过消除左递归来解决。
改进方法
1 消除二义性文法
通过重写或修改文法规则,消除存在二义性 的产生式。
2 消除左递归文法
通过改写产生式,消除文法中的左递归问题, 使得递归下降分析算法不会陷入无限循环。
编译原理 第四章自顶向下语法分析法
若文法的任一非终结符号,其规则右部的各个选择所能推出的终结符号串的头符号集合不满足两两相交的条件时,那么,要构造一个不带回溯的自顶向下的语法分析程序,需要采取什么措施呢?一般可采取改写文法的办法来解决。
(三)改写文法当文法不满足,可改写文法
对每一文法符号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是否还有别的选择。
编译原理(3)语法_4(自顶向下语法分析:LL(1)分析法)
课本例题3.8 第二步:计算非终结符的FOLLOW集合
G[E]: E→TE' E'→ + TE' | ε T→FT' T'→*FT' | ε F→(E) | i ③由E→TE' 知FOLLOW(E) ⊂ FOLLOW(E' ), 即FOLLOW(E' ) = {),#}; 由E→TE ' 且E ' → ε知FOLLOW(E)FOLLOW(T),即 FOLLOW(T) = {+,),#};
特别是当Y1~Yk均含有ε产生式时,应把ε也加到FIRST(X)中。
课本例题3.8 第一步:计算非终结符的FIRST集合 例3.8 试构造表达式文法G[E]的LL(1)分析表,其中: G[E]: E→TE' E'→ + TE' | ε T→FT' T'→*FT' | ε F→(E) | i
[解答] 首先构造FIRST集,步骤如下: ① FIRST(E') = {+, ε}; FIRST(T') = {*, ε}; FIRST(F) = {(, i}; ② T→F… 和E→T…知:FIRST(F) ⊂ FIRST(T) ⊂ FIRST(E) 即有FIRST(F) = FIRST(T) = FIRST(E) = {(,i}。
编译原理-自上而下的语法分析
高效性
由于从文法的最顶端开始分析, 一旦发现不匹配,就可以立即终 止当前分支的搜索,避免不必要 的计算,提高了编译器的效率。
易于处理左递归文
法
自上而下的分析方法可以很方便 地处理含有左递归的文法,而左 递归是许多实际编程语言的重要 特征。
局限性
无法处理左边界问题
自上而下的分析方法在处理某些含有左边界的文法时可能 会遇到问题,因为这种方法会优先匹配最左边的符号,而 左边界问题需要从右往左匹配符号。
案例三
在编译器优化中,自上而下的语法分析被用 于识别和修改源代码中的冗余和低效的语法 成分。例如,在C编译器的实现中,自上而 下的语法分析可以用于优化循环结构,减少 不必要的循环次数,提高程序的执行效率。
自上而下的语法分析还可以用于代码生成和 代码生成器的实现。通过识别和解析源代码 中的语法成分,可以生成更高效、更安全的 机器代码或字节码,提高程序的执行效率和
安全性。
THANKS
感谢观看
详细描述:递归下降分析算法易于理解,每个产生式规 则对应一个函数,函数的实现相对简单明了。
详细描述:对于每个产生式规则,需要编写相应的递归 函数,可能会导致代码冗余。
移入-规约分析算法
总结词
基于栈的算法
详细描述
移入-规约分析算法是一种自上而下的语法分 析算法,它将目标语句从左到右依次读入, 并根据文法的产生式规则进行移入或规约操 作,直到找到目标语句的语法结构。
词法分析
词法分析是编译过程的第一步,也称为扫描或词法扫描。它的任务是从左 到右读取源代码,将其分解成一个个的记号或符号。
词法分析器通常使用正则表达式或有限自动机来识别和生成记号,这些记 号可以是关键字、标识符、运算符、标点符号等。
编译原理 第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自顶向下的分析方法就是从文法的开始符号出发按最左推导方式向下推导试图推导出要分析的输开始符号输入符号串自底向上的分析方法从输入符号串开始按最左归约方式向上归约到文法的开始符号
编译原理LL(K)
S =>aAbc =>ababc 错误回退 ,再回退S 错误回退A,再回退
重复以上匹配过程,发现此时符号串abeB与abed 前3个符号均匹配,下面指针指向第四个符号d。 而符号串abeB 的第四个符号是B,若选择 B→ d 则得到下面语法树: S =>aB =>abeB =>abed
圆括号( ③ 圆括号( ) 利用圆括号可提出一个非终结符的多个产生式右部 的公共因子。例如, A→xy|xw|…|xz 可写成 A→x(y|w|…|z)
利用下面的两条规则,可把包含直接左递归 的产生式转换成用扩展BNF表示法表示的产生 式。
① 提公因子 每当一条产生式中有公因子可提的时候,就把它 提出来,若原产生式是 A→x|xy 则可写成 A→x(y|ε) A→x(y|ε),这里把ε当作最后一个 候选式。 这样,把本来具有相同开始符号的候选式 变成了开始符号不同的候选式,从而避免了实现 分析过程中的逐个试探,并且有助于消除文法的 直接左递归,同时也压缩了文法的长度。
end; 消除Ui Ui产生式中的直接左递归 消除Ui产生式中的直接左递归 end; 化简改写之后的文法,删除多余产生式。 ③ 化简改写之后的文法,删除多余产生式。
确定的自顶向下语法分析
4.4
LL(k)文法 LL(k)文法
LL(k)文法是上下文无关文法的一个真子集。同时, LL(k)文法也是允许采用确定的从左至右扫描(输入 串)和自上而下分析技术的最大一类文法。 LL系指:自左至右扫描(输入串),自上而下进行最 左推导。 分析过程中,如果每步仅利用当前的非终结符(事 实上已经位于栈顶)和至多向前查看k个输入符号 就能唯一确定采取什么动作 唯一确定采取什么动作,则这个文法称为LL(k) 唯一确定采取什么动作 文法。 下面主要讨论k=0,1时的情形。
编译原理-语法分析
自顶向下的语法分析方法简单直观,易于实现,但可能存在 左递归和回溯的问题。
自底向上的语法分析
01
自底向上的语法分析方法从源代码中的每个符号出发
,逐步归约到文法的起始符号。
02
该方法通常采用LR(0)、SLR(1)、LALR(1)等算法进行
实现。
03
自底向上的语法分析方法可以避免回溯问题,但需要
• 随着人工智能和机器学习技术的不断发展,可以利用这些技术来辅助语法分析 过程,提高语法分析的准确性和效率。例如,可以使用机器学习算法来自动识 别和处理语法规则和歧义问题。
• 另外,随着软件工程和代码质量的重视程度不断提高,对编译器和语法分析器 的要求也越来越高。未来的研究需要更加注重编译器和语法分析器的可维护性 和可扩展性,以满足不断变化的软件需求。
词法分析的算法
自底向上算法
自底向上算法是从源代码的左向右进行扫描,并从下到上构建语法结构。常见 的自底向上算法有预测分析法和移进-规约法。
自顶向下算法
自顶向下算法是从语法结构的顶层开始,向下进行推导,直到找到与源代码相 匹配的语法结构。常见的自顶向下算法有规范分析法和贪婪分析法。
语法分析概述
语法分析是编译过程的核心环节,其任务是将源代码分解成一系列的语法 结构,以便后续的语义分析和代码生成。
自底向上的算法,通过构建归 约表进行移进和规约操作。
LALR(1)算法
扩展的LR(0)算法,能够处理 更广泛的文法,生成更小的归 约表。
03
语义分析
语义分析概述
01
Байду номын сангаас02
03
语义分析是编译过程的 一个阶段,它是在语法
分析之后进行的。
语义分析的主要任务是 检查源代码的语义是否 正确,例如变量是否已 经声明,类型是否匹配
编译原理第四章语法分析-自上而下分析
• 例 4.4
4.4 递归下降分析程序构造
• 递归下降分析器:
这个分析程序由一组递归过程组成的,每个过程对应 文法的一个非终结符。 E→TE’ E’→+TE’| T→FT’ T’→*FT’| F→(E)|i
PROCEDURE E BEGIN T ; E’ END PROCEDURE E’ IF SYM=‘+’THEN BEGIN ADVANCE ; T ; E’ END
4.2 自上而下分析面临的问题
• 例4.1 假定有文法
(1) SxAy (2)A**|*
对输入串x*y,构造语法树。 • 构造过程:
(1)把S作为根 (2)用S的产生式构造子树 (3)让输入串指示器IP指向输入串的第一个符号。
S x A y x
S
A y x
S
A y
*
*
*
(4)调整输入串指示器IP与叶结点进行匹配。 (5)如果为非终结符,用A的下一个产生式构建子树。 (6)如果匹配成功则结束;否则,回溯到步骤(4)。
• 一个反例:
– 文法:SQc|c;QRb|b;RSa|a虽然不是直接 左递归,但S、Q、R都是左递归。
• 消除左递归算法:
– 算法的思想是:
• • • • 首先构造直接左递归; 再利用一般转换规则,消除直接左递归 化简文法。 下面算法在不含PP,也不含在右部产生式时可以消除 左递归。
• 消除一个文法的左递归算法:
(1) 把文法 G 的所有非终结符按任一种顺利排列成 P1…Pn;按此顺序执行; (2) FOR i:=1 TO n DO
BEGIN FOR j:=1 TO i-1 DO 把形如Pj+1→Pj 的规则改写成 Pj+11|1|…k| 。其中 Pj1|1|…k 是关于 Pj 的 所有规则; 消除关于Pi规则的直接左递归性。 END 化简由(2)所得的文法。即去除那些从开始符号出发永 远无法到达的非终结符的产生规则。
编译原理第4章习题答案
2)文法: S SS | SS* | a 输入串:aaa*a++ 自底向上语法分析过程:
c.消除左递归:S->aS’ S’->SAS’|Ɛ A->+|*
代入
S->aS’ S’->aS’AS’|Ɛ A->+|*
d.得到的文法适用于自顶向下的语法分析吗? 适用。因为文法中不存在左公因子,也不存在左递归
4.4.3 S->SS+|SS*|a
FIRST(S)={a}
因为S是起始符号,把{$}加入到Follow(S)中。 对于S->SS+的第一个S,把First(S+) = {a}加入到Follow(S)中。 对于S->SS*的第一个S,把First(S*) = {a}加入到Follow(S)中。 对于S->SS+的第二个S,把First(+) = {+}加入到Follow(S)中。 对于S->SS*的第二个S,把First(*) = {*}加入到Follow(S)中。 所以,FOLLOW(S)={a,+,*,$}
S A| B A AA | E0E (A是0比1多的串) B BB | E1E (B是1比0多的串) E 0E1E | 1E0E | (E是0和1的个数相等的串)
5)所有由0和1组成的且其中不包含子串011的串的集合。
S AB A 1 A | B 0 B | 01 B |
6)所有由0和1组成的形如xy的串的集合,其中 x y 且x和y等长。 S AB | BA A XAX | 0 (A是奇数长度,中间为0的串) B XBX | 1 (B是奇数长度,中间为1的串) X0|1
编译原理-清华大学-第4章-自顶向下语法分析方法(3+1)
(2)一个文法提取了左公共因子后,只解决 了相同左部产生式右部的FIRST集不相交问 题,当改写后的文法不含空产生式,且无左 递归时,则改写后的文法是LL(1)文法,否 则还需用LL(1)文法的判别方式进行判断才 能确定是否为LL(1)文法。
• FIRST(Ap)={a,c} • FIRST(Bq)={b,d}
2、非终结符A后跟符号FOLLOW集的定义:
• 定义:设 G = (VT ,VN , S , P) 是上下文无关文 法,A∈VN , S是开始符号。 FOLLOW(A)={a|S * …Aa… ,a∈VT} 若S *…A,则规定 #∈FOLLOW(A)
(3)反复使用规则(2)直到每个非终结符的 FOLLOW集不再增大
S→AB S→bC A→ε A→b B→ε B→aD C→AD C→b D→aS D→c
FOLLOW(S)={#}∪FOLLOW(D) FOLLOW(A)=( FIRST(B)-{ε} )∪
FOLLOW(S) ∪ FIRST(D) FOLLOW(B)=FOLLOW(S) FOLLOW(C)=FOLLOW(S) FOLLOW(D)=FOLLOW(B)∪FOLLOW(C)
• 1表示:只需向右看1个输入符号便可决定 如何推导(即选择哪个产生式进行推导)。
• 类似也可以有LL(K)文法:需向前查看K个 输入符号才可确定选用哪个产生式。
• 文法G[S]是否是LL(1)文法: S→aA S→d A→bAS A→ε
SELECT(S→aA) ={a} SELECT(S→d)={d} SELECT(A→bAS)={b} SELECT(A→ε)={a,d,#} SELECT(S→aA)∩SELECT(S→d)={a}∩{d}=Φ SELECT(A→bAS)∩SELECT(A→ε)={b}∩{a,d,#}=Φ
编译原理之自顶向下语法分析方法(25页)
间接左递归 若 PP α S→Aa A→Sb A→b
2021/8/25
5
消除左递归
消除直接左递归 形如:P → P α| β α非, β不以P打头
改写为:P → βP’ P’ → αP’|
2021/8/25
6
消除左递归
例:E → E+T|T T →T*F|F F →(E)| i
G[ E]: (1) E → TE’ (2) E’ → +TE’| (3) T → FT’ (4) T’ → *FT’ | (5) F → (E)|i
A →Bb|b
2021/8/25
10
回溯问题
例:S →iEtS|iEtSeS|a
E→b
判断句子ibtaea
提取左公因子:A →αβ1|αβ2
变为:
A →αA’
A’ →β1 |β2
若A →αβ1|αβ2 |…|αβn|r
变为:
A →αA’|r
A’ →β1 |β2|…|βn
2021/8/25
11
例:S →iEtS|iEtSeS|a
2021/8/25
Procedure E’; IF sym=‘+’ then Begin advance; T;E’ End;
Procedure T’; IF sym=‘*’ then Begin advance; F;T’ End;
14
3非递归的预测分析方法(LL(1))
一、总控程序 Input
24
非LL(1)文法的改造
消除左递归 提左公因子
2021/8/25
25
22
三、LL(1)文法:
一个文法G,若它的分析表M不含多重定义入 口,则称为LL(1)文法。
《编译原理》课程教学大纲--供四年制计算机科学与技术(医药软件开发)专业使用
《编译原理》教学大纲(供四年制计算机科学与技术(医药软件开发)专业使用)____________________________________________________________________一、前言本课程是计算机专业的重要专业课之一,主要介绍程序设计语言编译构造的基本原理和基本实现方法。
本课程主要讲授形式语言、有限自动机、自上而下和自下而上的语法分析、LR分析方法、属性文法和语法制导翻译、语义分析的蹭代码产生、存储器的动态分配与管理、符号表的组织与管理、优化问题、代码生成等内容。
本课程学生应掌握以下基本概念和原理,语言和文法、正规式、有限状态自动机、递归下降分析、算符优先分析、SLR 文法、代码生成、代码优化。
本课程的重点是突出基本概念、基本原理及算法,通过课堂教学与实践环节的训练,使学生掌握编译实现的基本方法和技术。
本课程的前导课程是计算机组成原理、数据结构、汇编语言程序设计、微机原理、操作系统原理等,并与程序设计语言等课程相关联。
本课程是考试课。
采用综合考核的考试方法,即在课程结束后一次性闭卷考试为主,并结合课堂提问、课后作业、上机作业等方面的考查,综合评定成绩。
本课程教学时数为:计算机科学与技术专业72学时,其中理论学时48,上机24学时。
教学采用课堂讲授法。
二、教学目的要求和内容第一章引论【目的要求】掌握编译的基本概念、编译过程概述、编译程序的结构了解编译程序与程序设计环境,编译程序的构造【教学内容】编译程序工作的基本过程及其各阶段的基本任务,编译程序总体框架。
【教学方法】课堂讲授第二章高级语言及其语法描述【目的要求】掌握程序语言定义、初等数据类型、数据结构熟悉高级高级语言的一般特性、程序结构、语句与控制结构掌握上下文无关文法,语法分析树与二义性。
【教学内容】上下文无关文法,程序语言定义参数传递。
【教学方法】课堂讲授第三章词法分析【目的要求】掌握词法分析器任务掌握词法分析器设计掌握正规表达式与有限自动机熟悉词法分析器自动生成。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第四章自顶向下语法分析方法语法分析是编译过程的核心部分。
语法分析的任务是:按照文法,从源程序符号串中识别出各类语法成份,同时进行语法检查,为语义分析和代码生成作准备。
执行语法分析任务的程序称为分析程序。
也称为语法分析器,它是编译程序的主要子程序之一。
在第二章中我们已经介绍过。
通过语法分析可建立起相应的语法树。
按语法树的建立方法,我们将语法分析方法分成两大类,即自顶向下分析和自底向上分析。
下面,我们先介绍自顶向下分析。
本章重点:自顶向下分析、LL(1)分析第一节自顶向下分析方法一、带回溯的自顶向下分析算法这是自顶向下分析的一般方法,即对任一输入符号串,试图用一切可能的方法,从识别符号出发,根据文法自上而下地为输入串建立一棵语法树。
下面用一个简单例子来说明这种过程:假定有文法G[S] :S—c A dA — ab|a 以及输入串w=cad为了自上而下地构造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是否还有别的选择。
为了实现回溯,我们一方面应把A的第一个选择所生长的子树注销掉;另一方面,应把IP恢复为进入A时的原值,也就是让它重新指向第二输入符号a。
现在我们试探用A的第二个选择,即考虑生成图3-1-1C的语法树。
由于子树A只有一个子结a,而且,它和IP所指的符号相一致,于是,A完成了匹配任务。
在A获得匹配后,指示器指向下一个未被触及的符号d e 在S的第二子结A完成匹配后,接着就轮到第三个子结d进行工作。
由于这个子结和最后一个输入符号相符,于是,我们完成了构造语法树的任务,证明了w是文法G[ s]的一个句子。
上述自顶向下地为输入符号w建立语法树的过程,实际上也是设法建立一个最左推导序列,以便通过一步步推导将输入串推导出来。
很明显,对于输入串w可以通过如下的推导过程将其推导出来:S CAd cad 所以用最左推导,是因为我们对输入串是自左向右扫描的,只有使用最左推导,才能保证按扫描顺序去匹配输入串。
在上述推出符号串w的过程中,由于出现在符号串中的非终结符号只有一个,因此,未明显地表现出最左推导的性质。
根据以上分析,不难编出程序来实现这种分析的算法。
但是,上述这种自顶向下的分析算法存在着一定的困难和缺点。
困难表现在不能为左递归文法构造自顶向下的语法分析器(上述所举例子的文法G[s]是不具有在递归性的)。
缺点主要表现在存在着回溯问题。
当然,应用带回溯的自顶向下的分析算法还必须将文法规则存放于内存。
下面将具体介绍这种分析算法所存在的问题及其解决办法。
二、存在问题及解决办法(一)左递归问题自顶向下分析法只有规则排列得合适时,才能正确工作。
该法的一个基本缺点是不能处理具有左递归的文法。
如下所示。
如:直接左递归和间接左递归A T aB|S T Sa|/ \A -无法确定语法树的终止,清除直接左递归的较好方法是改为右递归如:S—Sa|b 改为S T bSS'T aS I £一般情况下,直接左递归的形式可为:A T A a i|A a 2| …A a mB i| B 2…B n清除左递归后改写为:A TB l A‘ I B 2A'…I B n A'A'TQ 1A' | a 2A'…| a m A | £对于间接左递归的消除,需先将间接左递归变为直接左递归,然后再接上述方法消除。
条件是文法中无1A的有害规则和A—£的空产生式(二)回溯问题当产生式有多个选择时,选那个输入串去匹配为了避免回溯,就必须保证:对文法的任何非终结符号特别是规则右部有多个选择的非终结符号,当用它去匹配输入串时,应是确定无疑的。
即:U^a i| a 2| …| a n该规则右部有n个选择,为了实现目的,我们对文法的要求是:FIRST (a i)A FIRST (a j)=巾(i 工j )定义1:设G=(V T,V N, S, P)是上下文无关文法FIRST(a) ={a| a TaB, a € V T,a,p€ V*}若/T E,贝S规定a€ FIRST (a)即对文法中的任意一个非终符号,其规则右部有多个选择时,那么,由各个选择所推出的终结符号串的头符号集合要两两不相交。
这样,就可能根据当时读进的符号是属于哪个选择的FIRST (a),来唯一地确定应该选用哪个选择来匹配输入串。
如当前的输入符号为b(b € V), 若b€ FIRST (a i),贝S用第i个选择;若b不€ FIRST (a i),其中i=1~n,则语法错,转出错处理。
这样就避免了分析过程的回溯。
若文法的任一非终结符号,其规则右部的各个选择所能推出的终结符号串的头符号集合不满足两两相交的条件时,那么,要构造一个不带回溯的自顶向下的语法分析程序,需要采取什么措施呢一般可采取改写文法的办法来解决。
(三)改写文法当文法不满足,可改写文法提因子U H xv|xw U — x(v|w)三、递归子程序法此方法的主要做法是:对文法中每个非终结符号U,都编出一个子程序,以完成该非终结符号所对应的语法成分的分析和识别任务。
某个非终结符号的语法分析子程序的功能是:用该非终结符号的规则的右部符号串去匹配输入串。
分析过程是按文法规则自顶向下一级一级地分配任务,即调用有关的子程序来完成。
当编译程序根据文法和当前输入符号预测到下一个语法成分为U时,即预测到待匹配的输入符号串可以为从U出发所推导出的符号串相匹配时,就确定U为目标,并调用分析和识别U的子程序。
在分析和识别U 的过程中,有可能还要确立其他子目标并调用相应的子程序,只有在被调用的分析和识别某语法成分的子程序匹配输入串成功并正确返回时,该语法成分才算真正的获得了识别,并确定输入串无语法错误。
为什么针对某些非终结符号所编出的分析程序要编成递归子程序因为文法具有递归性。
前面已讲过,自顶向下分析不能处理左递归文法,若有左递归,则应改写文法予以消除。
但是,消除了左递归不等于消除了文法的所有递归性质,此时,文法仍可以有右递归性或自嵌入性。
如在文法中有规则U H…U或U H…U…此仍为递归规则,故分析U的子程序要编成递归子程序。
因为该子程序在用规则右部符号串去匹配输入串的过程中,又要调用U自己。
即在通过该子程序正常出口返回调用程序以前,又要重新直接进入该子程序,这就是直接递归。
此外,还有间接递归,如在文法中有规则:L H…V V —…UW那么U …V …UW即U+…UW在该情况下,在分析U的子程序中要调用分析V的子程序;而在分析U 的子程序中又要调用分析V的子程序。
这样,对U的分析程序就要编成递归子程序,因在进入U 的分析程序以后,在返回调用程序以前,又可能间接地进入自己(a)非终结符Z的分析(b)非终结符U 的分析 第二节LL(1)分析方法本节,我们将介绍实现自顶向下分 析的另一种方法,即所谓 LL(1)分析方 法。
如此命名该分析方法的原因在于相 应的语法分析将按自左至右的顺序扫 描输入符号串,并在此过程中产生一个 句子的最左推导。
至于括号中的“ 1”, 则表示在分析过程中,每进行一步推导,只要向前查看一个输入符号,便能 确定当前所应选用的产生式(规则)。
因此,我们通常把按上述方法执行语 法分析任务的程序称为LL(1)分析程序或LL(1)分析器,使用这种方法进行 语法分析,可借助于一张分析表及一个语法分析栈,在一个总控程序控制 下很方便地实现。
下面,我们将首先介绍LL(1)分析器的逻辑结构和工作过程,然后再介绍LL (1)分析器的构造方法。
(一)LL (1)分析器的逻辑结构及工作过程在逻辑上,一个LL (1)分析器由一个总控程序、一张分析表和一个分析 栈组成,如图4-2-1所示。
其中:总控程序 ——>X/1士匚一H 一 分析表m 分析栈al a2…彳ai … an #1、“输入”即待分析的符号串(注意,#€ V T,我们之所以在输入串的末尾放置一个#,仅为了分析算法格式的统一)。
2、分析表M可用一个矩阵(或二维数组)来表示,它概括了相应文法的全部信息。
矩阵的每一行与文法的一个非终结符号A相关联,而每一列则与文法的一个终结符号或#相关联。
分析表元素M[A, a]或者指示了当前推导所应使用的产生式,或者指出了输入串中含有语法错误。
分析器对每一输入串的分析在总控程序控制下进行。
其算法如下(为书写方便。
在下面的叙述中,我们将分析栈按顺时钟旋转九十度):第一步分析开始时,首先将符号#及文法的开始符号S依次置于分析栈底部,并把各指示器调整至起始位置,即初始格局为打 + I# S a © …然后,反复执行第二步所列的工作第二步设在分析的某一步,分析栈及余留的输入符号串处于如下的格其中,X,人,…X m为分析过程中所得的文法符号,此时,可视栈顶符号X m的不同情况,分别做如下的动作:1、若V N,则以X m及a i组成符号对(X m, a i)查分析表M设M凶aj 为一产生式,譬如说X-UVW V此时将X m从分析栈中退出,并将UVV按反序推入栈中(即用该产生式推导一步),从而得到新的格局# XX …X VVVUa a…#但若M[X m a i]= “ERROR则调用出错处理程序进行处理;2、若X m=a^#,则表明栈顶符号已与当前正扫视的输入符号得到匹配,此时应将X(即ai )从栈中退出,并将输入符号指示器向前推进一个位置;3、若X m=a i=#,则表明输入串已完全得到匹配,此时即可宣告分析成功而结束分析工作。
例考虑文法G[E]:E- TE'E' —+TE'| & T ' —*FT'| &F—(E)|i T —FT'相应的分析表如图4-2-2所示(其构造方法,在后面叙述)。
现以输入符号串i+i*i为例,列出利用上述算法对此符号串的分析过程如图4-2-3所示图4-2-2步骤分析栈余留输入串所用产生式1 # E i+i*i# E—TE'2 # E'T i+i*i# T—FT'3 # E'T'Fi+i*i #F—i4 # E'T'i i+i*i#(二) L L(1)分析表的构造方法上述LL(1)分析算法对于不同的LL(1)文法都是相同的。