您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 编译原理 第4章 new1语义分析和中间代码生成
第4章语义分析和中间代码生成第4章语义分析和中间代码生成4.1概述4.2属性文法4.3几种常见的中间语言4.4表达式及赋值语句的翻译4.5控制语句的翻译4.6数组元素的翻译4.7过程或函数调用语句的翻译4.8说明语句的翻译4.9递归下降语法制导翻译方法简介第4章语义分析和中间代码生成4.1概述4.1.1语义分析的概念一个源程序经过词法分析、语法分析之后,表明该源程序在书写上是正确的,并且符合程序语言所规定的语法。但是语法分析并未对程序内部的逻辑含义加以分析,因此编译程序接下来的工作是语义分析,即审查每个语法成分的静态语义。如果静态语义正确,则生成与该语言成分等效的中间代码,或者直接生成目标代码。第4章语义分析和中间代码生成直接生成机器语言或汇编语言形式的目标代码的优点是编译时间短且无需中间代码到目标代码的翻译;中间代码的优点是使编译结构在逻辑上更为简单明确,特别是使目标代码的优化比较容易实现。第4章语义分析和中间代码生成动态语义检查需要生成相应的目标代码,它是在运行时进行的;静态语义检查是在编译时完成的,它涉及以下几个方面:(1)类型检查,如参与运算的操作数其类型应相容。(2)控制流检查,用以保证控制语句有合法的转向点。如C语言中不允许goto语句转入case语句流;break语句需寻找包含它的最小switch、while或for语句方可找到转向点,否则出错。(3)一致性检查,如在相同作用域中标识符只能说明一次、case语句的标号不能相同等。第4章语义分析和中间代码生成由于语义是上下文有关的,因此语义的形式化描述是非常困难的,目前较为常见的是用属性文法作为描述程序语言语义的工具,并采用语法制导翻译的方法完成对语法成分的翻译工作。第4章语义分析和中间代码生成4.1.2语法制导翻译方法语法制导翻译的方法就是为每个产生式配上一个翻译子程序(称语义动作或语义子程序),并在语法分析的同时执行这些子程序。语义动作是为产生式赋予具体意义的手段,它一方面指出了一个产生式所产生的符号串的意义,另一方面又按照这种意义规定了生成某种中间代码应做哪些基本动作。在语法分析过程中,当一个产生式获得匹配(对于自上而下分析)或用于归约(对于自下而上分析)时,此产生式相应的语义子程序就进入工作,完成既定的翻译任务。第4章语义分析和中间代码生成语法制导翻译分为自下而上语法制导翻译和自上而下语法制导翻译。自下而上语法制导翻译:假定有一个自下而上的LR分析器,我们可以把这个LR分析器的能力加以扩大,使它能在用某个产生式进行归约的同时调用相应的语义子程序进行有关的翻译工作;每个产生式的语义子程序执行之后,某些结果(语义信息)必须作为此产生式的左部符号的语义值暂时保存下来,以便以后语义子程序引用这些信息。第4章语义分析和中间代码生成此外,原LR分析器的分析栈也加以扩充,以便能够存放与文法符号相对应的语义值。这样,分析栈可以存放三类信息:分析状态、文法符号及文法符号对应的语义值。扩充后的分析栈如图4–1所示。第4章语义分析和中间代码生成skXkVk·vals1X1V1·val………s0#—状态文法符号语义值TOP图4–1扩充后的LR分析栈第4章语义分析和中间代码生成考虑下面的文法及语义动作所执行的程序:产生式语义动作(0)S'→Eprintval[TOP](1)E→E(1)+E(2)val[TOP]=val[TOP]+val[TOP+2](2)E→E(1)*E(2)val[TOP]=val[TOP]*val[TOP+2](3)E→(E(1))val[TOP]=val[TOP+1](4)E→ival[TOP]=lexval(注:lexval为i的整型内部值)文法的LR分析表见表3.20。第4章语义分析和中间代码生成扩充分析栈工作的总控程序功能,使其在完成语法分析的同时也能完成语义分析工作(这时的语法分析栈已成为语义分析栈);即在用某一个规则进行归约之后,调用相应的语义子程序完成与所用产生式相应的语义动作,并将每次工作后的语义值保存在扩充后的“语义值”栈中。第4章语义分析和中间代码生成E·val=52E·val=7E·val=45+7E·val=9*E·val=595图4–2语法制导翻译计算表达式7+9*5#的语法树第4章语义分析和中间代码生成表4.1表达式7+9*5#的语义分析和计值过程步骤状态栈符号栈语义栈输入串主要动作10#_7+9*5#s3203#7__+9*5#r4301#E_7+9*5#s44014#E+_7_9*5#s350143#E+9_7__*5#r460147#E+E_7_9*5#s5701475#E+E*_7_9_5#s38014753#E+E*5_7_9__#r49014758#E+E*E_7_9_5#r2100147#E+E_7_45#r11101#E_52#acc第4章语义分析和中间代码生成4.2属性文法4.2.1文法的属性属性是指与文法符号的类型和值等有关的一些信息,在编译中用属性描述处理对象的特征。随着编译的进展,对语法分析产生的语法树进行语义分析,且分析的结果用中间代码描述出来。对于一棵等待翻译的语法树,它的各个结点都是文法中的一个符号X,该X可以是终结符或非终结符。根据语义处理的需要,在用产生式A→αXβ进行归约或推导时,应能准确而恰当地表达文法符号X在归约或推导时的不同特征。第4章语义分析和中间代码生成例如:判断变量X的类型是否匹配,要用X的数据类型来描述;判断变量X是否存在,要用X的存储位置来描述;而对X的运算,则要用X的值来描述;因此,语义分析阶段引入X的属性,如X.type、X.place、X.val等来分别描述变量X的类型、存储位置以及值等不同的特征。第4章语义分析和中间代码生成文法符号的属性可分为继承属性与综合属性两类。继承属性用于“自上而下”传递信息。继承属性由相应语法树中结点的父结点属性计算得到,即沿语法树向下传递,由根结点到分枝(子)结点,它反映了对上下文依赖的特性。继承属性可以很方便地用来表示程序语言上下文的结构关系。综合属性用于“自下而上”传递信息。综合属性由相应语法分析树中结点的分枝结点(即子结点)属性计算得到,其传递方向与继承属性相反,即沿语法分析树向上传递,从分枝结点到根结点。第4章语义分析和中间代码生成4.2.2属性文法属性文法是一种适用于定义语义的特殊文法,即在语言的文法中增加了属性的文法,它将文法符号的语义以“属性”的形式附加到各个文法的符号上(如上述与变量X相关联的属性X.type、X.place和X.val等),再根据产生式所包含的含义,给出每个文法符号属性的求值规则,从而形成一种带有语义属性的上下文无关文法,即属性文法。属性文法也是一种翻译文法,属性有助于更详细地指定文法中的代码生成动作。第4章语义分析和中间代码生成例如,简单算术表达式求值的属性文法如下:产生式语义规则(1) S→Eprint(E.val)(2) E→E(1)+TE.val=E(1).val+T.val(3) E→TE.val=T.val(4) T→T(1)*FT.val=T(1).val*F.val(5) T→T(1)T.val=T(1).val(6) F→(E)F.val=E.val(7) F→iF.val=i.lexval第4章语义分析和中间代码生成上面的一组产生式中,每一个非终结符都有一个属性val来表示整型值,如E.val表示E的整型值,而i.lexval则表示i的整型内部值。与产生式关联的每一个语义规则的左部符号E、T、F等的属性值的计算由其各自相应的右部符号决定,这种属性也称为综合属性。与产生式S→E关联的语义规则是一个函数print(E.val),其功能是打印E产生式的值。S在语义规则中没有出现,可以理解为其属性是一个虚属性。第4章语义分析和中间代码生成简单变量类型说明的文法G[D]如下:G[D]:D→intL∣floatLL→L,id∣id其对应的属性文法为:产生式语义规则(1) D→TLL.in=T.type(2) T→intT.type=int(3) T→floatT.type=float(4) L→L(1),idL(1).in=L.in;addtype(id.entry,L.in)(5) L→idaddtype(id.entry,L.in)注意到与文法G[D]相应的说明语句形式可为intid1,id2,…,idn或者floatid1,id2,…,idn第4章语义分析和中间代码生成非终结符T有一个综合属性type,其值为int或float。语义规则L.in=T.type表示L.in的属性值由相应说明语句指定的类型T.type决定;属性L.in被确定后将随语法树的逐步生成而传递到下边的有关结点使用,这种结点属性称为继承属性。由此可见,标识符的类型可以通过继承属性的复写规则来传递。例如,对输入串inta,b,根据上述的语义规则,可在其生成的语法树中看到用“→”表示的属性传递情况,如图4–3所示。第4章语义分析和中间代码生成图4–3属性信息传递情况示意DTLintL,id2id1第4章语义分析和中间代码生成4.3中间语言为了使编译程序在逻辑上更为简单明确,特别是为了使目标代码的优化比较容易实现,许多编译程序都采用了某种复杂性介于源程序语言和机器语言之间的中间语言,并且首先把源程序翻译成这种中间语言程序(中间代码)。第4章语义分析和中间代码生成常见的中间语言形式:逆波兰式三元式四元式第4章语义分析和中间代码生成四元式是一种比较普遍采用的中间代码形式。四元式的四个成分是:算符OP、第一运算量ARG1、第二运算量ARG2以及运算结果RESULT。其中,运算量和运算结果有时指用户自定义的变量,有时指编译程序引进的临时变量。第4章语义分析和中间代码生成赋值语句X:=-B*(C+D)的四元式序列:序号OPARG1ARG2RESULT注释(1)uminusB-T1T1为临时变量(2)+CDT2T2为临时变量(3)*T1T2T3T3为临时变量(4):=T3-X赋值运算表中:“uminus”是为了区别“-”而表示的求负运算符。凡只需一个运算量的算符,使用ARG1。第4章语义分析和中间代码生成4.4表达式及赋值语句的翻译4.4.1简单算术表达式和赋值语句的翻译简单算术表达式是一种仅含简单变量的算术表达式;简单变量是指普通变量和常数,不含数组元素及结构引用等复合型数据结构。简单算术表达式的计值顺序与四元式出现的顺序相同,因此很容易将其翻译成四元式形式。第4章语义分析和中间代码生成考虑以下文法G[A]:A→i=E E→E+E∣E*E∣−E∣(E)∣i在此,非终结符A代表“赋值句”。为了实现由表达式到四元式的翻译,需要给文法加上语义子程序,以便在进行归约的同时执行对应的语义子程序。第4章语义分析和中间代码生成实现简单算术表达式和赋值语句到四元式的翻译一般采取下列步骤:(1)分析文法的特点。(2)设置一系列语义变量,定义语义过程、语义函数。(3)修改文法,写出每一条规则式的语义子程序。(4)扩充LR分析栈,构造LR分析表。第4章语义分析和中间代码生成语义子程序所涉及的语义变量、语义过程及函数说明如下:(1)对非终结符E定义语义变量E.place,即用E.place表示存放E值的变量名在符号表中的入口地址或临时变量名的整数码。(2)定义语义函数newtemp( ),即每次调用newtemp( )时都将回送一个代表新临时变量的整数码;临时变量名按产生的顺序可设为T1、T2、……。(3)定义语义过程emit(op,arg1,arg2,result),emit的功能是产生一个四元式并填入四元式表中。第4章语义分析和中间代码生成(4)定义语义函数lookup(i.name),其功能是审查i.name是否出现在符号表中,是则返回i.name在符号表的入口指针,否则返回NULL。使用上述语义变量、过程和函数,可写出文法G[A]中的每一个产生式的语义子程序。(1) A→i=E{p=lookup(i.name);if(p==NULL)error
本文标题:编译原理 第4章 new1语义分析和中间代码生成
链接地址:https://www.777doc.com/doc-3547333 .html