我要投搞

标签云

收藏小站

爱尚经典语录、名言、句子、散文、日志、唯美图片

当前位置:2019跑狗图高清彩图 > 指称语义 >

编译原理 第8章语法制导翻译和中间代码生成

归档日期:07-16       文本归类:指称语义      文章编辑:爱尚语录

  语法制导翻译和中间代码生成8.1语义处理概述 8.2语义形式化简介 8.3属性文法,语法制导翻译和Yacc(Bison) 8.4中间代码 8.5一些语句的翻译 语言的语义和编译的语义处理工作 静态语义:语法规则的良形式条件 静态语义检查:审查静态语义 动态语义:程序单元执行的操作 动态语义处理:生成中间(目标)代码 8.1语义处理概述 编译阶段程序设计语言的语义 静态语义是对程序约束的描述,这些约束无法通过抽象语法 规则来妥善地描述,实质上就是语法规则的良形式条件,它 可以分为类型规则和作用域/可见性规则两大类 动态语义 程序单位描述的计算 编译程序的语义处理工作 静态语义审查 解释执行动态语义 语法分析后的源程序 语义处理静态语义审查 (1)类型检查。根据类型相容性要求,验证程序中执行的每个操 作是否遵守语言的类型系统的过程,编译程序必须报告不符合类 型系统的信息。 (2)控制流检查。控制流语句必须使控制转移到合法的地方。例 如,在C语言中break语句使控制跳离包括该语句的最小while、for 或switch语句。如果不存在包括它的这样的语句,则就报错。 (3)一致性检查。在很多场合要求对象只能被定义一次。例如 Pascal语言规定同一标识符在一个分程序中只能被说明一次,同 一case语句的标号不能相同,枚举类型的元素不能重复出现等等 (4)上下文相关性检查。比如,变量名字必须先声明后引用;而有时,同一名字必须出现两次或多次,例如,Ada 语言程序中, 循环或程序块可以有一个名字,出现在这些结构的开头和结尾, 编译程序必须检查这两个地方用的名字是相同的。 (5)名字的作用域分析 解释执行动态语义 (计算)生成代码(中间代码或目标代码) 语义处理的描述属性文法:描述语义规则。 语法制导翻译:在语法分析的同时,执行 语义子程序: 检查静态语义 翻译(生成)中间(目标)代码 语义处理的描述-例 DD;Did:TTchar aray[num]of P代表程序;D代表说明;E代表表达式。如程序语句:key: integer; String:char; key mod 1999 语言本身提供两种基本类型:char和integer。 除此之外还有缺省的基本类型type_ error和void。假定所有数组 都从下标1开始 确定标识符类型的语义描述 (3)Did:T{addtype (id. Entry, type)}(4)Tchar Type:=char} (5)Tinteger Type:=integer} Type:=pointer type)}(7)Tarray [num]of array(num.Val, .type)}类型检查的语义描述 Sid:=E voidelse S.Type type_error} .typeelse type_error} Swhile Typeelse type_error} 语义处理的实现工具 Yacc(Bison)对语法制导翻译的支持: Yacc(Bison)对语义值的支持 通过$伪变量访问文法符号的语义值。 Yacc(Bison)对语义动作的支持 在语法规则的动作中调用语义子程序:计算语义值, 诊断语义错误,生成中间代码等。 Variable TypeT_Identifier CreateVariableDeclaration(&@1,$1, $2); 静态语义分析的环境符号表 为语义分析提供类型、作用域等信息。 为代码生成提供类型、作用域、存储类别 、存储(相对)位置等信息。 8.2语义形式化-- 语义建模 文法模型---- 属性文法 命令式或操作式模型----- 操作语义学 应用式模型-----指称语义学 公理式模型-----公理语义学 规格说明模型-----代数数据类型 属性文法 表达式文法 .typeE.type :=int} .typeE.type :=bool} bool}操作语义 描述一段程序的含义是通过执行该段程序所改变的计算机 (无论是真实计算机还是虚拟计算机)状态来反映。计算 机里所有的寄存器的值和存储单元的值作为计算机的状态 (expr1;expr2;expr3){expr1; Loop:ifexpr2=0 goto out expr3;goto loop out: 公理语义公理语义概念是随着程序正确性的证明而发展的。 当正确性证明能构造时表明程序执行它的规格说明所 描述的计算。在一个证明中,每一个语句之前之后都 有一个逻辑表达式对程序的变量进行约束,以此说明这 个语句的含义。 一般的记号{P} 给定P,什麽是它的规格说明S2.给定规格说明S,开发实现此规格说明的程序P 3.S和P执行同样的功能吗 While循环 I是循环不变式。if--then--else S1else S2{Q} 指称语义 指称语义的基本概念是给每一段程序实体定义一个数学 意义上的对象,和一个从实体实例向数学意义对象的 映射的函数 特点: 不但对全部程序赋予全文而且对程序设计语法 每一个语法成分短语(表达式,命令,声明… 都给予含义。每一个语法成分(短语)的含义是以它的自 成分的含义的术语来定义的。 语义结构平行于语法结构。 语义函数: 程序设计语言的语义利用映射函数来证 二进制数语言110或10101 语法实体 指称(十进制数) 21语义实体 二进制数文法 Numeral::=0 自然数Natrual={0,1,2,3,…} 语义函数 Valuation:NumeralNatural Valuation[101] 表示把Valution施用于101 Valuation[N] 把它施用于N定义: Valuation(用四个方程)因为有四个形式numeral Valuation[0] Valuation[N0]2Valution Valuation[N1]2Valution [N]+1 所以: Valuation[110]=2 规格说明模型-代数数据类型描述实现一个程序的各种函数间的关系。 如表明一个实现服从任何两个函数间的这 种关系,则可以声明这个实现是此规格 说明的正确实现。 8.3属性文法,语法制导翻译和Yacc(Bison) 属性文法A(attribute grammar)是一个三元组 :A=(G,V,F),其中 G:是一个上下文无关文法, V:有穷的属性集,每个属性与文法的一终结 符或非终结符相连, F:关于属性的属性断言或谓词集.每个断言 与一个产生式相联.而此断言只引用该产生 式左端或右端的终结符或非终结符相联的 属性 例如:定义表达式的文法如下: 给出定义表达式值的属性文法我们为文法符号E引进属性符号val,用E.val表示E的值,属 性计算规则以赋值语句的形式给出,附在每个产生式后 ,并用大括号括起来。为了明确E的不同出现位置,用 上角标区别。终结符n的值是词法分析程序提供的,这 里用n.lex表示。下面给出属性文法: n.lex}属性文法的主要思想有两点: 首先对于每个文法符号引进相关的属性符号; 其次对于每个产生式写出属性值计算的规则。 属性文法:允许为每个终结符和非终结符配备一 些属性的文法.它既能描述程序设计语言的语法, 又为其语义描述提供了手段. 属性文法由D.E.Knuth于1968年引进.后来才被 用于编译程序的设计。 属性有不同的类型,可以象变量一样地被赋值. 赋值规则附加于语法规则之上.赋值与语法同时 进行,赋值过程就是语义处理过程.在推导语法 树的时候,诸属性的值被计算并通过赋值规则层 层传递.有的从语法规则左边向右边传,有的从 右边向左边传.语法推导树最后完成时,就得到 开始符号的属性值.也就是整个程序的语义. 属性分为两种:继承属性和综合属性. inherited synthesized(derived)attribute继承属性的计算规则由顶向下, 综合属性的计算规则由底向上. 例如定义表达式值的属性文法, E.val是一个综合属性 的例子: n.lex}考虑句子2+(3+1)的求值顺序,将2+(3+1)的 语法树结点改为有附加属性的结点(这样的树称为 带注释的语法树): E.val=6 E.val=2 E.val=4n.lex=2 E.val=1n.lex=3 n.lex=1 又例:一个简单台式计算器的定义 综合属性val digitPrint(E.val) E.val:=E1.val+T.val E.val:=T.val T.val:=T1.val F.valT.val:=F.val F.val:=E.val F.val:=digit.lexval 3*5+4的带注释的分析树只使用综合属性. E.val=19E.val=15 T.val=4 T.val=15 F.val=4 T.val=3 F.val=3 F.val=5 digit.lexval=4 digit.lexval=5 digit.lexval=3 3*5+4的带注释的分析树继承属性 一个结点的继承属性值是由此结点的父结,点和/或兄弟 结点的某些属性来决定的。例,添加标识符类型的语义 描述: 继承属性type 产生式 TLTint ,idLid L.type:=T.type T.type=integer T.type:=real .type:=L.typeaddtype(id.entry,L.type) addtype(id.entry,L.type) L.type=real L.type= real L.type= real T.type=real real id2 id1 id3 继承属性(续)Real id1,id2,id3的带注释的语法树 D.E.Knuth讲述属性文法使用的例子:定点二进制数的CFG: 显然,可以使用一个正规文法表示同样的语 言.D.E.Knuth使用这个CFG 是为了说明综合属性和继承 属性如何附加在非终结符上. 非终结符N表示整个二进制 非终结符N表示整个二进制数,该例中共使用了三个属性:综合属性v和le,继承属性f,分别使 用和显示综合属性和继承属性.综合属性v附加 该值分配给N的值与它的位置有关,是与2成比例,但这个比例因子是无法综合的,因此设计一 个从S继承的属性f,那么附加在B的属性表示为 非终结符S表示一个二进制 数字串,它的值v与它在串中的位置有关,与串 的长度le有关, f的计算基于串的长度和相对于 小数点的位置,所以有: 继承属性和综合属性11.01的带注释的语法树 的和;整数部分和小数部分已分别选定了比例因子f,并沿语法树传下去了,该数 的整数部分的数字串继承的比例因子是1,而该数的小数部分的数 字串继承的比例因子基于小数点至它的右端的数字的数目,即小 数部分的长度*/ +1]/*任何二进制数串都是由子串后跟一位二进制数字构成,二进 制数字B的比例因子与数串的一样,子串的要乘以2,数串的长度 /*属性v和f有关,f是从父结点继承的*/属性计算方法 树遍历的属性计算方法 设语法树已经建立起了,并且树中已带有开始符号的继承属性和 终结符的综合属性。然后以某种次序遍历语法树,直至计算出所 有属性。最常 用的遍历方法是深度优先,从左到右的遍历方法 。如果需要的话,可使用多次遍历(或称遍)。 一遍扫描的处理方法 与树遍历的属性计算文法不同,一遍扫描的处理方法是在语法分析 的同时计算属性值,而不是语法分析构造语法树之后进行属性的 计算,而且无需构造实际的语法树。 因为一遍扫描的处理方法与语法分析器的相互作用,它与下面两个 因素密切相关: (1)所采用的语法分析方法 (2)属性的计算次序。 D.E.Knuth的例子,串11.01的语法树中的属性流 属性le自底向上 Le=1Le=2 Le=2 Le=1 D.E.Knuth的例子,串11.01的语法树中的属性流 属性f自上而下 f=1/4f=1/2 f=1/2 D.E.Knuth的例子,串11.01的语法树中的属性流 属性v自底向上 v=3+1/4D.E.Knuth的例子 当然,只使用综合属性i和l也可以描 述二进制数值的计算,这样属性计算可以使用一遍扫描的 处理方法: 语法制导翻译-在语法分析的同时进行语义处理从概念上讲,语法制导翻译即基于属性文 法的处理过程通常是这样的:对单词符 号串进行语法分析,构造语法分析树, 然后根据需要遍历语法树并在语法树的 各结点处按语义规则进行计算 就如D.E.Knuth的例子所见到的,首先对输入符号串建立 语法树,接着分析属性的依赖关系,当属性和属性计 算规则设计的合适时,即语义规则的计算能够在一遍 扫描语法树的情况下可以完成,便可以在语法分析的 同时进行语义处理。这个思路为编译程序生成系统提 供了一种模型。 语义处理采用的方法—语法制导(将语义处理的描述和文法 的产生式关联起来)语法分析的同时完成语义处理 例:类形检查 .type=int E.type:=int else error} .type=bool E.type:=bool else error} bool}编译实现 (LR)增加语义栈 归约时进行语义动作 (LL(1))匹配时进行语义动作 LR(0)分析表 action GOTO 状态 S4S3 s5s7 r4r4 r4 r4 r4 r3r3 r3 r3 r3 s4s3 r1r1 r1 r1 r1 s4s3 r2r2 r2 r2 r2 增加语义栈,对串n 的LR分析的同时进行语义工作分析步骤1 时状态栈,符号栈和语义栈的内容: 分析步骤2时状态栈,符号栈和语义栈的内容: 分析步骤3时状态栈,符号栈和语义栈的内容: 分析步骤4时状态栈,符号栈和语义栈的内容: 分析步骤5时状态栈,符号栈和语义栈的内容: 分析步骤6时状态栈,符号栈和语义栈的内容: Yacc或bison作为编译程序的生成工具,利用的就是语法制导翻译方法。 下面的文法定义了类似 Pascal语法的声明和简单 赋值语句: 考虑为该文法增加两个属性,name和 dl 每当一个新变量被声明,就 将它的name属性附加给变 量,然后将这个名字加列 到名字清单中,属性dl表 示目前声明块已声明了的 所有名字 要进行的语义检查是:使用 的名字必须已声明。 属性文法在下一张: DS{S.dl Yacc或bison作为编译程序的生成工具,利用的就是语法制导翻译方法。它使用符号$$表示产生式左端的属性, $n表示存取产生式右端第n个文法符号相联的属性 如上例作为Yacc的输入,可写成:$$.dl);$5.dl=$$.dl} {$$.name=’z’}8.4中间代码 概述 何谓中间代码( Intermediate code) (Intermediate representation) (Intermediate language) 是源程序的一种内部表示 复杂性介于源语言和目标机语言之间 中间代码的作用: 使编译程序的逻辑结构更加简单明确 利于进行与目标机无关的优化 利于在不同目标机上实现同一种语言 中间代码的形式: 逆波兰式、四元式、三元式、间接三元式、树 中间代码的层次 中间代码按照其与高级语言和机器语言的 接近程度,可以分成以下三个层次: 高级:最接近高级语言,保留了大部分源语言 的结构。 中级:介于二者之间,与源语言和机器语言都 有一定差异。 低级:最接近机器语言,能够反映目标机的系 统结构,因而经常依赖于目标机。 不同层次的中间代码举例 源语言 (高级语言 中间代码(高级) 中间代码( 中级) 中间代码( 低级) float a[10][20]; a[i][j+2]; t1 j+2]t1 20t3 t2t4 t3t5 t4t7 *t6r1 20r5 r2r6 r5r7 216f1 T1T2) T2T3) T5T6) T3T6 T7) 三元式 间接三元式间接三元式序列 间接码表 8.5讨论一些语法成分的翻译 控制语句中布尔表达式的翻译控制语句 的代码E.true E.false E.true: 的代码goto out E.false: 的代码out: 只把条件转移的布尔表达式E翻译成仅含 条件真 布尔表达式E:arop gotoE.true goto E.false gotoE.true gotoE.false gotoE.true gotoE.false (不是最优) 拉链返填 (10)goto 链尾(10)(20) goto (20)goto10 (30)goto (30)goto 20 链头(30)(40)L:„„ (40) 语句if goto(p+1) (E.false) goto(p+1) goto(E.true goto(E.false) goto(E.true goto(E.false) (E.true)( 语义描述使用的量:E.true 的第一个四元式nextstat 下一四元式地址 过程: emit( 输出一条四元式,而后ebegin);E.Codebegin:= .codebegin;E.true:=merge(E .true)E.false:= .codebegin);E.Codebegin:= .codebegin;E.true:= .true;E.false:= merge(E .false;E.Codebegin:= .codebegin;E.false:= .true;E.Codebegin:= .codebegin;E.false:= Eid1rop id2 E.true:=nextstat;E.Codebegin:=nextstat; E.false:=nextstat+1; emit(‗if‘ id1.place ‗rop‘ id2.place ‗goto‘–); emit(‗goto‘-)} E.true:=nextstat;E.codebegin:=nextstat; E.false:=nextstat+1; emit(‗if‘ id.place ‗goto‘–); emit(‗goto‘-)} 2简单赋值语句(的四元式)翻译 四元式形式 t:=arg1 op arg2 语义 属性:id.name, E.place 函数:lookup(id.name) 过程:emit(t:=arg1op arg2); newtemp; 产生式 语义描述 P:=lookup(id.name) emit(P―:=‖E.place) {E.place:=newtemp; emit(E.place―:=‖ E.place:=newtemp;emit(E.place―:=‖―uminus‖ E.place:=Pelse error} 3(回顾)静态语义检查的例子-(体现一般说 明语句的翻译,使用符号表代替变量名字清单) 两个属性,name和dl,每当一个新的变量声明时,就把它的name属性附给它,name属性是综合属性。 将所声明的变量都放到一个变量名字清单中(用语义函数addlist实现),用 属性dl综合声明块中声明的所有变量。然后这个dl属性又作为继承属性 传到后面的语句部分,每个语句用到的变量都要进行审查,看它是否在 变量名字清单中 DS{S.dl D.dl}D1 addlist(V.name,D2.dl)} NULL}S1 {check(V.name,S1.dl); S2.dl 如笛卡儿所说:“同一件事情可以使这批人高兴的要跳舞,却使另一批人伤心的要流泪。”如菊花 中国与西方山水审美观的差异是十分明显的。在人与自 然的关系方面,中国哲学主张“天人合一”,“物我一 体”,而西方哲学则主张天人对立,物我对立。这种哲学 观念的差异,必然导致山水审美观的分岐。 一)、中国人特别关注山水景观所附载的人文美;而西方则 关注山水景观本身的自然美 《滕王阁序》“落霞与孤鹜齐飞,秋水共长天一色。” “关关睢鸠,在河之洲,窈窕淑女,君子好逑”, 车尔尼雪夫斯基这样来描写水:“水由于它的形状而显现出美,辽阔的、 一平如镜的宁静的水在我们的心理产生宏伟的形象。奔腾的瀑布,它 的气势是令人震惊的,它的奇怪特殊的形象也是令人神往的。水,由于 它的灿烂透明,它的淡青色光辉而令人迷恋,水把四周的一切如画地反 映出来,把这一切屈曲地摇曳着,我们看到的水是第一流的写生画家。” 动,其内在精神与韵致得到充分表达,是谓神似。西画借助焦点透视 法,重远近层次、阴影明暗,把模仿的逼真性(形似)作为衡量艺术成 败得失的主要尺度。 3,中国“天人合一”,高扬人的主体精神。认为艺术不 在模仿自然,而在表达受自然感动之“心”;不在再现外 物,而在抒情言志。而西方在于求真,在于再现外物。 三)、中国人的风景审美其目的在于舒适精神、怡乐性情;西方人的目的在于追求形式美的享受以及光感、色彩、空

本文链接:http://capstonebake.com/zhichenyuyi/282.html