第六章 中间代码生成 主要内容 常见的中间代码结构 语法制导方法概论 四元式中间代码生成过程.

Slides:



Advertisements
Similar presentations
陋室銘 劉禹錫 立人國中小丹老師編製 劉禹錫二三事 司空見慣 劉禹錫才氣縱橫,卻恃才傲物,一生落拓時候 多,當他貶為蘇州刺史時,司空李紳請他喝酒, 並請了一個貌美清秀的歌妓獻唱,他大為心動 寫了一首詩:「高髻雲鬢新樣妝,春風一曲杜 韋娘,司空見慣渾閒事,斷盡蘇州刺史腸。」 李紳明白其中寓意,便將歌妓送給他。而「司.
Advertisements

七年级数学校本课程 台山市任远中学 李锦明. 1. 最古老的过河问题 1. 最古老的过河问题 一个农民携带一只狼,一只羊和一 箱卷心菜,要借助一条小船过河。 小船上除了农民只能再带狼、羊、 卷心菜中的一样。而农民不在时, 狼会吃羊,羊会吃菜。农民如何过 河呢?
专题复习 --- 走进名著 亲近经典 读完《鲁滨孙漂流记》这本精彩的小说 后,一个高大的形象时时浮现在我的眼 前,他就是勇敢的探险家、航海家鲁滨 孙。他凭着顽强的毅力,永不放弃的精 神,实现了自己航海的梦想。 我仿佛看到轮船甲板上站着这样的一 个人:他放弃了富裕而又舒适的生活, 厌恶那庸庸碌碌的人生,从而开始了一.
第五章 企业所得税、个人所得税.
九十五年國文科命題知能 研習分享.
說 劍 《莊子‧雜篇》─ 第 一 組 賴泊錞 謝孟儒 張維真 羅苡芸
必修2 第一单元 古代中国经济的基本结构和特点
德 国 鼓 励 生 育 的 宣 传 画.
控制方长投下的子公司,需要编制合并报表的演示思路
人民版必修三专题三复习 近代中国 思想解放的潮流 灵石中学 易吉华.
成才之路 · 语文 人教版 • 中国古代诗歌散文欣赏 路漫漫其修远兮 吾将上下而求索.
105年桃連區適性入學宣導 桃園市十二年國民基本教育宣導團 宣講講師:龍岡國中 校長 郭玉承 時 間:105年 3 月 9 日 1.
行政诉讼法.
第二章 复式记账原理*** 主要内容、重点难点: 1.会计要素与会计等式*** 2.会计科目与账户*** 3. 借贷记账法***
第六章 其他税收法律制度.
2011年10月31日是一个令人警醒的日子,世界在10月31日迎来第70亿人口。当日凌晨,成为象征性的全球第70亿名成员之一的婴儿在菲律宾降生。 ?
第九课时 二元一次方程组 .
企劃撰寫.
江苏省2008年普通高校 招生录取办法 常熟理工学院学生处
氧气的制法 装置 原理 练习 随堂检测.
七(7)中队读书节 韩茜、蒋霁制作.
第二单元 生产、劳动与经营 第六课 投资理财的选择 一.储蓄存款和商业银行.
文明史观 文明史观,通常被称为文明史研究范式,是研究历史的一种理论模式。人类社会发展史,从本质上说就是人类文明演进的历史。
1、分别用双手在本上写下自己的名字 2、双手交叉
南美洲 吉林省延吉一高中 韩贵新.
第十章 会计档案 本章主要介绍了五方面的内容:(1)会计档案的概念和内容;(2)会计档案归档;(3)会计档案的保管期限;(4)会计档案的查阅、复制和交接;(5)会计档案的销毁 本章属于非重点章, 三年试卷中所占分值各为6分、7分、7分。
初级会计实务 第八章 产品成本核算 主讲人:杨菠.
《愛》 張愛玲 指導老師:胡翰平 國二甲 S 黃宜宣.
1.6 中国人口迁移.
第三课 走向自立人生.
  評量研習 國立臺南大學應用數學系     謝  堅.
2007年11月考试相关工作安排 各考试点、培训中心和广大应考人员:
中考阅读 复习备考交流 西安铁一中分校 向连吾.
主题一 主题二 模块小结与测评 主题三 考点一 主题四 考点二 主题五 考点三 主题六 考点四 命题热点聚焦 考点五 模块综合检测 考点六.
分式的乘除(1) 周良中学 贾文荣.
104年振聲國中 志願選填個別序位 說明會 104年06月08日 輔導室關心您.
中央广播电视大学开放教育 成本会计(补修)期末复习
人教版义务教育课程标准实验教科书 小学数学四年级上册第七单元《数学广角》 合理安排时间 248.
第三单元 发展社会主义民主政治.
市级个人课题交流材料 《旋转》问题情境引入的效果对比 高淳县第一中学 孔小军.
你不得不知的几件事 2、图书《10天行测通关特训》 3、网络课程 《网校9元课程系列》《考前强化夜校班》 4、地面课程 《10天10晚名师密授营》《考前预测集训营》
3.3 资源的跨区域调配 ——以南水北调为例 铜山中学 李启强.
我国三大自然区.
第五章 电流和电路 制作人 魏海军
第十二单元 第28讲 第28讲 古代中国的科技和文艺   知识诠释  思维发散.
第6讲 近代中国的新方向—— 五四运动至新中国成立.
“08高考化学学业水平(必修科目)测试的命题和教学对策研究”
中考语文积累 永宁县教研室 步正军 2015.9.
第十课 创新意识与社会进步 1.辩证的否定观:辩证否定、形而上学的否定观
课标教材下教研工作的 实践与思考 山东临沂市教育科学研究中心 郭允远.
小学数学知识讲座 应用题.
勾股定理 说课人:钱丹.
倒装句之其他句式.
动物激素的调节及其在农业生产中的应用(B级)
江苏省2009年普通高校 招生录取办法 江苏省教育考试院
第 22 课 孙中山的民主追求 1 .近代变法救国主张的失败教训: “师夷之长技以制 夷”“中体西用”、兴办洋务、变法维新等的失败,使孙中山
《美国的两党制》选考复习 温州第二高级中学 俞优红 2018年6月14日 1.
第七章 财务报告 主讲老师:王琼 上周知识回顾.
6 下标变量的中间代码生成 下标:数组;变量: 下标变量:即数组分量: 简单变量:id,其地址可查到;
如何寫工程計畫書 臺北市童軍會考驗委員會 高級考驗營 版.
人教版数学四年级(下) 乘法分配律 单击页面即可演示.
求曲线方程(3).
高等数学提高班 (省专升本) 教师: 裴亚萍 数学教研室: 东校区 2118 电话: 长号:
第九章 目标代码生成.
電子白板百萬小學堂 本活動建議搭配電子白板 學生最多可分成2~6組(請按組別按鈕) 老師可以視時間多少,來進行活動 每一組要回答十個問題。
基础会计.
第2节 大气的热力状况 基础知识回顾 重点难点诠释 经典例题赏析.
畢氏定理(百牛大祭)的故事 張美玲 製作 資料來源:探索數學的故事(凡異出版社).
第8章 语法制导翻译与中间代码生成.
102年人事預算編列說明 邁向頂尖大學辦公室製作.
Presentation transcript:

第六章 中间代码生成 主要内容 常见的中间代码结构 语法制导方法概论 四元式中间代码生成过程

中间代码:是一种复杂性介于源程序语言和目标语言之间一种语言,中间代码与具体机器无关。 C语言: f (x<y) x+=15 ; else x-=15; 用Pentium机器语言目标代码: 1010 1001 0001 0110 0000 0001 0011 1100 0001 1000 0000 0001 0111 1100 0000 0101 0010 1101 0001 0101 0000 000 1110 1010 0000 0011 0000 0101 0001 0101 0000 000 0101 0011 0001 1000 0000 0001 ………………….. 0000 0000 0000 0000 四元式中间代码: (<,x,y,t1) (then,t1,-,-) (addi,x,15,t2) ; (:=,t2,-,x) (else,-,-,-) (subi,x,15,t3) ; (:=,t3,-,x) (ifend,-,-,-)

1. 生成中间代码的目的 便于优化 便于移植 让生成的目标代码效率更高 优化不等同于对代码的精简和算法的优化 编译前端:与目标机无关 编译后端:与目标机相关 1、便于优化,我们想让生成的目标程序的执行效率是最高的,应该在生成中间代码的时候对源程序进行一些优化。这些优化工作可以提高目标程序的效率。同学可能会想是不是我们在设计程序的时候可以设计比较优秀的程序结构和良好的代码使得生成的目标代码效率比较好,是不是就不需要在编译过程中进行优化了呢? 其实不然。一种情形是程序设计者未必都是编程的高手,这样在他写的代码中有可能出现一些不是效率很高的情形,譬如说,我们写程序的时候会有一些不太注意的问题没有考虑到,同时有一些我们为了让计算机发挥它的计算优势,有一些中间结果我们没有算出来,比方说3.14*1.5我们一般不会把他的结果写在程序中,而是把这样一个结果写在这里。这样的计算如果在编译中把他计算出来,在生成目标程序就没有这样的计算,执行效率就会得到提高。 由于程序设计语言的一些限定条件,即使是程序设计者具有很强的程序设计能力,有些优化工作他也是不能做的,比方说多维下标变量地址计算过程,比方说a[i][j]和 a[i][k],我们在计算他们的地址的时候都先要计算a[i]的地址然后再计算j k 的地址,实际上a[i]的计算过程实际上是重复计算了,这样的问题在程序设计语言中,程序员是没有办法解决的,所以在编译中对他们进行优化是很必要的。在前面词法、语法、语义分析完了以后,我们直接对他进行优化可以么? 实际上是可以的,但是操作起来很麻烦,所以我们要把它变为一种中间的表示形式,然后基于这种中间的表示形式可能更方便一些,这是我们生成中间代码的第一个目的。 2、便于移植,一个编译程序从结构上来说我们可以把它分成是编译前端和编译后端两个组成部分,编译前端是指和目标机没有关联的部分,和目标机相关联的部分是编译后端。一个是有关一个是无关的。大家可以想象,同一个程序设计语言如果在不同的目标机上实现的话通常是需要构建不同的编译器,因为目标机不一样,生成的目标代码就不一样 ,那么怎么办呢?比方说我在某一种型号的机器上有一个编译器,又要在另一个型号的机器上生成编译器,我们需要把整个编译器都重新做么?实际上肯定是没必要的,因为有相当一部分程序是一样的,比方说词法、语法、语义,不管在什么样的目标机上执行他都是一样的,这些和目标机不相关的部分,在不同的目标机上实际上也是要做相同的工作,所以为了便于把一个编译器移植到另一个目标机,我们把编译前端的工作做的越多越好,因为编译前端的工作是不用改变的,而编译后端是需要和目标机相关的需要变化的。生成中间代码我们就可以把编译前端的工作做的非常的多。类似的工作比方说java语言的编译器,他是把java源程序,编译到中间一个语言上,在不同的目标机执行的时候映射到不同的目标语言,就可以执行了。这样的方法,对于我们处理源程序的翻译工作是非常有利的,因此一般的编译器都要做中间代码生成的工作,这就是我们做中间代码的目的。

前端 后端 前端1 后端1 L1 M1 M2 L2 前端2 M3 L3 前端3 M4 M5 目 标 代 码 生 成 中 间 优 化 语 义 分 析 法 词 程 序 源 前端1 后端1 L1 M1 M2 L2 前端2 M3 L3 前端3 M4 M5

前端 后端 前端1 后端1 L1 M1 后端2 M2 L2 后端3 M3 L3 后端4 M4 M5 后端5 目 标 代 码 生 成 中 间 优 化 语 义 分 析 法 词 程 序 源 前端1 后端1 L1 M1 后端2 M2 L2 后端3 M3 L3 后端4 M4 M5 后端5

2 常用的中间代码结构 后缀式----逆波兰式 图结构中间代码 三地址中间代码 特别是表达式的内部表示 抽象语法树 有向无环图DAG 三元式 2 常用的中间代码结构 后缀式----逆波兰式 特别是表达式的内部表示 图结构中间代码 抽象语法树 有向无环图DAG 三地址中间代码 三元式 四元式

2.1 后缀式(逆波兰式 ) 将运算对象写在前面,把运算符写在后面,因而也称后缀式。 a+b ab+ a+b*c abc* + 程序设计语言中的表示 逆波兰表示 a+b ab+ a+b*c abc* + (a+b)*c ab+c * 逆波兰式的特点: 逆波兰式中的变量的次序与中缀式中的变量的次序完全一致。 逆波兰式中无括号。 逆波兰式中的运算符已按计算顺序排列。

后缀式的计算机处理 后缀式的最大优点是易于计算机处理 处理过程:从左到右扫描后缀式,每碰到运算对象就推进栈;碰到运算符就从栈顶弹出相应目数的运算对象施加运算,并把结果推进栈。最后的结果留在栈顶。  例:表达式-b+c*d的后缀式 b-cd*+的计值过程 b t1 d c t1 t2 t1 t3 t1= - b t2= c*d t3= t1+t2

2.2 抽象语法树 抽象语法树AGT(Abstract Grammar Tree)可以显示地表示源程序的结构,是常用的一种标准中间代码形式。它的应用由开始的表达式已经推广到了整个程序。 例如: c := a * b + a *b := c + * * a b a b

2.3 三地址中间代码 所谓三地址是指操作符的两个运算分量及其该操作的运算结果的抽象地址。 2.3 三地址中间代码 所谓三地址是指操作符的两个运算分量及其该操作的运算结果的抽象地址。 (op,operand1,operand2,result) 表示result:=operand1 op operand2 最常见的三地址中间代码有三元式和四元式两种。

例如:语句 a := b * c + b / d 三元式 : 编号 (op,ARG1,ARG2) (1) ( * , b , c ) (2) ( / , b , d ) (3) ( + , (1) , (2)) (4) ( := , (3) , a ) 四元式: (op,ARG1,ARG2,RESULT) ( * , b , c , t1 ) ( / , b , d , t2 ) ( + , t1 , t2 , t3 ) ( := , t3 ,-, a ) 注: ARG1,ARG2 , RESULT为操作分量和运算结果的抽象地址表示,应包含相应语义信息。

一般的四元式操作符应包括以下几类: 1.算术、逻辑、关系运算符 ADDI、ADDF、SUBI、SUBF、MULTI、 MULTF、 DIVI、DIVF、MOD、AND、 OR、EQ、NE、GT、GE、LT、LE 2.I/O操作 ( READI,─, ─,id )…………整数输入 ( READF ,─,─,id )…………实数输入 ( WRITE,─,─ ,id )…………输出id

3.类型转换 ( FLOAT,id1, ─, id2 ) …id2 := float ( id1 ) 4.赋值 ( ASSIG ,id1,-, id2 ) …id2 := id1 5.地址加 ( AADD ,id1,id2, id3 ) …addr(id3 ):= addr ( id1 ) + id2

6.标号定义 ( LABEL,─,─,label )….定义标号label 7.条件/无条件转移 ( JMP,─,─ ,label )…转向标号label ( JMP0,id,─ ,label ) …若id=0,则转label ( JMP1,id,─,label ) …若id=1,则转label

8.过程调用 (ENTRY,Label,Size,Level ) ………子程序入口 (CALL,f,─,Result ) ………过程或函数调用 9.传送参数 VARACT VALACT FUNACT PROACT

3 语法制导方法概论 什么是语法制导方法:语法制导方法就是基于文法结构,在每个产生式的右部增加语义动作(或语义子程序),在语法分析过程中,随着分析的步步进展,如果遇到文法符号则做语法分析;如果遇到语义动作,就完成对应的语义处理。把这种在语法分析的同时进行语义处理的办法称为语法制导方法。 语法制导方法:基于文法结构,在每个产生式的右部增加语义动作,在语法分析过程中,如遇语义动作,就完成对应的语义处理,完成语义分析、中间代码生成和目标代码生成部分。

语法制导方法的组成:语法制导方法包括两个部分: 抽象描述部分:即带有动作符的文法描述,称为动作方法; 实现部分:语法分析的同时能够处理语义动作的驱动程序。 例如:有动作语义文法G  G: S→ #Init# AB A → aA│ b #Add# B → b #Add# B│c #Out_Val# 各动作符对应的语义子程序如下: Init m = 0 Out_Val if (m!= 0) { printf (“%d”, m ); m = 0; } Add m++ ;

语法制导方法的种类:语法制导方法依赖于具体的语法分析方法,因此可以分为自顶向下语法制导方法和自底向上语法制导方法。自顶向下语法制导方法中通常采用LL(1)分析方法为基础,而自底向上语法制导方法中通常以LR(1)分析方法为基础。

LL(1)语法制导方法的实例 设有如下LL(1)文法: G: S → A B A → a A │ b B → b B │ c 要求:应用语法制导翻译方法完成如下任务: 对输入文法 G 的任意句子 L ,输出 L 中 b 串的长度。如串 abbbc 是 G 的句子,则该 处理器将输出3。

G的原始LL(1)分析表 a b c # S A B G: S → AB A → aA │b B → bB │c S → A B

G 的动作文法如下: G: S→ #Init# AB A → aA│ b #Add# B → b #Add# B│c #Out_Val# 各动作符对应的语义子程序如下: Init m = 0 Out_Val if (m!= 0) { printf (“%d”, m ); m = 0; } Add m++ ;

G的带动作符的LL(1)分析表 a b c # S A B G[S]: S→ #init# A B A → a A│ b #Add# B → b #Add# B│c#Out_Val# G的带动作符的LL(1)分析表 a b c # S S → #init# A B S → #init## A B A A → a A A → b #Add# B B → b #Add# B B → c#Out_Val##

语法制导的实现过程(1) 替换 替换 匹配Match 对给定的终极符串abbbc,分析过程: S# abbbc # 替换 例 G[s] : [1] S→ #init# A B [2] A → a A [3] A → b #Add# [4] B → b#Add# B [5] B → c#Out_Val# {a,b} {b} {c} {a} 对给定的终极符串abbbc,分析过程: S# abbbc # 替换 #init# A B # abbbc # # Init # m=0 替换 A B # abbbc # aA B # abbbc # 匹配Match 替换 A B # bbbc # b #Add#B # bbbc # 匹配Match #Add# B # bbc # #Add# m=1 B # bbc #

语法制导的实现过程(2) 替换 匹配Match 替换 匹配Match 匹配Match 对给定的终极符串abbbc,分析过程(续): B # 例 G[s] : [1] S→ #init# A B [2] A → a A [3] A → b#Add# [4] B → b#Add#B [5] B → c#Out_Val# {a,b} {b} {c} {a} 对给定的终极符串abbbc,分析过程(续): B # 替换 bbc # b #Add# B # bbc # 匹配Match #Add# B # bc # #Add# m=2 B # bc # b#Add# B # 替换 匹配Match #Add#B # c # #Add# m=3 c # Out_Val # # c # 匹配Match # Out_Val # # # #Out_Val# 输出3 # # Success

5 中间代码生成中的几个问题 (1)语义信息的提取与保存: 四元式: (算符op,ARG1,ARG2,运算结果RESULT) 如:3.5+i (ADDF,3.5,(i.level,i.off,dir),(-1,t3,dir)) 语义信息的两种表示方式: 指向相应符号表的指针 把对应分量的语义信息放在此处 下面我们要考虑一下进行中间代码生成的时候应该注意的问题,这里有几个情况先和大家做一下交代,1、语义信息的提取,我们现在写的四元式都是+xy t1,大家读起来可能比较方便,但是实际上这个x y存的并不是x和y的符号,而是一个指针,指向xy在符号表中的位置,一个变量标识符的语义信息包括三个部分:种类信息 类型信息 抽象地址,我们要进行xy的计算,这些语义信息实际上是应该能够提到的,你让他俩进行计算这里涉及到一些类型检查类型转换等等操作,如果这些语义信息提取不出来的话,这个事儿就没法做了, 一种方式是把他们的语义信息都放到四元式里,这样的方式对于四元式的管理和组织,还有信息的冗余都会产生很大的影响,比方说x在程序中出现很多次,你要是把x的语义信息都存在四元式中就会产生很多的冗余信息, 所以最好的一种方式就是x y都是一个指针,指向对应的位置,需要提取信息的时候我们就可以通过指针到符号表中把信息提取出来,为了方便,同学看起来也方便,以后在我们的课堂中,我们还是用xy来表示,但是大家一定要清楚这里实际上是一个指针,通过符号表可以把它们的语义信息提取出来。

四元式中操作分量或运算结果的地址表示ARG结构: form分为三大类: 标号类LabelForm:语义信息Label是相应的标号值,包括过程 ⁄ 函数体的入口标号; 数值类ValueForm:语义信息Value就是该数据值; 地址类AddrForm:语义信息Addr由四部分组成:变量名、层数、偏移和访问方式(分为直接访问方式和间接访问方式)。 ARG结构:

(2)语义栈Sem及其操作 中间代码生成尤其是变量和表达式的处理过程中要用到语义栈Sem ,该栈主要存放运算分量和运算结果的类型和地址表示 。 SemElem=record typ:ElemType ; {运算分量或结果的类型} FORM:ARG_Record {地址表示分类语义信息} end; SemStack=array[1..Max] of SemElem; var Sem:SemStack ; top:integer ; 对语义栈Sem的操作有 push(x):将标识符x的类型和Form压入Sem栈;pop(n):从Sem的栈顶删除n个元素。

(3) 常用的语义子程序 申请临时单元 new_dir(t): 申请一个临时变量t,且t是直接寻址; new_indir(t):申请一个临时变量t,且t是间接寻址。 GenCode(ω) : ω为操作码,该子程序功能是产生一条四元式中间代码。此时左、右运算分量语义信息已经在语义栈Sem的次栈顶和栈顶。

6 表达式的中间代码生成 简单表达式的LL(1)文法 (1)E →T Es (2)Es → (3)Es →+ T Es (5)T → P Ts (6)Ts→ (7)Ts →* P Ts (8)Ts →/ P Ts (9)P →C (10)P →id (11)P →( E )

(3)Es →+T#GenCode(+)#Es (4)Es →-T#GenCode(-)#Es (5)T → PTs (6)Ts→ 简单表达式的带有动作符的LL(1)文法 (1)E →TEs (2)Es → (3)Es →+T#GenCode(+)#Es (4)Es →-T#GenCode(-)#Es (5)T → PTs (6)Ts→ (7)Ts →*P#GenCode(*)#Ts (8)Ts →/P#GenCode(/)#Ts (9)P →C#Push(C)# (10)P →id#Push(id)# (11)P →(E) 当遇到常量C和简单变量id时,把它们的语义信息压入语义栈; 当处理完一个运算符(+,-,*,/)的右分量时,该运算符的左、右运算分量已经分别存放在语义栈 Sem 的次栈顶和栈顶的位置,因此可以生成相应的运算符的四元式,并把运算结果的语义信息压入语义栈。

简单表达式的LL(1)分析表 C id ( ) + - * / # E 1 Es 2 3 4 T 5 Ts 6 7 8 P 9 10 11 产生式 Predict集 (1 ) E → T Es C, id , ( (2)Es →  #, ) (3)Es → + T Es + (4)Es → - T Es - (5)T → P Ts (6)Ts→ #, ),+,- (7)Ts → * P Ts * (8)Ts → / P Ts / (9)P → C C (10)P → id Id (11)P → ( E ) (

# EsT x + y * z # LL [ T ,id ] = [5] # E x + y * z # LL[ E ,id ] = [1] # EsT x + y * z # LL [ T ,id ] = [5] # EsTs P x + y * z # LL [ P ,id ] = [10] # EsTs #Push ( id )# id x + y * z # Match # EsTs #Push ( id )# + y * z # #Push ( id )# # EsTs + y * z # (1)E → T Es (2)Es → (3)Es → + T # GenCode ( + ) # Es (4)Es → - T # GenCode ( - ) # Es (5)T → P Ts (6)Ts→ (7)Ts → * P # GenCode ( * ) # Ts (8)Ts → / P # GenCode ( / ) # Ts (9)P → C # Push ( C ) # (10)P → id # Push ( id ) # (11)P → ( E ) Top Top intptr (x,level,off, dir) 语义栈Sem

# EsTs + y * z # LL [ Ts,+ ] = [6] #Es + y * z # LL [ Es,+] = [3] 表达式 x + y * z 的中间代码生成过程(2) 分析栈S 输入流T 动作 # EsTs + y * z # LL [ Ts,+ ] = [6] #Es + y * z # LL [ Es,+] = [3] # Es #GenCode ( + )# T + + y * z # Match # Es #GenCode ( + )# T y * z # LL [ T,id ] =[5] # Es #GenCode ( + ) #TsP y * z # LL [ P,id ] = [10] # Es #GenCode ( + )# Ts#Push ( id )# id y * z # (1)E → T Es (2)Es → (3)Es → + T # GenCode ( + ) # Es (4)Es → - T # GenCode ( - ) # Es (5)T → P Ts (6)Ts→ (7)Ts → * P # GenCode ( * ) # Ts (8)Ts → / P # GenCode ( / ) # Ts (9)P → C # Push ( C ) # (10)P → id # Push ( id ) # (11)P → ( E ) Top intptr (x.level, x.off, dir) 语义栈Sem

表达式 x + y * z 的中间代码生成过程(3) 分析栈S 输入流T 动作 # Es# GenCode (+) # Ts # Push (id) # id y * z # Match # Es# GenCode (+) # Ts # Push (id) # * z # # Push (id) # # Es # GenCode (+) # Ts * z # (1)E → T Es (2)Es → (3)Es → + T # GenCode ( + ) # Es (4)Es → - T # GenCode ( - ) # Es (5)T → P Ts (6)Ts→ (7)Ts → * P # GenCode ( * ) # Ts (8)Ts → / P # GenCode ( / ) # Ts (9)P → C # Push ( C ) # (10)P → id # Push ( id ) # (11)P → ( E ) Top intptr (y,level, off, dir) Top intptr (x.level, x.off, dir) 分析表 语义栈Sem

表达式 x + y * z 的中间代码生成过程(4) 分析栈S 输入流T 动作 # Es # GenCode (+ )# Ts * z # LL [ Ts,* ] = [7] # Es # GenCode (+) # Ts # GenCode (*) # P* * z # Match # Es # GenCode (+) # Ts # GenCode (*) # P z # (1)E → T Es (2)Es → (3)Es → + T # GenCode ( + ) # Es (4)Es → - T # GenCode ( - ) # Es (5)T → P Ts (6)Ts→ (7)Ts → * P # GenCode ( * ) # Ts (8)Ts → / P # GenCode ( / ) # Ts (9)P → C # Push ( C ) # (10)P → id # Push ( id ) # (11)P → ( E ) Top intptr (y.level, y.off, dir) intptr (x.level, x.off, dir) 语义栈Sem

# Es # GenCode (+) # Ts # GenCode (*) # # Push (id) # # 表达式 x + y * z 的中间代码生成过程(5) 分析栈S 输入流T 动作 # Es # GenCode (+) # Ts # GenCode (*) # P z # LL[P,id] = [10] # Es # GenCode (+) # Ts # GenCode (*) # # Push ( id ) # id z # Match # Es # GenCode (+) # Ts # GenCode (*) # # Push (id) # # (1)E → T Es (2)Es → (3)Es → + T # GenCode ( + ) # Es (4)Es → - T # GenCode ( - ) # Es (5)T → P Ts (6)Ts→ (7)Ts → * P # GenCode ( * ) # Ts (8)Ts → / P # GenCode ( / ) # Ts (9)P → C # Push ( C ) # (10)P → id # Push ( id ) # (11)P → ( E ) Top intptr (y.level, y.off, dir) intptr (x.level, x.off, dir) 语义栈Sem

# Es # GenCode (+) # Ts # GenCode (*) # # #GenCode (*)# 表达式 x + y * z 的中间代码生成过程(6) 分析栈S 输入流T 动作 # Es # GenCode (+) # Ts # GenCode (*) # # Push (id) # # #Push (id)# # Es # GenCode (+) # Ts # GenCode (*) # # #GenCode (*)# # Es # GenCode (+) # Ts # (MULTI, (y,level, off, dir), (z,level, off, dir), (-1,-1, t1, dir)) (1)E → T Es (2)Es → (3)Es → + T # GenCode ( + ) # Es (4)Es → - T # GenCode ( - ) # Es (5)T → P Ts (6)Ts→ (7)Ts → * P # GenCode ( * ) # Ts (8)Ts → / P # GenCode ( / ) # Ts (9)P → C # Push ( C ) # (10)P → id # Push ( id ) # (11)P → ( E ) Top intptr (z, level, off, dir) Top intptr intptr (y,level,off, dir) (-1,-1, t1, dir) 分析表 intptr (x,level, off, dir) 语义栈Sem

# Es # GenCode (+) # Ts # LL [ Ts,# ] = [6] 表达式 x + y * z 的中间代码生成过程(7) 分析栈S 输入流T 动作 # Es # GenCode (+) # Ts # LL [ Ts,# ] = [6] # Es # GenCode (+) # # #GenCode (+)# # Es # LL [ Es,# ] = [2] # # Success (MULTI, y ,z, t1) (ADDI, x, t1. t2) (MULTI, (y,level,off, dir), (z,level, off, dir), (-1,-1, t1, dir)) (ADDI, (x,level,off, dir), (-1,-1, t1, dir) , (-1, -1,t2, dir)) (1)E → T Es (2)Es → (3)Es → + T # GenCode ( + ) # Es (4)Es → - T # GenCode ( - ) # Es (5)T → P Ts (6)Ts→ (7)Ts → * P # GenCode ( * ) # Ts (8)Ts → / P # GenCode ( / ) # Ts (9)P → C # Push ( C ) # (10)P → id # Push ( id ) # (11)P → ( E ) Top intptr (-1,-1, t1, dir) Top intptr intptr (-1,1-, t2, dir) (x, level, off,dir) 语义栈Sem

例:将下列表达式翻译成四元式序列。 X*2+A*(i+1)/(j+1) 其中i和j为整型变量,其它为实型变量。 (FLOAT, 2, _ , t1) (MULTF, X , t1, t2) (ADDI, i, 1, t3) (FLOAT, t3, _ , t4) (MULTF,A, t4, t5) (ADDI, j, 1, t6) (FLOAT, t6, _ , t7) (DIVF,t5, t7, t8) (ADDF, t2, t8, t9)