第四章 语法制导的翻译 本章内容 1、介绍语义描述的一种形式方法:语法制导的翻译,它包括两种具体形式 语法制导的定义 翻译方案

Slides:



Advertisements
Similar presentations
XX啤酒营销及广告策略.
Advertisements

第四章:长期股权投资 长期股权投资效果 1、控制:50%以上 有权决定对方财务和经营.
编 译 原 理 指导教师:杨建国 二零一零年三月.
订单合并拆分功能详解 荷叶.
第五章 语法制导的翻译 赵建华 南京大学计算机系 2010年3月.
编译原理第二次习题课 王静.
跳楼价 亏本大甩卖 清仓处理 买一送一 5折酬宾. 跳楼价 亏本大甩卖 清仓处理 买一送一 5折酬宾.
清仓处理 跳楼价 满200返160 5折酬宾.
LR与LL分析 编译原理习题课二 胡云斌 PB

第三节 格林公式及其应用(2) 一、曲线积分与路径无关的定义 二、曲线积分与路径无关的条件 三、二元函数的全微分的求积 四、小结.
第三章 导数与微分 习 题 课 主要内容 典型例题.
北师大版七年级数学 5.5 应用一元一次方程 ——“希望工程”义演 枣庄市第三十四中学 曹馨.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
全国计算机等级考试 二级基础知识 第二章 程序设计基础.
海洋存亡 匹夫有责 ——让我们都来做环保小卫士 XX小学三(3)班.
XX信托 ·天鑫 9号集合资金信托计划 扬州广陵
第七章 中间代码生成 静态 中间 分析 检查 代码 记号流 器 生成 本章内容 介绍几种常用的中间表示:后缀表示、图形表示和三地址代码
7 Intermediate Representation
编译原理习题
2.2 语法分析器生成器YACC 分析器的构造步骤: 产生式→识别活前缀的DFA→分析表(+驱动器) YACC概述
CH6.属性文法语法制导翻译 《程序设计语言编译原理》 陈火旺等编著 2000年第3版
自上而下分析 4.4.
编译原理与技术 第7章 中间代码生成 3学时.
属性文法和语法制导翻译 授课:胡静.
第六章 属性文法和语法制导翻译 网上教学系统: : 编译原理
编译原理与技术 词法分析(1) 2018/11/28 《编译原理与技术》讲义.
第三章 词法分析.
管理信息结构SMI.
走进编程 程序的顺序结构(二).
辅导课程六.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
语义分析简介 编译程序的目标:将源程序翻译成为语义等价的目标程序。 语义分析的主流技术:
第六、七章属性文法、语法制导翻译和中间代码
第八章语法制导翻译和中间代码生成 8.1概述 8.2属性文法和语法制导翻译 8.3语义分析 8.4中间代码 8.5一些语句的翻译.
编译原理与技术 语法制导翻译 2019/1/17 《编译原理与技术》讲义.
第二章 Java语言基础.
中间代码生成.
语法制导的翻译 (Syntax-Directed Translation)
《编译原理与技术》 期末复习 计算机科学与技术学院 郑启龙 李 诚 25/12/2018.
第二章 词法分析 (Lexical Analysis)
第3,4次课 一个简单的语法制导翻译器 2.3~2.5.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
编译原理与技术 第4章 语法制导的翻译 6学时.
第七章 语义分析和中间代码生成 本章内容 介绍几种常用的中间表示:后缀表示、图形表示和三地址代码
C语言程序设计 主讲教师:陆幼利.
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
编译原理总结-1 第3~5章.
编译原理实践 13.语法分析程序的自动生成工具YACC.
第六章 语法制导的翻译 本章内容 介绍一种语义描述方法:语法制导的翻译,介绍语法制导的翻译的实现方法。
线 性 代 数 厦门大学线性代数教学组 2019年4月24日6时8分 / 45.
自底向上的语法分析 4.5.
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
第4章 Excel电子表格制作软件 4.4 函数(一).
实验三 16位算术逻辑运算实验 不带进位控制的算术运算 置AR=1: 设置开关CN 1 不带进位 0 带进位运算;
第九节 赋值运算符和赋值表达式.
3.16 枚举算法及其程序实现 ——数组的作用.
第三章 函数的微分学 第二节 导数的四则运算法则 一、导数的四则运算 二、偏导数的求法.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
業務員 傷害險通報作業 新光人壽內網-產險傷害險通報P2~P4 【個人】傷害險通報作業P5~P10 【團體】傷害險通報作業P11~P16
第二节 函数的极限 一、函数极限的定义 二、函数极限的性质 三、小结 思考题.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
鸡兔同笼(续) ——选择结构.
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
FPGA系统设计与实践 本章小结(第5章).
编译原理实践 6.程序设计语言PL/0.
一元一次方程的解法(-).
§2 自由代数 定义19.7:设X是集合,G是一个T-代数,为X到G的函数,若对每个T-代数A和X到A的函数,都存在唯一的G到A的同态映射,使得=,则称G(更严格的说是(G,))是生成集X上的自由T-代数。X中的元素称为生成元。 A变, 变 变, 也变 对给定的 和A,是唯一的.
第8章 语法制导翻译与中间代码生成.
Presentation transcript:

第四章 语法制导的翻译 本章内容 1、介绍语义描述的一种形式方法:语法制导的翻译,它包括两种具体形式 语法制导的定义 翻译方案 第四章 语法制导的翻译 本章内容 1、介绍语义描述的一种形式方法:语法制导的翻译,它包括两种具体形式 语法制导的定义 翻译方案 2、介绍语法制导翻译的实现方法

4.1 语法制导的定义 例 简单计算器的语法制导定义 产 生 式 语 义 规 则 L  E n print (E.val) 4.1 语法制导的定义 例 简单计算器的语法制导定义 产 生 式 语 义 规 则 L  E n print (E.val) E  E1 + T E.val = E1 .val + T.val E  T E.val = T.val T  T1  F T.val = T1.val  F.val T  F T.val = F.val F (E) F.val = E.val F  digit F.val = digit.lexval

4.1 语法制导的定义 4.1.1 语法制导定义的形式 基础文法 每个文法符号有一组属性 每个文法产生式A  有 4.1 语法制导的定义 4.1.1 语法制导定义的形式 基础文法 每个文法符号有一组属性 每个文法产生式A  有 一组形式为b=f(c1, c2, …, ck )的语义规则,其中 b和c1, c2, …, ck 是该产生式文法符号的属性, f 是函数 综合属性:如果b是A的属性,c1 , c2 , …, ck 是产生式右部文法符号的属性或A的其它属性 继承属性:如果b是右部某文法符号X的属性

4.1 语法制导的定义 4.1.2 综合属性 S属性定义:仅使用综合属性的语法制导定义 产 生 式 语 义 规 则 L  E n 4.1 语法制导的定义 4.1.2 综合属性 S属性定义:仅使用综合属性的语法制导定义 产 生 式 语 义 规 则 L  E n print (E.val) E  E1 + T E.val = E1 .val + T.val E  T E.val = T.val T  T1  F T.val = T1.val  F.val T  F T.val = F.val F (E) F.val = E.val F  digit F.val = digit.lexval

4.1 语法制导的定义 注释分析树:结点的属性值都标注出来的分析树 8+5*2 n的注释分析树 digit.lexval = 2 L 4.1 语法制导的定义 注释分析树:结点的属性值都标注出来的分析树 8+5*2 n的注释分析树 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n 4.1 语法制导的定义 分析树各结点属性的计算可以自下而上地完成 digit.lexval = 2 L E.val = 18 n T.val = 10 E.val = 8 T.val = 8 F.val = 8 digit.lexval = 8 T.val = 5 +  F.val = 5 F.val = 2 digit.lexval = 5

4.1 语法制导的定义 4.1.3 继承属性 int id, id, id 产 生 式 语 义 规 则 D  TL 4.1 语法制导的定义 4.1.3 继承属性 int id, id, id 产 生 式 语 义 规 则 D  TL L.in = T.type T int T. type = integer T real T. type = real L L1, id L1.in = L.in; addType(id.entry, L.in) L id

4.1 语法制导的定义 例 int id1, id2, id3的标注了部分属性的分析树 不可能像像综合属性那样自下而上标注属性 D 4.1 语法制导的定义 例 int id1, id2, id3的标注了部分属性的分析树 不可能像像综合属性那样自下而上标注属性 D int T.type = integer , id3 L.in = integer id2 id1

4.1 语法制导的定义 4.1.4 属性依赖图 例 int id1, id2, id3的分析树(虚线)的依赖图(实线) D  TL L.in = T.type D int T , id3 L id2 id1 1 entry 10 2 entry 3 entry in 9 8 in 7 6 in 5 4 type

4.1 语法制导的定义 4.1.4 属性依赖图 例 int id1, id2, id3的分析树(虚线)的依赖图(实线) L L1, id L1.in = L.in; addType (id.entry, L.in) D int T , id3 L id2 id1 1 entry 10 2 entry 3 entry in 9 8 in 7 6 in 5 4 type

4.1 语法制导的定义 4.1.4 属性依赖图 例 int id1, id2, id3的分析树(虚线)的依赖图(实线) L id 4.1 语法制导的定义 4.1.4 属性依赖图 例 int id1, id2, id3的分析树(虚线)的依赖图(实线) L id addType (id.entry, L.in) D int T , id3 L id2 id1 1 entry 10 2 entry 3 entry in 9 8 in 7 6 in 5 4 type

4.1 语法制导的定义 4.1.5 属性计算次序 1、拓扑排序:结点的一种排序,使得边只会从该次序中先出现的结点到后出现的结点 4.1 语法制导的定义 4.1.5 属性计算次序 1、拓扑排序:结点的一种排序,使得边只会从该次序中先出现的结点到后出现的结点 例 1,2,3,4,5,6,7,8,9,10 D int T , id3 L id2 id1 1 entry 10 2 entry 3 entry in 9 8 in 7 6 in 5 4 type

4.1 语法制导的定义 4.1.5 属性计算次序 2、属性计算次序:构造输入的分析树 D int T , id3 L id2 id1 4.1 语法制导的定义 4.1.5 属性计算次序 2、属性计算次序:构造输入的分析树 D int T , id3 L id2 id1 1 entry 10 2 entry 3 entry in 9 8 in 7 6 in 5 4 type

4.1 语法制导的定义 4.1.5 属性计算次序 2、属性计算次序:构造输入的分析树,构造属性依赖图 D int T , id3 L id2 4.1 语法制导的定义 4.1.5 属性计算次序 2、属性计算次序:构造输入的分析树,构造属性依赖图 D int T , id3 L id2 id1 1 entry 10 2 entry 3 entry in 9 8 in 7 6 in 5 4 type

4.1 语法制导的定义 4.1.5 属性计算次序 2、属性计算次序:构造输入的分析树,构造属性依赖图,对结点进行拓扑排序 D int T , 4.1 语法制导的定义 4.1.5 属性计算次序 2、属性计算次序:构造输入的分析树,构造属性依赖图,对结点进行拓扑排序 D int T , id3 L id2 id1 1 entry 10 2 entry 3 entry in 9 8 in 7 6 in 5 4 type

4.1 语法制导的定义 4.1.5 属性计算次序 2、属性计算次序:构造输入的分析树,构造属性依赖图,对结点进行拓扑排序,按拓扑排序的次序计算属性 D int T , id3 L id2 id1 1 entry 10 2 entry 3 entry in 9 8 in 7 6 in 5 4 type

4.1 语法制导的定义 语义规则的计算方法 分析树方法:刚才介绍的方法,动态确定计算次序,效率低 概念上的一般方法 4.1 语法制导的定义 语义规则的计算方法 分析树方法:刚才介绍的方法,动态确定计算次序,效率低 概念上的一般方法 基于规则的方法:(编译器实现者)静态确定(编译器设计者提供的)语义规则的计算次序 适用于手工构造的方法 忽略规则的方法:(编译器实现者)事先确定属性的计算策略(如边分析边计算),(编译器设计者提供的)语义规则必须符合所选分析方法的限制 适用于自动生成的方法

4.2 S属性定义的自下而上计算 4.2.1 语法树 语法树是分析树的浓缩表示:算符和关键字是作为内部结点 语法制导翻译可以基于分析树,也可以基于语法树 语法树的例子: if B then S1 else S2 8 + 5  2 if-then-else B S1 S2 + * 2 5 8

4.2 S属性定义的自下而上计算 4.2.2 构造语法树的语法制导定义 产 生 式 语 义 规 则 E  E1 + T 产 生 式 语 义 规 则 E  E1 + T E.nptr = mkNode( ‘+’, E1.nptr, T.nptr) E  T E.nptr = T.nptr T  T1  F T.nptr = mkNode( ‘’, T1.nptr, F.nptr) T  F T.nptr = F.nptr F  (E) F.nptr = E.nptr F  id F.nptr = mkLeaf (id, id.entry) F  num F.nptr = mkLeaf (num, num.val)

4.2 S属性定义的自下而上计算 a+5b的语法树的构造 指向符号表中a的入口 指向符号表中b的入口 E.nptr + T.nptr  F.nptr id +  num num 5 指向符号表中a的入口 指向符号表中b的入口

4.2 S属性定义的自下而上计算 a+5b的语法树的构造 指向符号表中a的入口 指向符号表中b的入口 E.nptr + T.nptr  F.nptr id +  num num 5 指向符号表中a的入口 指向符号表中b的入口

4.2 S属性定义的自下而上计算 a+5b的语法树的构造 指向符号表中a的入口 指向符号表中b的入口 E.nptr + T.nptr  F.nptr id +  num num 5 指向符号表中a的入口 指向符号表中b的入口

4.2 S属性定义的自下而上计算 a+5b的语法树的构造 指向符号表中a的入口 指向符号表中b的入口 E.nptr + T.nptr  F.nptr id +  num num 5 指向符号表中a的入口 指向符号表中b的入口

4.2 S属性定义的自下而上计算 a+5b的语法树的构造 指向符号表中a的入口 指向符号表中b的入口 E.nptr + T.nptr  F.nptr id +  num num 5 指向符号表中a的入口 指向符号表中b的入口

4.2 S属性定义的自下而上计算 a+5b的语法树的构造 指向符号表中a的入口 指向符号表中b的入口 E.nptr + T.nptr  F.nptr id +  num num 5 指向符号表中a的入口 指向符号表中b的入口

4.2 S属性定义的自下而上计算 a+5b的语法树的构造 指向符号表中a的入口 指向符号表中b的入口 E.nptr + T.nptr  F.nptr id +  num num 5 指向符号表中a的入口 指向符号表中b的入口

4.2 S属性定义的自下而上计算 a+5b的语法树的构造 指向符号表中a的入口 指向符号表中b的入口 E.nptr + T.nptr  F.nptr id +  num num 5 指向符号表中a的入口 指向符号表中b的入口

4.2 S属性定义的自下而上计算 a+5b的语法树的构造 指向符号表中a的入口 指向符号表中b的入口 E.nptr + T.nptr  F.nptr id +  num num 5 指向符号表中a的入口 指向符号表中b的入口

4.2 S属性定义的自下而上计算 4.2.3 S属性的自下而上计算 LR分析器的栈增加一个域来保存综合属性值 若产生式A →XYZ的语义规则是 A.a = f (X.x, Y.y, Z.z), 那么归约后: . . . Z Z. z Y Y. y X X.x top . . . A A.a top 栈 state val

4.2 S属性定义的自下而上计算 简单计算器的语法制导定义改成栈操作代码 产 生 式 语 义 规 则 L  E n 产 生 式 语 义 规 则 L  E n print (E.val) E  E1 + T E.val =E1 .val +T.val E  T E.val = T.val T  T1  F T.val = T1.val  F.val T  F T.val = F.val F (E) F.val = E.val F  digit F.val = digit.lexval . . . Z Z. z Y Y. y X X.x top 栈 state val

4.2 S属性定义的自下而上计算 简单计算器的语法制导定义改成栈操作代码 产 生 式 代 码 段 L  E n print (E.val) 产 生 式 代 码 段 L  E n print (E.val) E  E1 + T E.val =E1 .val +T.val E  T E.val = T.val T  T1  F T.val = T1.val  F.val T  F T.val = F.val F (E) F.val = E.val F  digit F.val = digit.lexval . . . Z Z. z Y Y. y X X.x top 栈 state val

4.2 S属性定义的自下而上计算 简单计算器的语法制导定义改成栈操作代码 产 生 式 代 码 段 L  E n 产 生 式 代 码 段 L  E n print (val [ top1] ) E  E1 + T E.val =E1 .val +T.val E  T E.val = T.val T  T1  F T.val = T1.val  F.val T  F T.val = F.val F (E) F.val = E.val F  digit F.val = digit.lexval . . . Z Z. z Y Y. y X X.x top 栈 state val

4.2 S属性定义的自下而上计算 简单计算器的语法制导定义改成栈操作代码 产 生 式 代 码 段 L  E n 产 生 式 代 码 段 L  E n print (val [ top1] ) E  E1 + T val [top 2 ] = val [top 2]+val [top] E  T E.val = T.val T  T1  F T.val = T1.val  F.val T  F T.val = F.val F (E) F.val = E.val F  digit F.val = digit.lexval . . . Z Z. z Y Y. y X X.x top 栈 state val

4.2 S属性定义的自下而上计算 简单计算器的语法制导定义改成栈操作代码 产 生 式 代 码 段 L  E n 产 生 式 代 码 段 L  E n print (val [ top1] ) E  E1 + T val [top 2 ] = val [top 2]+val [top] E  T T  T1  F T.val = T1.val  F.val T  F T.val = F.val F (E) F.val = E.val F  digit F.val = digit.lexval . . . Z Z. z Y Y. y X X.x top 栈 state val

4.2 S属性定义的自下而上计算 简单计算器的语法制导定义改成栈操作代码 产 生 式 代 码 段 L  E n 产 生 式 代 码 段 L  E n print (val [ top1] ) E  E1 + T val [top 2 ] = val [top 2]+val [top] E  T T  T1  F val [top 2]val [top] T  F T.val = F.val F (E) F.val = E.val F  digit F.val = digit.lexval . . . Z Z. z Y Y. y X X.x top 栈 state val

4.2 S属性定义的自下而上计算 简单计算器的语法制导定义改成栈操作代码 产 生 式 代 码 段 L  E n 产 生 式 代 码 段 L  E n print (val [ top1] ) E  E1 + T val [top 2 ] = val [top 2]+val [top] E  T T  T1  F val [top 2]val [top] T  F F (E) F.val = E.val F  digit F.val = digit.lexval . . . Z Z. z Y Y. y X X.x top 栈 state val

4.2 S属性定义的自下而上计算 简单计算器的语法制导定义改成栈操作代码 产 生 式 代 码 段 L  E n 产 生 式 代 码 段 L  E n print (val [ top1] ) E  E1 + T val [top 2 ] = val [top 2]+val [top] E  T T  T1  F val [top 2]val [top] T  F F (E) val [top 1] F  digit F.val = digit.lexval . . . Z Z. z Y Y. y X X.x top 栈 state val

4.2 S属性定义的自下而上计算 简单计算器的语法制导定义改成栈操作代码 产 生 式 代 码 段 L  E n 产 生 式 代 码 段 L  E n print (val [ top1] ) E  E1 + T val [top 2 ] = val [top 2]+val [top] E  T T  T1  F val [top 2]val [top] T  F F (E) val [top 1] F  digit . . . Z Z. z Y Y. y X X.x top 栈 state val

4.3 L属性定义的自上而下计算 边分析边翻译的方式能否用于继承属性? 属性的计算次序一定受分析方法所限定的分析树结点建立次序的限制 分析树的结点是自左向右生成 如果属性信息是自左向右流动,那么就有可能在分析的同时完成属性计算

4.3 L属性定义的自上而下计算 4.3.1 L属性定义 如果每个产生式AX1…Xj-1Xj…Xn的每条语义规则计算的属性是A的综合属性;或者是Xj 的继承属性,但它仅依赖: 该产生式中Xj左边符号X1, X2, …, Xj-1的属性; A的继承属性 S属性定义属于L属性定义

4.3 L属性定义的自上而下计算 变量类型声明的语法制导定义是一个L属性定义 产 生 式 语 义 规 则 D  TL 产 生 式 语 义 规 则 D  TL L.in = T.type T int T. type = integer T real T. type = real L L1, id L1.in = L.in; addType(id.entry, L.in) L id

4.3 L属性定义的自上而下计算 4.3.2 翻译方案 例 把有加和减的中缀表达式翻译成后缀表达式 例 把有加和减的中缀表达式翻译成后缀表达式 如果输入是8+5 2,则输出是8 5 + 2  E  T R R  addop T {print (addop.lexeme)} R1 |  T  num {print (num.val)} E  T R  num {print (8)} R  num{print (8)}addop T{print (+)}R  num{print(8)}addop num{print(5)}{print (+)}R … {print(8)}{print(5)}{print(+)}addop T{print()}R … {print(8)}{print(5)}{print(+)}{print(2)}{print()}

4.3 L属性定义的自上而下计算 例 数学排版语言EQN E sub 1 .val E .val S  B B  B1 B2 B  B1 sub B2 B  text E 1 .val

4.3 L属性定义的自上而下计算 例 数学排版语言EQN(语法制导定义) E sub 1 .val E .val 产 生 式 语 义 规 则 产 生 式 语 义 规 则 S  B B.ps = 10; S.ht = B.ht B  B1 B2 B1.ps = B.ps; B2.ps = B.ps; B.ht = max(B1.ht, B2.ht ) B  B1 sub B2 B1.ps =B.ps; B2.ps = shrink(B.ps); B.ht = disp (B1.ht, B2.ht ) B  text B.ht = text.h  B.ps

4.3 L属性定义的自上而下计算 例 数学排版语言EQN(翻译方案) S  {B.ps = 10 } B继承属性的计算 B {S.ht = B.ht } 位于B的左边

4.3 L属性定义的自上而下计算 例 数学排版语言EQN(翻译方案) S  {B.ps = 10 } B综合属性的计算 B {S.ht = B.ht } 放在右部末端

4.3 L属性定义的自上而下计算 例 数学排版语言EQN(翻译方案) S  {B.ps = 10 } B {S.ht = B.ht }  B  {B1.ps = B.ps } B1 {B2.ps = B.ps } B2 {B.ht = max(B1.ht, B2.ht ) }  B  { B1.ps =B.ps } B1 sub { B2.ps = shrink(B.ps) } B2 {B.ht = disp (B1.ht, B2.ht ) }  B  text {B.ht = text.h  B.ps } 58

4.3 L属性定义的自上而下计算 例 左递归的消除引起继承属性 产 生 式 语 义 规 则 E  E1 + T 例 左递归的消除引起继承属性 产 生 式 语 义 规 则 E  E1 + T E.nptr = mkNode( ‘+’, E1.nptr, T.nptr) E  T E.nptr = T.nptr T  T1F T.nptr = mkNode( ‘’, T1.nptr, F.nptr) T  F T.nptr = F.nptr F  (E) F.nptr = E.nptr F  id F.nptr = mkLeaf (id, id.entry) F  num F.nptr = mkLeaf (num, num.val)

4.3 L属性定义的自上而下计算 E  T {R.i = T.nptr} T + T + T + … R {E.nptr = R.s} T {R1.i = mkNode ( ‘+’, R.i, T.nptr)} R1 {R.s = R1.s} R   {R.s = R.i } T  F {W.i = F.nptr} W {T.nptr = W.s} W   F {W1.i = mkNode ( ‘’, W.i, F.nptr)} W1 {W.s = W1.s} W   {W.s = W.i } F 产生式部分不再给出

4.3 L属性定义的自上而下计算 略去了E  TR  T 部分 T i W F.nptr id  i W num i W s  指向符号表中a的入口 指向符号表中b的入口 i W s i W  略去了E  TR  T 部分

4.3 L属性定义的自上而下计算 略去了E  TR  T 部分 T i W F.nptr id  i W num i W s  指向符号表中a的入口 指向符号表中b的入口 i W s i W  略去了E  TR  T 部分

4.3 L属性定义的自上而下计算 略去了E  TR  T 部分 T i W F.nptr id  i W num i W s  指向符号表中a的入口 指向符号表中b的入口 i W s i W  略去了E  TR  T 部分

4.3 L属性定义的自上而下计算 略去了E  TR  T 部分 T i W F.nptr id  i W num i W s  指向符号表中a的入口 指向符号表中b的入口 i W s i W  略去了E  TR  T 部分

4.3 L属性定义的自上而下计算 略去了E  TR  T 部分 T i W F.nptr id  i W num i W s  指向符号表中a的入口 指向符号表中b的入口 i W s i W  略去了E  TR  T 部分

4.3 L属性定义的自上而下计算 略去了E  TR  T 部分 T i W F.nptr id  i W num i W s  指向符号表中a的入口 指向符号表中b的入口 i W s i W  略去了E  TR  T 部分

4.3 L属性定义的自上而下计算 略去了E  TR  T 部分 T i W F.nptr id  i W num i W s  指向符号表中a的入口 指向符号表中b的入口 i W s i W  略去了E  TR  T 部分

4.3 L属性定义的自上而下计算 略去了E  TR  T 部分 T i W F.nptr id  i W num i W s  指向符号表中a的入口 指向符号表中b的入口 i W s i W  略去了E  TR  T 部分

4.3 L属性定义的自上而下计算 4.3.3 预测翻译器的设计 把预测分析器的构造方法推广到翻译方案的实现 产生式R  +TR |  的分析过程 void R( ) { if (lookahead == '+' ) { match ( '+' ); T( ); R( ); } else / 什么也不做 /

4.3 L属性定义的自上而下计算 i1 = mkNode(addoplexeme, i , nptr); syntaxTreeNode R (syntaxTreeNode i) { syntaxTreeNode nptr, i1, s1, s; char addoplexeme; if (lookahead == '+' ) { / 产生式 R  +T R / addoplexeme = lexval; match('+' ); nptr = T(); i1 = mkNode(addoplexeme, i , nptr); s1 = R (i1); s = s1; } else s = i; / 产生式 R   / return s; R : i, s T : nptr + : addoplexeme

4.3 L属性定义的自上而下计算 4.3.4 用综合属性代替继承属性 Pascal的声明,如m, n : integer D  L : T (非L属性定义) T  integer | char L  L, id | id 信息从右向左流,归约从左向右,两者不一致

4.3 L属性定义的自上而下计算 4.3.4 用综合属性代替继承属性 Pascal的声明,如m, n : integer D  L : T (非L属性定义) T  integer | char L  L, id | id 等所需信息获得后再归约 改成从右向左归约 D  id L L  , id L | : T D : L , id integer T

4.3 L属性定义的自上而下计算 D  id L { addtype (id. entry, L. type)} L  , id L1 {L. type = L1. Type; addtype (id. entry, L1. type)} L  : T {L. type = T. type} T  integer {T. type = integer} T  real {T. type = real} D : L , id integer T

4.4 L属性的自下而上计算 在自下而上分析的框架中实现L属性定义的方法 它能实现任何基于LL(1)文法的L属性定义 也能实现许多(但不是所有的)基于LR(1) 的L属性定义

4.4 L属性的自下而上计算 4.4.1 删除翻译方案中嵌入的动作 E  T R R  + T {print (‘+’)}R1 |  T {print (‘’)}R1 |  T  num {print (num.val)} 在文法中加入产生的标记非终结符,让每个嵌入动作由不同标记非终结符M代表,并把该动作放在产生式M  的右端 R  + T M R1 |  T N R1 |  M   {print (‘+’)} N   {print (‘’)} 这些动作的一个重要 特点: 没有引用原来产生式 文法符号的属性

4.4 L属性的自下而上计算 4.4.2 分析栈上的继承属性 例 int p, q, r D  T {L.in = T.type} L T int {T. type = integer} T real {T. type = real} L {L1.in = L.in } L1, id {addtype (id.entry, L.in )} L id {addtype (id.entry, L.in )}

4.4 L属性的自下而上计算 4.4.2 分析栈上的继承属性 D T L , r q p int  type in 1、属性位置能预测 例 int p, q, r D  T {L.in = T.type} L T int {T. type = integer} T real {T. type = real} L {L1.in = L.in } L1, id {addtype (id.entry, L.in )} L id {addtype (id.entry, L.in )}

4.4 L属性的自下而上计算 4.4.2 分析栈上的继承属性 D T L , r q p int  type in 1、属性位置能预测 例 int p, q, r D  T {L.in = T.type} L T int {T. type = integer} T real {T. type = real} L {L1.in = L.in } L1, id {addtype (id.entry, L.in )} L id {addtype (id.entry, L.in )} 继承属性的计算可 以略去,引用继承属 性的地方改成引用其 他符号的综合属性

4.4 L属性的自下而上计算 D T L , r q p int  type in 产 生 式 代 码 段 D  TL T int 代 码 段 D  TL T int val[top] = integer T real val[top] = real L L1, id addType(val[top], val[top3]) L id addType(val[top], val[top1])

4.4 L属性的自下而上计算 2、属性的位置不能预测 S  aAC C.i = A.s S  bABC C.i = A.s C  c C.s = g(C.i) 增加标记非终结符,使得位置可以预测 S  bABMC M.i = A.s; C.i = M.s M   M.s = M.i

4.4 L属性的自下而上计算 2、属性的位置不能预测 S  aAC C.i = A.s S  bABC C.i = A.s C  c C.s = g(C.i) 增加标记非终结符,使得位置可以预测 S  bABMC M.i = A.s; C.i = M.s C  c C.s = g(C.i) 还得考虑M.s M   M.s = M.i 计算的可预测

4.4 L属性的自下而上计算 4.4.3 模拟继承属性的计算 继承属性是某个综合属性的一个函数 S  aAC C.i = f (A.s) C  c C.s = g(C.i) 增加标记非终结符,把f(A.s)的计算移到对标记非终结符归约时进行 S  aANC N.i = A.s; C.i = N.s N   N.s = f (N.i)

4.4 L属性的自下而上计算 例 数学排版语言EQN S  {B.ps = 10 } B {S.ht = B.ht }  B  {B1.ps = B.ps } B1 {B2.ps = B.ps } B2 {B.ht = max(B1.ht, B2.ht ) }  B  { B1.ps =B.ps } B1 sub { B2.ps = shrink(B.ps) } B2 {B.ht = disp (B1.ht, B2.ht ) }  B  text {B.ht = text.h  B.ps }

4.4 L属性的自下而上计算 产 生 式 语 义 规 则 S  LB B.ps = L.s; S.ht = B.ht L   产 生 式 语 义 规 则 S  LB B.ps = L.s; S.ht = B.ht L   L.s = 10 将B.ps存入栈中,便于引用 B  B1 MB2 B1.ps = B.ps; M.i = B.ps; B2.ps = M.s;B.ht = max(B1.ht, B2.ht ) M   M.s = M.i B  B1 sub NB2 B1.ps =B.ps; N.i = B.ps; B2.ps = N.s; B.ht = disp (B1.ht, B2.ht ) N   N.s = shrink(N.i) B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 产 生 式 语 义 规 则 S  LB B.ps = L.s; S.ht = B.ht L   产 生 式 语 义 规 则 S  LB B.ps = L.s; S.ht = B.ht L   L.s = 10 将B.ps存入栈中,便于引用 B  B1 MB2 B1.ps = B.ps; M.i = B.ps; B2.ps = M.s;B.ht = max(B1.ht, B2.ht ) M   M.s = M.i 单纯为了属性位置可预测 B  B1 sub NB2 B1.ps =B.ps; N.i = B.ps; B2.ps = N.s; B.ht = disp (B1.ht, B2.ht ) N   N.s = shrink(N.i) B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 产 生 式 语 义 规 则 S  LB B.ps = L.s; S.ht = B.ht L   产 生 式 语 义 规 则 S  LB B.ps = L.s; S.ht = B.ht L   L.s = 10 将B.ps存入栈中,便于引用 B  B1 MB2 B1.ps = B.ps; M.i = B.ps; B2.ps = M.s;B.ht = max(B1.ht, B2.ht ) M   M.s = M.i 单纯为了属性位置可预测 B  B1 sub NB2 B1.ps =B.ps; N.i = B.ps; B2.ps = N.s; B.ht = disp (B1.ht, B2.ht ) N   N.s = shrink(N.i) 兼有计算功能 B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 举例说明 在text归约成B时,B的ps属性 都在次栈顶位置 S M s B  L s text sub N s

4.4 L属性的自下而上计算 产 生 式 语 义 规 则 S  LB B.ps = L.s; S.ht = B.ht L   产 生 式 语 义 规 则 S  LB B.ps = L.s; S.ht = B.ht L   L.s = 10 B  B1 MB2 B1.ps = B.ps; M.i = B.ps; B2.ps = M.s;B.ht = max(B1.ht, B2.ht ) M   M.s = M.i B  B1 sub NB2 B1.ps =B.ps; N.i = B.ps; B2.ps = N.s; B.ht = disp (B1.ht, B2.ht ) N   N.s = shrink(N.i) B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 产 生 式 代 码 段 S  LB val[top1] = val[top] L   L.s = 10 产 生 式 代 码 段 S  LB val[top1] = val[top] L   L.s = 10 B  B1 MB2 B1.ps = B.ps; M.i = B.ps; B2.ps = M.s;B.ht = max(B1.ht, B2.ht ) M   M.s = M.i B  B1 sub NB2 B1.ps =B.ps; N.i = B.ps; B2.ps = N.s; B.ht = disp (B1.ht, B2.ht ) N   N.s = shrink(N.i) B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 产 生 式 代 码 段 S  LB val[top1] = val[top] L   产 生 式 代 码 段 S  LB val[top1] = val[top] L   val[top+1] = 10 B  B1 MB2 B1.ps = B.ps; M.i = B.ps; B2.ps = M.s;B.ht = max(B1.ht, B2.ht ) M   M.s = M.i B  B1 sub NB2 B1.ps =B.ps; N.i = B.ps; B2.ps = N.s; B.ht = disp (B1.ht, B2.ht ) N   N.s = shrink(N.i) B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 产 生 式 代 码 段 S  LB val[top1] = val[top] L   产 生 式 代 码 段 S  LB val[top1] = val[top] L   val[top+1] = 10 B  B1 MB2 val[top2] = max(val[top2], val[top]) M   M.s = M.i B  B1 sub NB2 B1.ps =B.ps; N.i = B.ps; B2.ps = N.s; B.ht = disp (B1.ht, B2.ht ) N   N.s = shrink(N.i) B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 产 生 式 代 码 段 S  LB val[top1] = val[top] L   产 生 式 代 码 段 S  LB val[top1] = val[top] L   val[top+1] = 10 B  B1 MB2 val[top2] = max(val[top2], val[top]) M   val[top+1] = val[top1] B  B1 sub NB2 B1.ps =B.ps; N.i = B.ps; B2.ps = N.s; B.ht = disp (B1.ht, B2.ht ) N   N.s = shrink(N.i) B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 产 生 式 代 码 段 S  LB val[top1] = val[top] L   产 生 式 代 码 段 S  LB val[top1] = val[top] L   val[top+1] = 10 B  B1 MB2 val[top2] = max(val[top2], val[top]) M   val[top+1] = val[top1] B  B1 sub NB2 val[top3] = disp (val[top3], val[top] ) N   N.s = shrink(N.i) B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 产 生 式 代 码 段 S  LB val[top1] = val[top] L   产 生 式 代 码 段 S  LB val[top1] = val[top] L   val[top+1] = 10 B  B1 MB2 val[top2] = max(val[top2], val[top]) M   val[top+1] = val[top1] B  B1 sub NB2 val[top3] = disp (val[top3], val[top] ) N   val[top+1] = shrink(val[top2]) B  text B.ht = text.h  B.ps

4.4 L属性的自下而上计算 产 生 式 代 码 段 S  LB val[top1] = val[top] L   产 生 式 代 码 段 S  LB val[top1] = val[top] L   val[top+1] = 10 B  B1 MB2 val[top2] = max(val[top2], val[top]) M   val[top+1] = val[top1] B  B1 sub NB2 val[top3] = disp (val[top3], val[top] ) N   val[top+1] = shrink(val[top2]) B  text val[top] = val[top]  val[top1]

本 章 要 点 语义规则的两种描述方法:语法制导的定义和翻译方案 设计简单问题的语法制导定义和翻译方案,这是本章的重点和难点 本 章 要 点 语义规则的两种描述方法:语法制导的定义和翻译方案 设计简单问题的语法制导定义和翻译方案,这是本章的重点和难点 语法制导定义和翻译方案的实现 S属性的自下而上计算(边分析边计算) L属性的自上而下计算(边分析边计算) L属性的自下而上计算(边分析边计算) 不再介绍先分析后计算的方法 不能边分析边计算的情况是存在的,见5.6节

例 题 1 下面是产生字母表 = {0, 1, 2}上数字串的一个 文法: S  D S D | 2 D  0 | 1 例 题 1 下面是产生字母表 = {0, 1, 2}上数字串的一个 文法: S  D S D | 2 D  0 | 1 写一个语法制导定义,判断它接受的句子是否为回文 数 S  S print(S.val) S  D1 S1 D2 S.val = (D1.val == D2.val) and S1.val S  2 S.val = true D  0 D.val = 0 D  1 D.val = 1

例 题 2 为下面文法写一个语法制导的定义,用S的综合属性val 给出下面文法中S产生的二进制数的值。例如,输入 例 题 2 为下面文法写一个语法制导的定义,用S的综合属性val 给出下面文法中S产生的二进制数的值。例如,输入 101.101时,S.val = 5.625(可以修改文法) 若按22+ 0 + 20 + 2-1 + 0 + 2-3来计算,该文法对小数点 左边部分的计算不利,因为需要继承属性来确定每个B 离开小数点的距离 S  L . L | L L  L B | B B  0 | 1 S . L B

例 题 2 为下面文法写一个语法制导的定义,用S的综合属性val 给出下面文法中S产生的二进制数的值。例如,输入 例 题 2 为下面文法写一个语法制导的定义,用S的综合属性val 给出下面文法中S产生的二进制数的值。例如,输入 101.101时,S.val = 5.625(可以修改文法) 若小数点左边按(1  2 + 0)  2 + 1计算。该办法不能 直接用于小数点右边,需改成((1  2 + 0)  2 + 1)/23, 这时需要综合属性来统计B的个数 S  L . L | L L  L B | B B  0 | 1 S . L B

例 题 2 为下面文法写一个语法制导的定义,用S的综合属性val 给出下面文法中S产生的二进制数的值。例如,输入 例 题 2 为下面文法写一个语法制导的定义,用S的综合属性val 给出下面文法中S产生的二进制数的值。例如,输入 101.101时,S.val = 5.625(可以修改文法) 更清楚的办法是将文法改成下面的形式 S  L . R | L L  L B | B R  B R | B B  0 | 1 S . L B R

例 题 2 S  L . R S. val = L. val + R. val S  L S. val = L. val 例 题 2 S  L . R S. val = L. val + R. val S  L S. val = L. val L  L1 B L. val = L1. val 2 + B. val L  B L. val = B. val R  B R1 R. val = R1. val / 2 + B. val / 2 R  B R. val = B. val / 2 B  0 B. val = 0 B  1 B. val = 1

例 题 3 给出把中缀表达式翻译成没有冗余括号的中 缀表达式的语法制导定义。例如,因为和是 左结合, 例 题 3 给出把中缀表达式翻译成没有冗余括号的中 缀表达式的语法制导定义。例如,因为和是 左结合, ((a  (b + c ))  (d ))可以重写成a  (b + c )  d 两种方法: 先把表达式的括号都去掉,然后在必要的地方再加括号 去掉表达式中的冗余括号,保留必要的括号

例 题 3 第一种方法 S  E print ( E. code ) E  E1 + T if T. op == plus then 例 题 3 第一种方法 S  E print ( E. code ) E  E1 + T if T. op == plus then E.code =E1.code||“+”||“(”||T.code||“)” else E. code = E1. code || “+” || T. code; E. op = plus E  T E. code = T. code; E. op = T. op

例 题 3 T  T1  F if (F. op == plus) or (F. op == times) then 例 题 3 T  T1  F if (F. op == plus) or (F. op == times) then if T1. op == plus then T. code = “(” || T1. code || “)” || “” || “(” || F. code || “)” else T. code = T1. code || “” || “(” || F. code || “)” else if T1. op = plus then T. code = “(” || T1. code || “)” || “” || F. code T. code = T1. code || “” || F. code; T. op = times

例 题 3 T  F T. code = F. code; T. op = F. op F  id 例 题 3 T  F T. code = F. code; T. op = F. op F  id F. code = id. lexeme; F. op = id F  ( E ) F. code = E. code; F. op = E. op

例 题 3 第二种方法 给E,T和F两个继承属性left_op和right_op 分别表示左右两侧算符的优先级 例 题 3 第二种方法 给E,T和F两个继承属性left_op和right_op 分别表示左右两侧算符的优先级 给它们一个综合属性self_op表示自身主算符的优先级 再给一个综合属性code表示没有冗余括号的代码 分别用1和2表示加和乘的优先级,用3表示id和(E)的优先级,用0表示左侧或右侧没有运算对象的情况

例 题 3 S  E E. left_op = 0; E. right_op = 0; print ( E. code ) 例 题 3 S  E E. left_op = 0; E. right_op = 0; print ( E. code ) E  E1 + T E1. left_op = E. left_op; E1. right_op = 1; T. left_op = 1; T. right_op = E. right_op; E.code =E1.code|| “+” || T. code ; E. self_op = 1; E  T T. left_op = E. left_op; T. right_op = E. right_op; E. code = T. code; E. self_op = T. self_op

例 题 3 T  T1  F . . . T  F . . . F  id F. code = id. lexeme; F. self_op = 3

例 题 3 F  ( E ) E. left_op = 0; E. right_op = 0; F. self_op = 例 题 3 F  ( E ) E. left_op = 0; E. right_op = 0; F. self_op = if (F. left_op < E. self_op) and (E. self_op >= F. right_op) then E. self_op else 3 F. code = then E. code else “(” || E. code || “)”

习 题 第一次 4.1,4.3,4.5 第二次 4.7,4.9, 4.10 第三次 4.13,4.14