第七章 中间代码生成(2)

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

产生一条中间代码子程序GenCode()
产生一条中间代码子程序GenCode() 调用该函数时,左右操作数已进语义栈Sem; 分别取出左右操作数; 检查类型是否相同,不同则进行转换,产生类型转 换四元式; 产生中间代码( *, Sem[top-1], Sem[top],t) pop(2); //弹出左右分量 push(t) //压入结果t的类型和Form
top
R.typ, R.form L.typ, L.form
Sem
7.3 表达式的中间代码生成

表达式的中间代码就是依据原表达式的语 义产生出正确计算表达式值的四元式中间 代码(即将计算顺序体现出来)
– 表达式的运算分量可以是简单变量、复杂变
量和函数调用 – 表达式的运算符可以是算术运算符,关系运 算符,逻辑运算符等
复合变量的四元式生成
复合变量:下标变量 A[i][j], 域名变量 st.name, 指针 变量 *p 复合变量的中间代码是计算复合变量地址的四元式

变量的语法: V id V1 V2 [E] V1 V2.id
地址: addr(V) = addr(id) addr(V1) = addr(V2)+(E-low+1)*Elesize addr(V1) = addr(V2)+offset(id)

2.
– –
语义栈Sem及其操作
语义栈的内容:运算分量的类型和FORM 数据结构定义:


typedef struct SemElem {typ: ElemType; Form: FormStruct} typedef SemElem SemStack[Max] SemStack Sem; //声明Sem为语义栈 int top; //声明top为语义栈栈顶 push(x) : 将x的类型和Form压入语义栈 pop(n) :从Sem栈栈顶依次弹出n个元素


<Push(C)> Ts Es )<GenCode(*)> Ts Es +i*b) Ts Es) <GenCode(*)> Ts Es +i*b) Es )<GenCode(*)> Ts Es +i*b) + T <GenCode(+)> Es )<GenCode(*)> Ts Es + i*b) T<GenCode(+)> Es )<GenCode(*)> Ts Es i*b) PTs <GenCode(+)> Es) <GenCode(*)> Ts Es i*b) id <Push(id)> Ts <GenCode(+)> Es )<GenCode(*)> Ts Es i*b) <Push(id)> Ts <GenCode(+)> Es )<GenCode(*)> Ts Es *b) Ts <GenCode(+)> Es )<GenCode(*)> Ts Es *b) *P <GenCode(*)> Ts <GenCode(+)> Es )<GenCode(*)> Ts Es *b) P <GenCode(*)> Ts <GenCode(+)> Es )<GenCode(*)> Ts Es b)
V1 *V2
addr(V1) = content(addr(V2))
下标变量的四元式生成

一维下标变量 a[i]和多维下标变量 a[i][j][k]
Var A:array [L1..U1][L2..U2]…[Ln…Un] of T;(n>=1)
数组第1行的宽度是 D1=U1-L1+1; 数组第i行的宽度是 Di=Ui-Li+1; 设类型T所占单元数为,则数组A占单元数为 size(A) = D1*D2*…*Dn* 下标变量A[E1][E2]…[Ek]地址为: Addr(A) + ((E1-L1)*S1 + …(Ek-Lk)*Sk)*size(T) 其中 当 i =1时,s1 = 1,否则 si = Di+1*Di+2*…*Dn sn = 1

E T Es P Ts Es id <Push(id)> Ts Es <Push(id)> Ts Es Ts Es *P<GenCode(*)>Ts Es P <GenCode(*)> Ts Es (E)<GenCode(*)> Ts Es E) <GenCode(*)> Ts Es T Es) <GenCode(*) Ts Es P Ts Es) <GenCode(*)> Ts Es C <Push(C)> Ts Es )<GenCode(*)> Ts Es <Push(C)> Ts Es )<GenCode(*)> Ts Es
第七章 中间代码生成
7.1 几种常见的中间表示 7.2 中间代码中生成的几个问题
7.3 表达式的中间代码生成
7.4 原子语句的中间代码生成 7.5 结构语句的中间代码生成 7.6 声明的中间代码生成
7.5 结构语句的中间代码生成

条件语句
– If 语句 – Switch 语句

赋值语句

Left = Right
Left.code Right.code
(FLOAT, Right, _, t.Form) (ASSIG, t.Form, n, left.Form) 其中n表示 Right.typ所占空间大小.
I/O 语句

Read(V)
V.code

Write(Exp);

A[E1][E2]…[Ek] (k<=n)
(ASSIG, size(T), -, tsize)
E1 t1
(SUBI, t1, L1, t2) (MULTI, t2, s1, t3)
(MULTI, t3, tsize, t4)
(AADD , addr(A), t4, ad) ……
Ek tn
Exp.code
(READ, _, _, V.Form)
(WRITE, _, _, Exp.Form)
Goto语句和Label语句

Goto L

L: S
(LABEL, _, _, LL)
(JUMP, _, _, LL)
S.code
Return语句

Return E
E.code

Return
(RETURN, _, _, _ )
a*(3.5+i*b) a*(3.5+i*b) a*(3.5+i*b) a*(3.5+i*b) *(3.5+i*b) *(3.5+i*b) *(3.5+i*b) (3.5+i*b) (3.5+i*b) 3.5+i*b) 3.5+i*b) 3.5+i*b) 3.5+i*b) +i*b)


id<Push(id)> <GenCode(*)> Ts <GenCode(+)> Es) <GenCode(*)> Ts Es b) <Push(id)> <GenCode(*)> Ts <GenCode(+)> Es )<GenCode(*)> Ts Es ) <GenCode(*)> Ts <GenCode(+)> Es )<GenCode(*)> Ts Es ) Ts <GenCode(+)> Es )<GenCode(*)> Ts Es ) <GenCode(+)> Es ) <GenCode(*)> Ts Es ) Es ) <GenCode(*)> Ts Es ) ) <GenCode(*)> Ts Es ) <GenCode(*)> Ts Es Ts Es Es
函数调用
函数调用例子

函数f(x+1,Y),其中x是一般整型变量, Y是变 参整型变量,假定f是实在函数,f的两个形参 一个是值参一个是变参
(ADDI, x, 1, t1) (VALACT, t1, offset1, 1) (VARACT, Y, offset2, 1) (CALL, f, true, t2)
(RETURN, _, _, E.Form)
函数调用语句
f(E1, …, En) 从符号表中获取f 的属性

– Level, params, type

生成中间代码
E1.code …… En.code 形实参结合
(VALACT, 实参.Form, offset, size) (VARACT, 实参.Form, offset, size) (call, f, true, t) (call, f, false, t)
– (MULTF, a, t3, t4)
表达式四元式生成LL(1)语法制导
E T Es Es Es + T Es Es - T Es T P Ts Ts Ts *P Ts Ts /PTs PC P id P (E) E T Es Es Es + T #GenCode(+)#Es Es - T #GenCode(-)# Es T P Ts Ts Ts *P #GenCode(*)# Ts Ts /P #GenCode(/)# Ts P C #Push(C)# P id #Push(id)# P (E)
(SUBI, tn, Lk, tn+1) (MULTI, tn+1, sk, tn+2) (MULTI, tn+2, tsize, tn+3)
(AADD , ad, tn+3, tn+4)
表达式代码生成的例子
class[5].age + *ptr.age typedef struct { char name[30]; int age; float height; }person; class[5] (-, 5, 0, t5) t4 (*, t5, 33, t6) class[5].age t1 (AADD, class, t6, t4) (AADD , t4, 30, t1) (Assig, ptr, t7) *ptr t7 _, t2 *ptr.age (AADD , t7, 30, t2) (+, t1, t2, t3) t1,t2,t4和t7的mode是indir;

变量及操作:

7.2 中间代码生成中的几个问题
3.
常用的语义子程序
申请临时单元 new_dir(t): 在临时变量区申请一个单元t,且t是直接 寻址 new_indir(t): t是间接寻址
存放中间代码子程序Generate(,left,right,result) 将一条四元式中间代码存放到中间代码区中
首先给出简单算术表达式的中间代码生成 复合变量的中间代码生成

表达式的四元式
表达式E a *(3.5 + i *b) 假设a,b为实型变量,i为整型变量 E生成的四元式如下:

– (FLOAT, i, -, t1) – (MULTF, t1, b, t2)
源自文库
– (ADDF, 3.5, t2, t3)
7.4 原子语句的中间代码生成
赋值语句: V = Exp; I/O 语句

– Read(V); – Write(Exp);
Goto 语句 : Goto Label 标号语句: Label: Statement; 函数调用返回语句: Return Exp; 函数调用: F(Exp1, …, Expn)
第七章 中间代码生成
7.1 几种常见的中间表示 7.2 中间代码中生成的几个问题
7.3 表达式的中间代码生成
7.4 原子语句的中间代码生成 7.5 结构语句的中间代码生成 7.6 声明的中间代码生成
7.2 中间代码生成中的几个问题
1.

语义信息的获取和保存

目标代码阶段保留符号表,则可用标识符在符号表中的 地址 不保留符号表,则用FORM结构保存标识符的语义信息
int x[10]; (L, 0) person class[10]; (L, 10) person *ptr; (L, 340)
第七章 中间代码生成
7.1 几种常见的中间表示 7.2 中间代码中生成的几个问题
7.3 表达式的中间代码生成
7.4 原子语句的中间代码生成 7.5 结构语句的中间代码生成 7.6 声明的中间代码生成
相关文档
最新文档