编译 第三章 语法分析.ppt
《编译 第三章 语法分析.ppt》由会员分享,可在线阅读,更多相关《编译 第三章 语法分析.ppt(65页珍藏版)》请在三一办公上搜索。
1、第三章 语法分析,语法分析方法,自下而上是指:根据文法,对输入字串进行归约,若能正确地归约 为文法的初始符号,则表示输入字串是合法的.典型方法是算符优先分析法.自上而下是指:从文法的初始符号进行推导,若能推导出与输入 字串相同的句子,则表示输入字串是合法的.典型方法是递归下降分析法.,语法分析概述,3.1分析器的作用,一、语法分析的任务:把单词符号作为基本单位,根据文法,分析源程序(字符串)是否为合法的程序.同时报告语法错误并进行错误的恢复,使后面的分析能够进行下去。,二、语法错误的处理,程序的错误有各种不同的性质。例如,错误可能是:(1)詞法错误,如标识符、关键字或算符的拼写错误(2)语法错
2、误,如算术表达式的括号不配对(3)语义错误,如算符作用于不相容的运算对象(4)逻辑错误,如无穷的递归调用。大多数错误的诊断和恢复集中在语法分析阶段,原因如下:(1)大多数错误是语法错误(2)诊断语法错误比诊断语义错误和逻辑错误容易得多。分析器出错处理的基本目标是:(1)清楚而准确地报告错误的出现;(2)迅速从每个错误中恢复过来,以便诊断后面的错误(3)不应使正确程序的处理速度降低太多。,三、错误恢复策略,(1)紧急方式恢复:发现错误时,分析器每次抛弃一个输入记号,直至输入记号属于某个指定的同步记号集合为止。同步记号一般是定界符,如分号或end。优点:方法简单,不会陷入死循环。适用于一个语句中很
3、少出现多个错误的情况。(2)短语级恢复:发现错误时,分析器对剩余输入作局部纠正,用可以使分析器继续分析的输入串来代替剩余输入的前缀。如:用分号代替逗号、删除多余的分号、插入遗漏的分号。这种替换可用于纠正任何输入串,已经用于几个错误修复编译器,首先是用于自上而下的分析方法。它的主要缺点是很难应付实际错误出现在诊断点以前的情况。(3)出错产生式:如果对经常遇到的错误了解得很清楚,就可以扩充语言的文法,增加产生错误结构的产生式,用此扩充的方法来构造分析器。(4)全局纠正:在处理不正确的输入串时,作尽可能少的修改。,3.2上下文无关文法,文法:是描述语言的语法结构的形式规则(即语法规则)形式描述:用一
4、组数学符号和规则来描述语言的方式。形式语言:形式描述所用的数学符号和规则。形式:指仅考虑数学符号间的推演,而不涉及符号的具体含义。上下文无关文法是这样一种文法:它定义的语法单位,独立于该语法单位可能出现的环境,不必考虑上下文关系.自然语言不是上下文无关文法;程序语言是上下文无关文法.程序设计语言的许多结构包含固有的递归性,可用上下文无关文法定义。例:如果S1和S2是语句,E是表达式,则“if E then S1 else S2”是语句。使用语法变量stmt表示语句类,用expr表示表达式类,上述语句可用文法产生式方便地表示为:stmtif expr then stmt else stmt,1.
5、上下文无关文法定义 上下文无关文法 G 是一个四元组:G=(VT,VN,S,P)VT:是一个非空有限集,每个元素称为终结符.程序设计语言的文法中记号是终结符的同义词。例如:if,then,else,while,do,等都是终结符。VN:是一个非空有限集,每个元素为非终结符,代表了一种语法单位.且 VT VN=.例如:表达式,短语,语句等。S:是一个非终结符,称为开始符号,S VN.S 是文法G 的最高层次的语法单位.在程序语言中,S代表了程序这一语法概念.P:是产生式的有限集合。一条产生式定义了一个非终结符,产生式形式如下:A(A VN,(VT VN)*)称A定义为.(有时也会用:=代替)(V
6、T|VN)*,例:文法(id,+,-,*,/,(,),expr,op,expr,P)定义了简单的算术表达式,P是由下列产生式组成的有限集合:exprexpr op exprexpr(expr)expr-exprexpridop+op-op*op/op,b)用英文大写字母表前面的字母、字母S、小写字母串代表非终结符;英文小写字母表前面的字母、数字、运算符号、标点符号、黑体字代表终结符;希腊字母、大写字母后面的字母、小写字目表后面的字母串等代表由VT,VN组成的符号串;即:,(VT VN)*.c)一个文法,可以仅用开始符号及产生式代替.例如:表达式的文法可以定义如下:E E+E|E-E|E*E|E
7、/E|(E)E 为文法的开始符号,+-*/()为终结符.,例如:考虑一个文法G1:,S bAA|a aA 它定义了一个什么样的语言呢?S是开始符号,是非终结符A是非终结符是终结符与非终结符组成的字符串b是终结符a是终结符 结论:S baa*,例如:E=E+E=E*E+E=i*E+E=i*i+E=i*i+i,E是我们的开始符号,也是非终结符+、-、*、/是终结符i是终结符E+E、E*E+E、i*E+E、i*i+E是句型i*i+i是句子E=E+E、E+E=E*E+E、E*E+E=i*E+E、i*E+E=i*i+E是经一步推导出-直接推导E=i*i+i是经多步推导出-可推导出,一个句型到另一个句型的
8、推导有两种方式:最左推导和最右推导:最左推导是指每次直接推导,对句型的最左非终结符实行替换;最右推导是指每次直接推导,对句型的最右非终结符实行替换.,例如:有文法G:E=E+E|E*E|E/E|E-E|i,最左推导:E=E+EE+E=E*E+EE*E+E=i*E+Ei*E+E=i*i+Ei*i+E=i*i+i最右推导:E=E+EE=E+iE=E*E+iE=E*i+iE=i*i+i,4 语法树与文法的二义性 语法树可以表示句型的推导及句型的层次结构.语法树是一棵倒立树,根结点表示了文法的初始符号,每进行一步推导,树的叶结点构成的有序序列构成一个句型.例如:E=E+E=E*E+E=i*E+E=i*
9、i+E=i*i+i 可表示为:语法树可以表示同一句型的多种推导,是多种推导的共性抽象.但未必代表了同一句型的所有推导:E=E*E=E*E+E=i*E+E=i*i+E=i*i+i,语法树,定义:若文法 G 的某个句型存在两个不同的语法树表示,称该文法 是二义文法.因此,文法 E 是二义文法.二义性导致了i*i+i 的两种不同运算结果:(i*i)+i 以及 i*(i+i).编译中应避免二义文法.E 文法的二义性是因为没有规定*,+运算符的优先顺序,改进 E 后,得到:ET|E+T TF|T*F F(E)|i,E为表达式,T 为项,F 为因子,该文法对于句子i*i+i的各种推导,对应的语法树是唯一的
10、.,E,E,T,+,T,F,T,*,i,F,i,F,i,3.3 语言和文法,1、文法的优点:文法给出了精确的、易于理解的语言语法说明。某些文法类可以自动产生高效的分析器,分析器的构造过程可以揭示出语法的二义性和其他难于分析的结构。设计的漂亮的文法把结构加于程序设计语言,这些结构对于把源程序翻译成为正确的目标代码和错误诊断都是很有用的语言也是逐渐完善的,需要补充新的结构和完成附加的任务。如果存在以文法为基础的语言的实现,这些新结构的加入就更方便。但是不是所有的语言都可以用上下文无关文法来描述,例如:我们变量的使用就要求先定义后使用,后面的使用就的根据前面的类型和属性来决定。即:程序语言也有一定的
11、语言环境。因此我们强调语法分析器的输出结果。本章介绍语法分析,是分析语法结构,使用文法;而前一节词法分析,是分析我们的词法规则,使用正规式;他们有什么区别、联系、相似之处。,2、正规式和上下文无关文法的比较,正规式所描述的每一种结构都可以用上下文无关文法来描述。例如:正规式(a|b)*abb和上下文无关文法 A0 aA0|bA0|aA1 A1 bA2 A2 bA3 A3 描述同样的语言。既然上下文无关文法可以跟正规式等价,那么,我们为什么不在词法分析阶段不介绍正规式,而仅仅介绍上下文无关文法?(1)语言的词法规则非常简单,不必要功能更强大的上下文无关文法来描述它。(2)对于记号,正规式比上下文
12、无关文法提供了更见解和易于理解的符号表式。(3)从正规式可以自动地构造出比从其他文法更有效的词法分析器。(4)把语言的语法结构分成词法和非词法两部分,为编译器前段的模块化分提供了方便的途径。,3.文法的表式及产生的语言,例如 文法:S(S)S|推导我们的文法产生式,每一次推导得到的终结符为()或则,()成对出现,而是空串,所以此文法描述的语言是所有的配对括号组合。例如 文法:S if expr then stml A A else B|B S|stml stml S|stml|推导文法产生式,可以得到我们的if语句的语法结构,包括if的嵌套结构,描述所有的if语句。例如 文法:S while
13、expr do stml stml stml|推导文法产生式,得到该文法描述的是我们所有的while循环语句。,例如 设expr和term为非终结符,用以表式不同的优先级,终结符为id、括号、运算符等,facter为产生表达式的基本单位。则:文法一 facter id|(expr)term term*facter|term/facter|facter expr expr+term|expr-term|term 这个表达式文法是无二义性的,句子id+id+id和id+id*id的分析树如下:,文法二:facter id|(expr)term term+facter|term-facter|fac
14、ter expr expr*term|expr/term|term 对于文法二,就具有二义性,优先级于我们的语法结构不能对应,我们再分析id+id*id,得到语法树:,4.消除二义性,从上面例题可以看出,消除文法的二义性,可以重写文法的产生式,来使我们的算符优先级、算符结合性与我们的语法树相对应。例如 文法:stml if expr then stml|if expr then stml else stml|other 这里other代表任何语句,按照这个文法,复合的条件语句:if e1 then s1 else if e2 then s2 else s3,每个else和最近的还没有配对的th
15、en配对,但是以上是二义文法,因为串if e1 then if e2 then s1 else s2有两棵语法树,可以使用下面的文法消除二义性,思想是每个then和else之间的语句必须是配对的,配对是不包括不配对语句的“if then-else”结构的,文法:stml matched_stml|unmatched_stml matched_stml if expr then matched_stml else unmatched_stml|other unmatched_stml if expr then stml|if expr then matched_stml else unmatch
16、ed_stml 分析以上文法,对于复合的条件语句:if e1 then s1 else if e2 then s2 else s3 表示同样的意义,但对于if e1 then s1 else if e2 then s2 却限定了只有一种分析。,5.消除左递归,文法是左递归的,如果它有非终结符A,对于串a,存在着推导A Aa,至上而下的分析方法不能处理左递归文法,因此需要消除二义性,左递归的产生式A Aa|,可以用非左递归的产生式:A A A Aa|来代替,他们没有改变从A推导出的串集。例如:考虑下面的算术表达是文法:E E+T|T T T*F|F F(E)|id 消除E和T的直接左递归(形式为
17、A Aa 的产生式),可以得到:,E TE E+TE|T FT T*FT|F(E)|id 不管有多少A的产生是,我们都可以用下面的技术消除直接左递归。首先把A的产生式组在一起:A Aa1|Aa2|Aam|1|2|n 其中i都不以A开头,ai都非空,由产生式:A 1A|2A|nA A a1A|a2A|amA|代替。以上变换可以删除左递归,但不能消除两步或多步推导形成的左递归。例如 考虑文法:S Aa|b A Ac|Sd|,非终结符S式左递归的,因为S Aa Sda,但它不是直接左递归。用S产生式替换A Sd中的S,得到下面的文法:S Aa|b A Ac|Aad|bd|删除其中的直接左递归,产生如
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 第三章 语法分析 第三
链接地址:https://www.31ppt.com/p-2673933.html