第4章 语法分析和语法分析程序
清华大学编译原理第二版课后习答案
Lw.《编译原理》课后习题答案第一章第1章引论第1题解释下列术语:(1)编译程序(2)源程序(3)目标程序(4)编译程序的前端(5)后端(6)遍答案:(1)编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。
(2)源程序:源语言编写的程序称为源程序。
(3)目标程序:目标语言书写的程序称为目标程序。
(4)编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。
通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符号表管理等工作。
(5)后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。
(6)遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。
第2题一个典型的编译程序通常由哪些部分组成?各部分的主要功能是什么?并画出编译程序的总体结构图。
答案:一个典型的编译程序通常包含8个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。
其各部分的主要功能简述如下。
词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机内表达形式。
语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。
语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。
中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式的中间语言代码,如三元式或四元式。
中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。
盛威网()专业的计算机学习网站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
递归下降语法分析程序如下:
《编译原理》课后习题答案
第7 题证明下述文法G[〈表达式〉]是二义的。
〈表达式〉∷=a|(〈表达式〉)|〈表达式〉〈运算符〉〈表达式〉〈运算符〉∷=+|-|*|/答案:可为句子a+a*a 构造两个不同的最右推导:最右推导1 〈表达式〉=>〈表达式〉〈运算符〉〈表达式〉=>〈表达式〉〈运算符〉a=>〈表达式〉* a=>〈表达式〉〈运算符〉〈表达式〉* a=>〈表达式〉〈运算符〉a * a=>〈表达式〉+ a * a=>a + a * a最右推导2 〈表达式〉=>〈表达式〉〈运算符〉〈表达式〉=>〈表达式〉〈运算符〉〈表达式〉〈运算符〉〈表达式〉=>〈表达式〉〈运算符〉〈表达式〉〈运算符〉a=>〈表达式〉〈运算符〉〈表达式〉* a=>〈表达式〉〈运算符〉a * a=>〈表达式〉+ a * a=>a + a * a第8 题文法G[S]为:S→Ac|aB A→ab B→bc该文法是否为二义的?为什么?答案:对于串abc(1)S=>Ac=>abc (2)S=>aB=>abc即存在两不同的最右推导。
所以,该文法是二义的。
或者:对输入字符串abc,能构造两棵不同的语法树,所以它是二义的。
第9 题考虑下面上下文无关文法:S→SS*|SS+|a(1)表明通过此文法如何生成串aa+a*,并为该串构造语法树。
(2)G[S]的语言是什么?答案:(1)此文法生成串aa+a*的最右推导如下S=>SS*=>SS*=>Sa*=>SS+a*=>Sa+a*=>aa+a*(2)该文法生成的语言是:*和+的后缀表达式,即逆波兰式。
第10 题文法S→S(S)S|ε(1) 生成的语言是什么?(2) 该文法是二义的吗?说明理由。
答案:(1)嵌套的括号(2)是二义的,因为对于()()可以构造两棵不同的语法树。
第11 题令文法G[E]为:E→T|E+T|E-T T→F|T*F|T/F F→(E)|i证明E+T*F 是它的一个句型,指出这个句型的所有短语、直接短语和句柄。
第04章-语法分析自上而下分析
输入符号串是否为一个句子。 ▪ 语法分析器在编译器中的地位:
源程序
单词符号
词法分析器
取下一个单 词符号
语法分析器
语法分析树
编译器的 后继部分
2021/4/6
符号表
3
4.1 语法分析器的功能
▪ 语法分析方法
➢ 自上而下分析法
从文法的开始符号出发,反复使用文法的产生式, 寻找与输入符号串匹配的推导。
分析输入串x*y(记为)。
xx**yy
SS
IPIPIP xx A y * **
2021/4/6
7
4.2 自上而下分析面临的问题
▪ 当某个非终结符有多个产生式候选时,可 能带来如下问题:
➢ 1.分析过程中,当一个非终结符用某一个候选 匹配成功时,这种匹配可能是暂时的。这时, 不得不“回溯”。
➢ 2.文法左递归问题。一个文法是含有左递归的 ,如果存在非终结符P
➢ 最后所得的无左递归文法是: S→Qc | c Q→Rb | b R→bcaR | caR |a R R→ bca R |
➢ 不同排序所得的文法的等价性是显然的。
2021/4/6
17
4.3.2 消除回溯、提左因子
▪ 为了消除回溯就必须保证:对文法的任何 非终结符,当要它去匹配输入串时,能够 根据它所面临的输入符号准确地指派它的 一个候选去执行任务,并且此候选的工作 结果应是确信无疑的。
2021/4/6
14
4.3.1 左递归的消除
▪ 例4.3 考虑文法G(S)
S→Qc|c Q→Rb|b R→Sa|a
➢ 令它的非终结符的排序为R、Q、S。 ➢ 对于R,不存在直接左递归。 ➢ 把R代入到Q的有关候选后,把Q的规则变为
编译原理课后习题答案解析+清华大学出版社第二版
管理。(数组 CODE 存放的只读目标程序,它在运行时不改变。)运行时的数据区 S 是由解 释程序定义的一维整型数组,解释执行时对数据空间 S 的管理遵循后进先出规则,当每个 过程(包括主程序)被调用时,才分配数据空间,退出过程时,则所分配的数据空间被释放。 应用动态链和静态链的方式分别解决递归调用和非局部变量的引用问题。
RA 的用途说明如下: T: 栈顶寄存器 T 指出了当前栈中最新分配的单元(T 也是数组 S 的下标)。 B:基址寄存器,指向每个过程被调用时,在数据区 S 中给它分配的数据段起 始 地址,
也称基地址。 SL: 静态链,指向定义该过程的直接外过程(或主程序)运行时最新数据段的基地址,
用以引用非局部(包围它的过程)变量时,寻找该变量的地址。 DL: 动态链,指向调用该过程前正在运行过程的数据段基地址,用以过程执行结束释放
广义上讲,编译程序和解释程序都属于翻译程序,但它们的翻译方式不同,解释程序是 边翻译(解释)边执行,不产生目标代码,输出源程序的运行结果。而编译程序只负责把源 程序翻译成目标程序,输出与源程序等价的目标程序,而目标程序的执行任务由操作系统来 完成,即只翻译不执行。
)
第4题
对下列错误信息,请指出可能是编译的哪个阶段(词法分析、语法分析、语义分析、代 码生成)报告的。 (1) else 没有匹配的 if (2) 数组下标越界 (3) 使用的函数没有定义 (4) 在数中出现非数字字符
CAL L A 调用过程,完成填写静态链、动态链、返回地址,给出被调用过程的基地址值,送入基址 寄存器 B 中,目标程序的入口地址 A 的值送指令地址寄存器 P 中,使指令从 A 开始执 行。 第6题
编译原理 第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时的情形。
04 语法分析(1) _ 概述(含 消除左递归)
消除间接左递归的方法:
(1) 把间接左递归文法改写为直接左递归文法;
(2) 用消除直接左递归的方法改写文法。
下面给出一个消除文法所有左递归性的算法,该算
法对文法的要求是:文法不含回路(形如PP的
推导),且不含以ε为右部的产生式。
通用算法
• 阅读 P84 算法4.1
①把G的非终结符按任意顺序排列,如A1,…,An ②for(i=1;i<=n;i++)
0 1
q0
1
q1
q2
【定义】一个下推自动机可定义为一个7元组:
PDA M=(Q, , , q0, Z0, F, )
其中: ① Q是有限状态集; ② 是输入符号集; ③ 是栈符号集; ④ q0Q,称为起始状态; ⑤ Z0,称为栈起始符; ⑥ FQ,称为接受状态集; ⑦ 是转移函数,定义域为Q×({ε})×,且表示由 “当前状态qi、输入符号a和栈顶符号x决定PDA的转 移动作”。值域为Q×*,指明下推自动机的动作结 果包括“状态转移和栈操作”。
例4.6
设有文法G: I→I0 | Ia | Ib | a | b
对左递归文法G改写后的文法G'为 I → aI' | bI' I ' → 0I' | aI' | bI' |ε
习题 4.8
将下面的左递归文法G(S)改为非左递归的。
S → SaP|Sf |P P → QbP|Q Q → cSd|e 【解】 S → PS’ S’→ aPS’| f S’|ε P → QbP|Q Q → cSd|e
第4章 语法分析
—— 自顶向下分析法
思考题
上次课所留问题:
设计例3-3的词法分析程序。
编译原理第四章语法分析-自上而下分析
• 例 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)所得的文法。即去除那些从开始符号出发永 远无法到达的非终结符的产生规则。
编译原理第二版课后习答案
《编译原理》课后习题答案第一章第1章引论第1题解释下列术语:(1)编译程序(2)源程序(3)目标程序(4)编译程序的前端(5)后端(6)遍答案:(1)编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。
(2)源程序:源语言编写的程序称为源程序。
(3)目标程序:目标语言书写的程序称为目标程序。
(4)编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。
通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符号表管理等工作。
(5)后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。
(6)遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。
第2题一个典型的编译程序通常由哪些部分组成各部分的主要功能是什么并画出编译程序的总体结构图。
答案:一个典型的编译程序通常包含8个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。
其各部分的主要功能简述如下。
词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机内表达形式。
语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。
语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。
中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式的中间语言代码,如三元式或四元式。
中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。
目标代码生成程序:将优化后的中间代码程序转换成目标代码程序。
表格管理程序:负责建立、填写和查找等一系列表格工作。
表格的作用是记录源程序的各类信息和编译各阶段的进展情况,编译的每个阶段所需信息多数都从表格中读取,产生的中间结果都记录在相应的表格中。
编译原理龙书第四章答案
编译原理龙书第四章答案
1.什么是有效性检查?
答:有效性检查是语法分析中的一项重要检查,是指检查语言结构中
的各部分是否有效,即结构是否符合语言的语法规则。
2.什么是语法分析?
答:语法分析是指将文法定义的模式应用到给定的输入字符串中来识
别出输入字符串的结构特征,以确定给定的输入是否符合语法定义。
3.扩展BNF与简化后的BNF有什么区别?
答:扩展BNF使用更多的符号,可以更准确地表示文法的定义;而简
化后的BNF则把文法的定义层次降低,使用更少的符号,实现文法简化。
4.语法分析生成器的工作原理是什么?
答:语法分析生成器使用上下文无关文法定义的语句,根据文法定义
生成语法分析程序,它包括词法分析器和语法分析器。
当词法分析器处理
输入的字符串时,语法分析器就自动检查输入字符串是否满足文法定义。
5.什么是四元式?
答:四元式是源程序翻译成中间代码的基本单位,它用四元组的形式:(操作码,运算数1,运算数2,结果)来表示一条指令,便于后续的代码
优化和目标代码生成。
6.什么是类型检查?
答:类型检查是指在语义分析中,用来检查程序中表达式和变量的类
型是否合理。
编译原理课后习题答案解析+清华大学出版社第二版
计算机执行用高级语言编写的程序有哪些途径它们之间的主要区别是什么
答案:计算机执行用高级语言编写的程序主要途径有两种,即解释与编译。 像 Basic 之类的语言,属于解释型的高级语言。它们的特点是计算机并不事先对高级语
言进行全盘翻译,将其变为机器代码,而是每读入一条高级语句,就用解释器将其翻译为一 条机器代码,予以执行,然后再读入下一条高级语句,翻译为机器代码,再执行,如此反 复。
第2题
若 PL/0 编译程序运行时的存储分配策略采用栈式动态分配,并用动态链和静态链的方式分 别解决递归调用和非局部变量的引用问题,试写出下列程序执行到赋值语句 b∶ =10 时运行 栈的布局示意图。 var x,y; procedure p; var a; procedure q; var b; begin (q) b∶ =10; end (q); procedure s; var c,d; procedure r; var e,f; begin (r) call q; end (r); begin (s) call r; end (s); begin (p) call s;
(2) 数组下标越界 (3) 使用的函数没有定义 (4) 在数中出现非数字字符
答案: (1) 语法分析 (2) 语义分析 (3) 语法分析 (4) 词法分析
第5题
编译程序大致有哪几种开发技术
答案:
(1) 自编译:用某一高级语言书写其本身的编译程序。 (2) 交叉编译:A 机器上的编译程序能产生 B 机器上的目标代码。 (3) 自展:首先确定一个非常简单的核心语言 L0,用机器语言或汇编语言书写出它的
第6题
给出对 PL/0 语言作如下功能扩充时的语法图和 EBNF 的语法描述。 (1) 扩充条件语句的功能使其为: if〈条件〉then〈语句〉[else〈语句〉] (2) 扩充 repeat 语句为: repeat〈语句〉{;〈语句〉}until〈条件〉
语法分析与语法分析程序
❖
return;
❖
restore token-pointer value;
❖
if next-token='-' then return;
B中各元素均以终结符打头,故X=BZ相应的诸产生 式也以终结符打头,由Z=I+AZ对应的产生式引入了 新状态,由于产生式左部为新状态Zij,而右部为原文 法的符号,故也不会产生左递归。
• 例5.2 社有一文法:S→Sa|Ab|a,A→Sc。试用 矩阵法消除左递归。
5.1.2 带回朔的递归子程序法
•
if next-token='i' then return;
•
restore token-pointer value;
•
F:=false
• end;
❖function A: booleanave token-pointer value;
❖
A:=true;
❖
if next-token ='+' then
自顶向下分析可分为确定和不确定的
两种,确定分析法对文法有一定的限制, 但实现简单、直观,便于手工构造或自动 生成语法分析程序,是常用的方法之一。 不确定分析法实际是一种穷举试探法,效 率低,代价高,因而极少使用。
5.1 自顶向下的语法分析
❖ 所谓自顶向下分析,从语法树构成角度 讲是从上向下试图为输入符号串建立语 法树。
例5.3:设有一关于表达式的文法: E→TB,B→ATB|ε,T→FC,C→MFC|ε, F→(E)|i,A→+|-,M→*|/ 相应该文法我们可写出以下递归子程序法:
❖function E: boolean;
❖ begin
语法分析和语法分析程序
语义分析
01
语义分析是语法分析的第三个阶段,主要任务是理解句子所 表达的实际意义和概念。
02
语义分析需要理解单词和短语在特定语境下的含义,以及它 们之间的关系和逻辑。
03
语义分析通常使用语义规则和知识库等资源来进行,需要处 理各种语义歧义和概念歧义等问题。
应用广泛
语法分析在许多自然语言处理应 用中都发挥着重要的作用,如机 器翻译、信息检索、问答系统等。
语法分析的历史与发展
01 早期研究
早期的语法分析主要基于手工规则和专家系统, 这种方法复杂度高且可移植性差。
02 统计方法
随着统计方法的兴起,基于概率的语法分析方法 逐渐成为主流,这种方法能够自动地学习和识别 语言的语法结构。
解决方案
采用动态规划算法,逐步构建句子的 语法结构,同时考虑上下文信息。
语义理解难度
挑战
语法分析程序不仅需要理解句子的语法结构,还需要理解句子的语义,即理解句子所表达的实际意义 。
解决方案
利用知识图谱、语义网等技术,将语义信息纳入语法分析程序中,提高语义理解的准确性。
处理大规模数据的能力
挑战
随着大数据时代的到来,语法分析程序需要处理大规模数据,这对其性能和效率提出了 更高的要求。
文本分类与情感分析
基于语法分析程序,可以对文本进行分类和情感分析,识别文本的 主题、情感倾向和意图。
机器翻译
源语言解析
01
语法分析程序能够解析源语言文本,将其转化为内部表示形式,
为后续的翻译过程提供基础。
目标语言生成
02
基于源语言的内部表示形式,语法分析程序可以生成目标语言
语法分析程序
语法分析程序#include <stdio.h>#include <stdlib.h>#include <string.h>char prog[100],ch,token[8];int p=0,syn,n,i;char *keyword[6]={"begin","then","if","while","do","end"};void scaner();void Irparse();void statement();void expression_r();void term();void factor();void main(){int select=-1;p=0;printf("please input sentence, end of '#' !\n");do{ch=getchar();prog[p++]=ch;}while(ch!='#');p=0;printf("请输⼊1 或 2 \n 1.词法分析\n 2.语法分析\n");scanf("%d",&select);if(select==1){do{scaner();switch(syn){case -1:printf("词法分析出错\n");break;default :printf("<%d,%s>\n",syn,token);break;}}while(syn!=0);printf("词法分析成功\n");}else if(select==2){scaner();if(syn==1){Irparse();}//beginelse{printf("语法分析出错! 请检查begin关键字\n");return;}if(syn==6)//end{scaner();if(syn==0){printf("恭喜语法分析成功\n");}else{printf("语法分析出错! 请检查是否缺少'#'\n");}}else{printf("语法分析出错! 请检查是否缺少'end'\n");}}getchar();}void scaner(){for(n=0;n<8;n++){token[n]='\0';}n=0;ch=prog[p++];while(ch==''){ch=prog[p++];}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){do{token[n++]=ch;ch=prog[p++];}while((ch>='a'&&ch<='z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'));syn=10;for(n=0;n<6;n++){if(strcmp(token,keyword[n])==0){syn=n+1;}}p--;//return;}else if(ch>='0'&&ch<='9'){p--;do{token[n++]=prog[p++];ch=prog[p];}while(ch>='0'&&ch<='9');syn=11;return;}else{//ch=prog[p++];switch(ch){case'+':syn=13;token[0]=ch;break;case'-':syn=14;token[0]=ch;break;case'*':syn=15;token[0]=ch;break;case'/':syn=16;token[0]=ch;break;case':':syn=17;token[0]=ch;ch=prog[p++];if(ch=='='){token[1]=ch;syn++;}else p--;break;case'<':syn=20;token[0]=ch;ch=prog[p++];if(ch=='>'){token[1]=ch;syn++;}else if(ch=='='){token[1]=ch;syn=syn+2;}else p--;break;case'>':syn=23;token[0]=ch;ch=prog[p++];if(ch=='='){token[1]=ch;syn++;}else p--;break;case'=':syn=25;token[0]=ch;break;case';':syn=26;token[0]=ch;break;case'(':syn=27;token[0]=ch;break;case')':syn=28;token[0]=ch;break;case'#':syn=0;token[0]=ch;break;default: printf("词法分析出错! 请检查是否输⼊⾮法字符\n");syn=-1;break; }//return;}}void Irparse(){scaner();statement();while(syn==26)//;{scaner();statement();}}void statement(){if(syn==10){scaner();if(syn==18){scaner();expression_r();}else{printf("语法分析出错! 请检查表达式是否正确\n");return;}}else{printf("语法分析出错! 请检查语句是否正确\n");return;}}void expression_r(){term();while(syn==13||syn==14)//+ -{scaner();term();}}void term(){factor();while(syn==15||syn==16)//* /{scaner();factor();}}void factor(){if(syn==10||syn==11){scaner();}else if(syn==27){scaner();expression_r();if(syn==28){scaner();}else {printf("语法分析出错! 请检查是否缺少')'\n");return;}}else {printf("语法分析出错! 请检查是否输⼊⾮法字符\n");return;} }。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
建立语法树
4.2.1 优先文法 简介
4.2.2 LR分析法 LR分析: 自左至右扫描的自底向上的分析
LR分析对文法要求很少,效率极高,且能及时
发现错误,是目前最广泛使用的方法;一般用 CFG描述的语言均可用LR分析法 先介绍LR分析器的逻辑结构及工作原理,再 分别介绍几种LR分析器(即LR(0),SLR(1)和 LR(1))的构造
识别所有规[S]:
S→A|B A→aAb|c, B→aBb|d
LR(0)分析表的构造
识别G[S]全部活前缀的DFA
I0: S’→·S S→·A S→·B A→·aAb A→·c B→·aBb B→·d d c
S
I1: S’→S· I2: S→A· I3: S→B· A I4: A→a·Ab A→·aAb A→·c B→a·Bb B→·aBb B→·d B
A
b d
关健:句柄的确定
自顶向下分析的语法分析 例: 文法 S aCb C cd | c
为输入串w = acb建立分析树
S
a C b S S b a
a
c
C
C
c
b
d
试探的过程
问题:会产生回溯
–导致效率低
自顶向下分析法的另一问题 若有文法G6[S]:
(1) S→Sa
(2) S→b
(3) 存在一种算法,它能判定任意文法是否为LL(1)的;
(4) 存在一种算法,它能判定任意两个LL(1)文法是否等价; (5) CFL是否是LL(1)语言是不可判定的;
(6) 非LL(1)语言是存在的。
若在分析过程中,每步向前扫描k个符号来确定选用的产生 式,此分析方法称为是LL(k)分析。此法极少用,故从略。
习题 判断下列文法是否是LL(1)文法,如果是,请 写出LL(1)分析表;如果不是,请改造成LL(1) 文法。 S aFA | +aFA A +aFA |+B| F *aB BF|
4.2 自底向上的语法分析 优先分析法及LR分析法
问题:
如何确定句型的句柄 如何正确地选择产生式进行归约
A
B a
I8: A→aAb·
b I7: A→aA·b I9: B→aB·b b I10: B→aBb· a
c
I5: A→c·
I6: A→d· d
G[S]的LR(0)分析表
ACTION 0 1 a s4 b c s5 d s6 # acc S 1 GOTO A 2 B 3
2 3 4 5 6 7 8 9
b I9: B→Db ·, a
分析表实例
状态
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 r3 s14 r2 r2 a s3
ACTION b
c
acc
S 1
A
GOTO B
C 2
D
s4 r6 s8 s11 r4 r6 r5 s13 s9 r7 r1 s12 r3 5 10 6 7
不含句柄,则:期望移进一产生式的右部: A
我们把右部添加了一个“”的产生式,称为LR(0)项目 LR(0)项目:
归约项目: A→
接受项目: S’→S 移进项目: AX, ( XVT,可以是空串) 待约项目: AX, ( XVN, 可以是空串)
B→bD;Se D→D;d|d S→s;S|s
SLR(1)分析表的构造
习题
文法G[S]是否是LR(0)文法?如果是,请画
出LR(0)分析表;如果不是,请说明原理:
S→CbBA A→Aab|ab B→C|Db C→a D→a
LR(1)分析表的构造
文法G[S]的LR(1)项目集及DFA
I1: S’ →S ·, # S I0: S’ → ·S, # S→·CbBA, # C → ·a, b a a C I12: A→ab·, #/a I2: S →C·bBA, # b I4:S→Cb·BA, # B→·C, a B B →·Db, a C → ·a, a D →·a, b D I7: B→D ·b, a A→·Aab, A →·ab,
ACTION b s4 acc s5 r3 r4 r2 r3 r4 , #
GOTO L 1 E 2
5
6
s3
s4
r1
6
2
对符号串“a,b,a”的分析过程
步骤 1 2 3 4 5 6 7 8 9 10 11 12 0 03 02 025 0254 0252 02525 025253 025252 025256 0256 01 状态 栈中符号 # #a #E #E, #E,b #E,E #E,E, #E,E,a #E,E,E #E,E,L #E,L #E 余留符号 a,b,a# ,b,a# ,b,a# b,a# ,a# ,a# a# # # # # # 分析动作 s3 r3 s5 s4 r4 s5 s3 r3 r2 r1 r1 下一状态 3 GOTO[0,E]=2 5 4 GOTO[5,E]=2 5 3 GOTO[5,E]=2 GOTO[5,L]=6 GOTO[5,L]=6 GOTO[0,L]=1
自顶向下分析法:
从文法的开始符号出发,反复使用文法 的产生式,寻找与输入符号串匹配的推 导。
自底向上分析法:
从输入符号串开始,逐步进行归约,直至 归约到文法的开始符号。
自底向上的语法分析
例:文法G:
S → cAd A → ab A→a 识别输入串w=cabd是否是该文法的句子
S
A
c a b d c a b d c a
10
r1 r2 s4 r4 r6
r3 r5
r1 r2
r4 r6 s8 r3 s10 r5
r1 r2 s5 r4 r6
r3 r5
r1 r2 s6 r4 r6
r3 r5
r1 r2
7 r4 r6 r3 r5 9
习题 文法G[B]是否是LR(0)文法?如果是,请画
出LR(0)分析表;如果不是,请说明原理:
对文法的要求。确定的自顶向下分析要求文 法满足LL(1)文法。 本节主要介绍内容为: ◇ LL(1) 文法的定义和判别 ◇ 非LL(1)文法的等价变换 ◇ 确定的自顶向下分析方法 ◇ 递归子程序法 ◇ 预测分析方法
4.1 自顶向下的语法分析 消除文法的左递归
带回溯的递归子程序
回溯的消除及LL(1)文法
4.1.4 某些非LL(1)文法的改造 方法:
消除左递归 反复提取左因子 例: EE+T | T
T(E) | a(E) | a
经改造后可得文法:
ETE’ E’+TE’| TaT’ | (E) T’ (E) |
这是一个LL(1)文法
关于LL(1)的一些结论
能由LL(1)文法产生的语言称为LL(1)语言。它们已被证明具 有许多重要特性,主要有: (1) 任何LL(1)文法都是无二义性的; (2) 左递归文法是非LL(1)的;
推导baa#
S S S a S a S S a a S b
b
S
S
b
S
S
a
a
问题:左
递归—可 能导致死 循环
自顶向下分析法需要解决的问题 左递归
对文法进行改造
回溯
如何唯一地确定所采用的产生式? -LL(1)文法
当拒绝w时,只能知道w不是句子,不知出何错 及出在何处
本节将主要介绍确定的自顶向下分析思想和
expr_prime( ){
if(match(PLUS)){
advance( ); term( );
expr_prime( );
} }
4.1.3 回溯的消除及LL(1)文法 基本原理 First集及Follow集的构造 分析器的构造 例:
ETE’ E’ ATE’|ε TFT’ T’ MFT’|ε F(E)|i A+|- M* | / (4.1)’ 对i+ii进行预测分析的过程
编 译 原 理
第四章 语法分析和语法分析程序
winniewan@
本章内容
自顶向下分析和自底向上分析
围绕分析器的自动生成展开
难重点 语法分析是编译程序的核心部分。
语法分析的作用是识别由词法分析给出的单
词符号序列是否是给定文法的正确句子(程 序) 目前语法分析常用的方法有自顶向下(自上 而下)分析和自底向上(自下而上)分析两 大类。
(二)LR(0)分析表的构造 一些术语
规范句型的活前缀
• 将栈内符号与未扫描的输入串拼接起来,可得一规范
句型.即栈内符号串总是规范句型的前缀,且不含句柄
右侧的符号. • 把具有上述性质的符号串称为规范句型的活前缀
LR(0)项目(看详细内容)
LR(0)项目
活前缀:
包含全部句柄,则:进行归约: A, 记为A; 句柄中,则:应移进(句柄的后半部分), A12
(一)LR分析器的逻辑结构及工作原理
LR分析器=输入符号串+分析栈+总控程序+分析表
例:文法G[L]: 1. LE,L 2. LE
4. Eb
3. Ea
分析表 例:对符号串 “a,b,a”的分析过 程 四个分析动作:移进、 归约、接受、报错
状态 a 0 1 2 3 4 s3
b
I11: A→a·b, #/a a I5:S→CbB·A, # #/a #/a A I10: S→CbBA·, # A →A·ab #/a a I13: A→Aa·b, #/a b I14: A→Aab·, #/a
I3: C→a ·, b
I8: C→a ·, a D →a ·, b