《编译原理(第2版)71语义出理概述.ppt》由会员分享,可在线阅读,更多相关《编译原理(第2版)71语义出理概述.ppt(21页珍藏版)》请在三一办公上搜索。
1、第七章语法制导翻译和中间代码生成,7.1语义处理概述7.2属性文法和语法制导翻译7.3 中间代码生成(一些语句的翻译)7.4符号表,源语言程序,中间代码,汇编代码,词法分析,语义分析,语法分析,中间代码生成,代码生成,在编译中的逻辑阶段,前端处理,后端处理,语义处理,7.1 语义处理(语义分析和中间代码生成),源语言程序,汇编代码,词法分析,语义分析,语法分析,代码生成,前端处理,后端处理,语义处理,语义处理,语义处理,语义处理的任务:静态语义检查静态语义:语法规则的良形式条件静态语义检查:审查静态语义动态语义处理动态语义:程序单元执行的操作动态语义处理:生成(中间/目标)代码,语义处理,语义
2、处理的实现:属性文法:描述语义规则。语法制导翻译:在语法分析的同时,执行语义规则描述的动作:检查静态语义生成中间代码/目标代码,语义处理,语义处理的环境:符号表为语义分析提供类型、作用域等信息。为代码生成提供类型、作用域、存储类别、存储(相对)位置等信息。,语义处理,if sym=callsym thenbegingetsym;if sym identthen error(14)elsebegin i:=position(id);if i=0 then error(11)elsewith tablei doif kind=procedurthen gen(cal,lev-level,adr)e
3、lse error(15);getsymend end,PL/0编译程序的语义处理(一)call语句的处理,语义处理,error 11:标识符未说明;error 12:赋值语句中,赋值号左部的标识符属性应为 变量;error 15:call后标识符的属性应为过程;error 21:表达式内标识符属性不能为过程;error 32:read语句括号中的标识符不是变量。,PL/0编译程序的语义处理(二)语义错误列表,PL/0编译器的符号表,const a=10;var b,c;procedure p;begin c:=b+a;end;begin read(b);while b#0 do begin
4、call p;write(2*c);read(b);endend.,编译程序分析到第8行时符号表的内容,const a=10;var b,c;procedure p;begin c:=b+a;end;begin read(b);while b#0 do begin call p;write(2*c);read(b);endend.,(0)jmp 0 8 转向主程序入口(1)jmp 0 2 转向过程p入口(2)int 0 3 过程p入口,为过程p开辟空间(3)lod 1 3 取变量b的值到栈顶(4)lit 0 10 取常数10到栈顶(5)opr 0 2 次栈顶与栈顶相加(6)sto 1 4 栈顶
5、值送变量c中(7)opr 0 0 退栈并返回调用点(16)(8)int 0 5 主程序入口开辟5个栈空间(9)opr 0 16 从命令行读入值置于栈顶(10)sto 0 3 将栈顶值存入变量b中(11)lod 0 3 将变量b的值取至栈顶(12)lit 0 0 将常数值0进栈(13)opr 0 9 次栈顶与栈顶是否不等(14)jpc 0 24 等时转(24)(条件不满足转)(15)cal 0 2 调用过程p(16)lit 0 2 常数值2进栈(17)lod 0 4 将变量c的值取至栈顶(18)opr 0 4 次栈顶与栈顶相乘(2*c)(19)opr 0 14 栈顶值输出至屏幕(20)opr 0
6、 15 换行(21)opr 0 16 从命令行读取值到栈顶(22)sto 0 3 栈顶值送变量b中(23)jmp 0 11 无条件转到循环入口(11)(24)opr 0 0 结束退栈,归纳:语义分析(静态语义处理),(1)类型检查。验证程序中执行的每个操作是否遵守语言的类型系统的过程.,编译程序必须报告不符合类型系统的信息。(2)控制流检查。控制流语句必须使控制转移到合法的地方。例如,在C语言中break语句使控制跳离包括该语句的最小while、for或switch语句。如果不存在包括它的这样的语句,则就报错。(3)一致性检查。在很多场合要求对象只能被定义一次。例如Pascal语言规定同一标识
7、符在一个分程序中只能被说明一次,同一case语句的标号不能相同,枚举类型的元素不能重复出现等等。(4)相关名字检查。有时,同一名字必须出现两次或多次。例如,Ada 语言程序中,循环或程序块可以有一个名字,出现在这些结构的开头和结尾,编译程序必须检查这两个地方用的名字是相同的。(5)名字的作用域分析,类型检查程序的设计,1.辨认语言中可用的类型2.辨认具有类型的语言结构3.辨认语言的语义规则基础 类型的基本概念,类型的基本概念,数据类型的三要素:用于区别这种数据类型的数据对象的属性 这种类型数据对象可以具有的值 可以施用在这种类型的数据对象上的操作数据类型分为:基本(初等)数据类型:数值数据,逻
8、辑数据,字符数据,指针类型等。复合数据类型:数组、结构、表、栈、树等。抽象数据类型:Ada的包(Package),C+的类(Class)等。,类型的基本概念,类型的等价关系和相容关系:等价关系如果在任何场合下,类型A和类型B的表达式都可以互相替代,则称类型A与类型B等价。相容关系如果在类型A的表达式出现的任何场合下,都可以用类型B的表达式替换,则称类型B相容于类型A。,类型的基本概念,声明和定义,使用:声明:程序通过声明语句把标识符的名称、类型和作用域等信息传递给编译器。声明语句本身传递名字和类型信息,声明语句的位置传递作用域信息。定义:变量、类的声明就是定义。函数可以先声明一个原型,在定义中
9、再给出实现的代码。,类型的基本概念,强类型语言和弱类型语言:强类型语言标识符必须先声明后才能使用。标识符的类型信息在编译时是已知的。例如:PASCAL,C弱类型语言标识符不声明就可以直接引用。标识符的类型信息在编译时不能确定,在运行时推测得到。例如:Lisp,ML,运算符(函数)的重载 多态函数,重载运算符(overloading operator)是指该符号有多个含义,但根据上下文可以确定唯一的运算。如是重载符号,在AB中,当A和B为整数、实数、复数或者矩阵时,运算符执行不同类型的运算.当出现重载运算符时,要确定它所表示的唯一的意义,即进行运算符识别并检查运算符的操作数。多态函数(过程)-函
10、数(过程)允许参数的类型变化.多态函数(过程)的特点是,每次被调用时,传递过来的参数可以具有不同类型。,作用域分析,分程序结构的作用域规则作用域分析的实现,作用域,作用域类型:Global scope在任何函数和类定义之外的区域。所声明的标识符具有全局作用域。Class scope特指类定义的作用域。所声明的类类型具有全局作用域。所声明的类成员具有类作用域。Function scope特指函数形参表中参数的作用域。所声明的函数具有全局作用域,或类作用域,或其它局部作用域。所声明的形参具有函数作用域。Local scope由定界符/begin end分隔,定义在过程(函数)体或其它局部作用域(分
11、程序)内。所声明的标识符具有局部作用域。,分程序结构语言的作用域规则,当前开放的作用域中的标识符才能够被访问;在同一作用域中,不允许声明同名的标识符;在不同的作用域中,内层声明的标识符将遮蔽外层声明的同名标识符,使其变为不可见的。int a;chara;floata;a 引用char a;函数形参表中的变量在函数体中是可见的;int a;floatfunc(float a,float b)a引用float a;,分程序结构语言作用域举例,(1)main()(2)int a;(3)(4)(5)bool a;(6)(7)(8)double a;(9)(10)a(14)(15)(16),scope 3,scope 2,scope 1,scope 1:(1)-(16)scope 2:(4)-(14)嵌套于scope 1中 scope 3:(7)-(10)嵌套于scope 2中 scope 4:(11)-(12)嵌套于scope 2中 a(int)在scope 1中可见;a(bool)在scope 2,4中可见;a(double)在scope 3中可见程序运行到第12行时:scope 4是当前作用域;scope 1,2,4是开放的作用域;scope 3是关闭的作用域。,scope 4,