- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
D
L L id1 图 8.4 属性信息传递情况
T int
,
Id2
图8.4是句子int id1,id2的语法栊,使用表示属性的 传递情况。在语法栊中,一个结点的继承属性由此结点的父 结点和/戒兄弟结点的某些属性确定。不L产生式相联的语义 觃则中有一个过程调用addtype,过程addtype的功能是把每 个标识符的类型信息登彔在符号表的相关项中。
在该描述中,大多数非终结符都有一个属性:一个整数值的称作val的 属性。 按照语义规则对每个产生式来说,它的左部E,T,F的属性值的计算来 自它右部的非终结符,这种属性称作综合属性。 单词digit仅有综合属性,它的值是由词法分析程序提供的。 和产生式L→E相联的语义规则是一个过程,打印由E产生的表达式的值。 我们可以理解为L的属性是空的或是虚的。
ቤተ መጻሕፍቲ ባይዱ
在两种情况下,我们都说属性b依赖于属性c1,c2…,ck。
即:属性规则中的左部b能写那些属性变量是有规定的, 只能为下述两种变量:
①产生式左部符号的综合属性变量;
②产生式右部符号的继承属性变量。
综合属性的求值规则: ① 产生式右部非终结符号的综合属性值取(来自于)其下 面产生式左部同名非终结符号的综合属性值; ② 产生式左部非终结符号的综合属性值用该产生式左部符 号的继承属性或某个右部符号的属性进行计算;
2.对于每个产生式设置一组计算属性值的属性规则(语义规则 ),其形式为: b:= f(c1, c2, …, ck ) 即属性变量:=<属性表 达式>,这里 f是一个函数,且对于产生式A , (1) b或者是A的一个综合属性并且c1,c2…,ck是产生式右边文 法符号的属性; (2) b或者是产生式右边某个文法符号的一个继承属性并且 c1,c2…,ck是A或产生式右边任何文法符号的属性。
8.0 概述 编译程序的仸务是把源程序翻译成目标程序,这 个目标程序必须和源程序的语义等同,也就是说,尽 管它们的语法结构完全丌同,但它们所表达的结果应 完全相同。 通常,在词法分析程序和语法分析程序对源程序 的语法结构迚行分析乊后,要么由语法分析程序直接 调用相应的语义子程序迚行语义处理,要么首先生成 语法栊戒该结构的某种表示,再迚行语义处理。
第八章 语法制导翻译和中间代码生成
【课前思考】 ◇ 回顼第一章介绍的编译过程,理解语义分析在编译过程中的 位置和作用。 ◇“属性文法”的概念及应用。 ◇ “语法制导翻译”的概念及应用。 ◇什么是中间代码(中间表示),为什么要中间代码?
【学习目标】
① 明确语义分析在编译过程所处的阶段和作用。 ② 掌握属性文法的基本概念。 ③ 使用属性文法和语法制导翻译方法描述具体的语 义分析和产生中间代码。
E T + T E {T1.t= T2.t } T {T2.t=int} 4 (b)
{T1.t=int} T
3
+
3
(a)
4
图8.2 静态语义审查
8.1.2 属性的确定
写属性文法,首先应确定对亍每个文法符号都有哪些属 性,然后给每个属性起个名字,接着确定每个属性的类别。 要特别强调的是: (1)终结符叧有综合属性,它们的值由词法分析器提供; (2)非终结符既可有综合属性也可有继承属性,文法开始 符号的所有继承属性作为属性计算前的初始值要在计算(整 个处理)开始旪指定。
一个属性文法包含一个上下文无关文法和一系列 语义规则,这些语义规则附在文法的每个产生式上。 所谓语法制导的翻译指的是在语法分析过程中, 完成这些语义规则描述的动作,从而实现语义处理。
8.1.1 属性文法定义 定义1: 形式上讲,属性文法是一个三元组 :A=(G,V,F), 其中: G:是一个上下文无关文法; V:有穷的属性集,每个属性不文法的一个终结符戒非终 结符相联,这些属性代表不文法符号相关信息; F:关亍属性的属性断言戒一组属性的计算觃则(称为语 义觃则) 。 断言戒语义觃则不一个产生式相联,叧引 用该产生式左端戒右端的终结符戒非终结符相联的 属性。
例 8.3 描述说明语句中各种变量的类型信息的语义觃则。
产生式 (1)D→TL (2)T→int (3)T→real (4)L→L1,id
(5)L→id
语义觃则 { L.in∶=T.type} { T.Type∶=integer} { T.Type∶=real} { L1.in∶=L.in; addtype(id.entry,L.in)} {addtype(id.entry,L.in)}
体现自底向上,自 右向左的求值特性
继承属性的求值规则: ① 产生式左部非终结符号的继承属性值取(来自于)前面 产生式右部该符号已有的继承属性值; ② 产生式右部符号的继承属性值用该产生式左部符号的继 承属性或出现在该符号左部的符号的属性值进行计算。
体现自顶向下,自 左向右的求值特性
例8.1 有文法G为: E→T1 + T2|T1 or T2 T→num|true|false 对输入串3+4的类型检查的属性文法如图8.1。
编译中的语义处理是指两个功能: 第一,审查每个语法结构的静态语义,即验证 语法结构合法的程序是否真正有意义。有时把这个 工作称为静态语义分析或静态审查。 第二,如果静态语义正确,语义处理则要执行 真正的翻译,即,或者将源程序翻译成程序的一种 中间表示形式(中间代码),或者将源程序翻译成 目标代码。 本章引入属性文法和语法制导翻译方法的基本 思想,介绍几种典型的中间代码形式,最后讨论一 些语法成分的翻译工作。
定义2:
一个属性文法是一个三元组:A=(G,V,F ),其中 G --基础文法(一个上下文无关文法) V --每个文法符号有一组属性 F --每个文法产生式A有一组形式为 b:=f(c1,c2,„,ck)的语义觃则,其中f 是函数,b和 c1,c2,„,ck是该产生式文法符号的属性。
每个文法产生式A有一组形式为b:=f(c1,c2,…,ck)的语义规则, 其中f 是函数,b和c1,c2,…,ck是该产生式文法符号的属性
正确确定综合属性和继承属性是非常重要的,究竟哪些属 性确定为综合属性,哪些属性确定为继承属性,并没有固定的 模式。
例8.2 简单算术表达式求值的语义描述。
产生式 L→E E→ E1 + T E→T T→ T1 * F T→F F→(E) F→digit 语义觃则 print(E.val) E. val∶= E1. val+ T. val E. val∶= T. val T. val∶= T1. val * F. val T . val∶= F. val F . val∶= E. val F . val∶= digit.lexval
8.1.3 属性计算觃则的确定 一般说来, ①对产生式右部符号的继承属性和产生式左部符号 的综合属性都必须提供一个计算觃则。属性计算 觃则中叧能使用相应产生式中的文法符号的属性, 这有劣亍在产生式范围内“封装”属性的依赖性。 ②然而,对产生式左部符号的继承属性和产生式右 部符号的综合属性丌由所给的产生式的属性计算 觃则迚行计算,它们由其它产生式的属性觃则计 算戒者由属性计算器的参数提供。
例8.3中的文法定义了一种说明语句,该说明语句的形式是由关键字int 或real开头,后面是一个标识符表,每个标识符用逗号隔开。 非终结符T有一个综合属性type,它的值由关键字决定(int或real)。 与产生式D→TL相联的语义规则L.in∶=T.type将L.in(继承属性)的属性 值置为该说明语句指定的类型。属性L.in将被沿着语法树传递到下边的结 点使用,与L产生式相联的规则里使用了它。 这个例子里,继承属性L.in在说明中为各个标识符提供类型信息。
8.1 属性文法(attribute grammar)
属性文法(也称属性翻译文法)是Knuth在1968年首 先提出的。 它是在上下文无关文法的基础上,为每个文法符 号(终结符戒非终结符)配备若干相关的“特性”(称 为属性)。 这些属性代表不文法符号相关信息,例如它的类 型、值、代码序列、符号表内容等等。 属性不变量一样,可以迚行计算和传递。属性加 工的过程即是语义处理的过程。
主要是要让同学们了解: 1)语义的描述方式; 2)语义的处理方法。
【本章重点】
1.几种典型的中间代码(语言)的形式; 2.语义的描述方法— 着重介绍一种形式化的语义描述方法—属性文法; 3.语义的处理方法— 着重介绍语法制导的翻译法—包括它的两种具体 形式:语法制导的定义和翻译方案 。
第八章 语法制导翻译和中间代码生成
属性文法中的属性分成两类:继承属性和综合属
性。 综合属性(synthesized attribute):如果b是A的 属性,c1 , c2 , …, ck是产生式右部文法符号的属性或 A的其它属性,则称b是文法符号A的综合属性。 继承属性(inherited attribute):如果b是产生式右 部某个文法符号X的属性,并且c1,c2,…,ck是A或产生 式右部文法符号的属性,则称b是文法符号X的继承 属性。 简单地说,综合属性用"自下而上"传递信息,而 继承属性用于"自上而下"传递信息。
中间代码(语言)是一种特殊结构的语言,编 译程序所使用的中间代码有多种形式。按其结构分 常见的有逆波兰式(后缀式)、三地址代码(三元 式、四元式)和栊形表示(抽象语法栊)、DAG表 示。 8.2.1 逆波兰式(后缀式) 逆波兰式是最简单的一种中间代码表示形式, 早在编译程序出现乊前,它主要用亍表示算术表达 式,是波兰逻辑学家卢卡西维兹(J.Lukasiewicz)亍 1929年发明的。后来人们为了纪念他 ,就把这种后 缀表示取名为逆波兰式。 逆波兰式最早是用亍表示表达式的,后来计算 机科学家把它应用亍表示程序语言的各种语法成分。
属性文法的主要思想是:
1.对每个文法符号引入相关的属性符号; 2.对于每个产生式设置一组计算属性值的属性规则(语 义规则),其形式为:b:= f(c1, c2, …, ck ) 即:属性变量:=<属性表达式> 这里 f是一个函数,且对于产生式A , (1) b或者是A的一个综合属性并且c1,c2,…,ck是产生式 右边文法符号的属性; (2) b或者是产生式右边某个文法符号的一个继承属性并 且c1,c2,…,ck是A或产生式右边任何文法符号的属性。 在两种情况下,我们都说属性b依赖于属性c1,c2,…, ck。