5编译原理,陈意云 ,课后答案5
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2011-3-28 luanj@mail.ustc.edu.cn 14
7.6
• 假转方式 产生式
E → E1 or E2
语义规则
E1.true := E.true; E1.false := newlabel; E2.true := E.true; E2.false := E.false; E.code := E1.code [增加 || gen(‘goto’, E1.true)] || 增加: 增加 gen(E1.false, ‘:’) || E2.code E1.true := newlabel; E1.false := E.false; E2.true := E.true; E2.false := E.false; E.code := E1.code [删去 || gen(E1.true, ‘:’)] || E2.code 删去: 删去
E → id1 relop id2
E → true E → false
2011-3-28
luanj@mail.ustc.edu.cn
16Leabharlann Baidu
7.9
• 下面的C语言程序 main(){ int i, j; while((i || j) && (j > 5)){ i = j; } } 在x86/Linux机器上编译生成的汇编代码如下: 在该汇编代码中有关的指令后加注释,将源程序中的操作 和生成的汇编代码对应起来,以判断确实是用短路计算来 完成布尔表达式计算的。
luanj@mail.ustc.edu.cn 15
E → E1 and E2
2011-3-28
7.6 (续) 续表 (续
E → not E1 E1.true := E.false; E1.false := E.true; E.code := E1.code E1.true := E.true; E1.false := E.false; E.code := E1.code E.code := gen(‘if’, id1.place, relop.op, id2.place, ‘goto’, E.true) || gen(‘goto’, E.false) [修改为 E.code := gen('if', id1.place, not(relop.op) , 修改为: 修改为 id2.place, 'goto', E.false))] E.code := gen(‘goto’, E.true) E.code := gen(‘goto’, E.false) E → (E1 )
2011-3-28
luanj@mail.ustc.edu.cn
8
7.4 (续) (续
• D -> ID_LIST:T ID_LIST -> ID_LIST,ID_LIST|id • D -> { Init(idtable) } ID_LIST:T { for each name in idtable do enter(name, T.type, offset); offset := offset + T.width; end; } ID_LIST -> { Init(idtable1); Init(idtable2) } ID_LIST1,ID_LIST2 { merge(idtable1, idtable2, idtable) } ID_LIST -> id { add(idtable, id.name); }
2
7.1 (续) (续
• (a) 语法树
+ + + -
• (b) 有向无环图
+ +
* + + a
c b +
*
+
a
b c
d
a
b
c
d
3
2011-3-28
luanj@mail.ustc.edu.cn
7.1 (续) (续
• (c) 后缀表示 ab+cd+*-ab+c++ • (d) 三地址代码 t1 := a + b t2 := c + d t3 := t1 * t2 t4 := -t3 t5 := t1 + c t6 := t4 + t5
2011-3-28
luanj@mail.ustc.edu.cn
7
7.4
• 修改图7.4中计算声明的类型和相对地址的翻译方案,允 许名字表而不是单个名字出现在形式为D->id: T的声明中。
P -> DS D -> D;D D -> id:T T -> integer T -> real T -> array[num]of T1 T -> ↑T1 { offset = 0; } { enter(id.name, T.type, offset); offset += T.width; } { T.type = integer; T.width = 4; } { T.type = real; T.width = 8; } { T.type = array(num.val, T1.type); T.width = num.val * T1.width; } { T.type = pointer(T1.type); T.width = 4; }
E → true E → false • 指令解释 指令解释: or: 将栈顶和次栈顶值取出 进行或操作 将结果压栈 将栈顶和次栈顶值取出, 进行或操作,将结果压栈 and: 将栈顶和次栈顶值取出 进行与操作 将结果压栈 将栈顶和次栈顶值取出, 进行与操作,将结果压栈 not: 将栈顶值取出 进行非操作 将结果压栈 将栈顶值取出, 进行非操作,将结果压栈 push name: 将name的值压栈 的值压栈 relop op:将栈顶和次栈顶值取出 判断他们的 关系 将结果压栈 将栈顶和次栈顶值取出, 关系,将结果压栈 将栈顶和次栈顶值取出 判断他们的op关系
luanj@mail.ustc.edu.cn 18
7.9 (续) (续
E → true E → false
2011-3-28
luanj@mail.ustc.edu.cn
12
7.7 (续) (续
• E → E1 or E2 E → E1 and E2 E → not E1 E → ( E1 ) E → id1 relop id2 { emit (‘or’) } { emit (‘and’) } { emit (‘not’) } {} { emit(‘push ‘ || id1.name); emit(‘push ’ || id2.name); emit (‘relop ’ || relop.op) } { emit ( ‘1’ ) } { emit ( ‘0’ ) }
2011-3-28 luanj@mail.ustc.edu.cn 11
7.7
• 修改图7.11的语法制导定义,为栈机器产生代码。
E → E1 or E2 E → not E1 E → ( E1 ) E → id1 relop id2 E → E1 and E2 { E.place := newtemp; emit (E.place, ‘:=’, E1.place, ‘or’, E2.place) } { E.place := newtemp; emit (E.place, ‘:=’, E1.place, ‘and’, E2.place) } { E.place := E1.place } { E.place := newtemp; emit (E.place, ‘:=’, ‘not’, E1.place) } { E.place := newtemp; emit (‘if’, id1.place, relop.op, id2.place,‘goto’, nextstat+3 ); emit (E.place, ‘:=’, ‘0’ ); emit (‘goto’, nextstat + 2 ); emit (E.place, ‘:=’, ‘1’ ) } { E.place := newtemp; emit (E.place, ‘:=’, ‘1’ ) } { E.place := newtemp; emit (E.place, ‘:=’, ‘0’ ) }
2011-3-28
luanj@mail.ustc.edu.cn
9
7.5
• 算符θ作用于表达式e1,e2,...,ek的前缀形式 是θp1p2...pk,其中pi是ei的前缀形式。 (a) 写出a*-(b+c)的前缀形式。 (c) 给出把表达式翻成前缀形式的语法制导 定义。
2011-3-28
luanj@mail.ustc.edu.cn
10
7.5 (续) (续
• (a) *a-+bc • (c) 表达式翻成前缀形式的语法制导定义
E -> E+T | T T -> T*F | F F -> -F | (E) | id L -> En { printf(E.string); } E -> E1 + T { E.string = “+” + E1.string + T.string; } E -> T { E.string = T.string; } T -> T1*F { T.string = “*” + T1.string + F.string; } T -> F { T.string = F.string; } F -> -F1 { F.string = “-” + F1.string; } F -> (E) { F.string = E.string; } F -> id { F.string = id.value; }
2011-3-28 luanj@mail.ustc.edu.cn 4
7.2
• 把C程序 main(){ int i; int a[10]; while(i <= 10) a[i] = 0; } 的可执行语句翻译成: (a) 语法树 (b) 后缀表示 (c) 三地址代码
2011-3-28 luanj@mail.ustc.edu.cn 5
2011-3-28
luanj@mail.ustc.edu.cn
17
7.9 (续) 题目 (续
… .text .align 4 .globl main .type main,@function main: pushl %ebp movl %esp, %ebp subl $8, %esp nop .p2align 4,,7 .L2: cmpl $0, -4(%ebp) jne .L6 cmpl $0, -8(%ebp) jne .L6 jmp .L5 .p2align 4,,7
7.2 (续) (续
• (a) • (b) 语法树 后缀表示
<= while
= 10 array a i
i 10 <= a i array 0 = while
i 0
2011-3-28
luanj@mail.ustc.edu.cn
6
7.2 (续) (续
• (c) 三地址代码 1: if i <= 10 goto 3 2: goto 5 3: a[i] := 0; 4: goto 1 5: return 0
2011-3-28 luanj@mail.ustc.edu.cn 13
7.8
• 表7.4的语法制导定义把E-> id1< id2翻译成 一对语句 if id1<id2 goto ... goto ... 可以用一个语句 if id1>=id2 goto... 来代替,当E是真时执行后继代码。修改表 7.4的语法制导定义,使之产生这种性质的 代码。
2011-3-28
.L6: cmpl $5, -8(%ebp) jg .L4 jmp .L5 .p2align 4,,7 .L5: jmp .L3 .p2align 4,,7 .L4: movl -8(%ebp), %eax movl %eax, -4(%ebp) jmp .L2 .p2align 4,,7 .L3 .L1 leave ret …
编译原理习题课(5) 编译原理习题课(5)
栾 俊 luanj@mail.ustc.edu.cn 3/28/2011
7.1
• 把算术表达式 –(a+b)*(c+d)+(a+b-c) 翻译成: (a) 语法树 (b) 有向无环图 (c) 后缀表示 (d) 三地址代码
2011-3-28
luanj@mail.ustc.edu.cn
7.6
• 假转方式 产生式
E → E1 or E2
语义规则
E1.true := E.true; E1.false := newlabel; E2.true := E.true; E2.false := E.false; E.code := E1.code [增加 || gen(‘goto’, E1.true)] || 增加: 增加 gen(E1.false, ‘:’) || E2.code E1.true := newlabel; E1.false := E.false; E2.true := E.true; E2.false := E.false; E.code := E1.code [删去 || gen(E1.true, ‘:’)] || E2.code 删去: 删去
E → id1 relop id2
E → true E → false
2011-3-28
luanj@mail.ustc.edu.cn
16Leabharlann Baidu
7.9
• 下面的C语言程序 main(){ int i, j; while((i || j) && (j > 5)){ i = j; } } 在x86/Linux机器上编译生成的汇编代码如下: 在该汇编代码中有关的指令后加注释,将源程序中的操作 和生成的汇编代码对应起来,以判断确实是用短路计算来 完成布尔表达式计算的。
luanj@mail.ustc.edu.cn 15
E → E1 and E2
2011-3-28
7.6 (续) 续表 (续
E → not E1 E1.true := E.false; E1.false := E.true; E.code := E1.code E1.true := E.true; E1.false := E.false; E.code := E1.code E.code := gen(‘if’, id1.place, relop.op, id2.place, ‘goto’, E.true) || gen(‘goto’, E.false) [修改为 E.code := gen('if', id1.place, not(relop.op) , 修改为: 修改为 id2.place, 'goto', E.false))] E.code := gen(‘goto’, E.true) E.code := gen(‘goto’, E.false) E → (E1 )
2011-3-28
luanj@mail.ustc.edu.cn
8
7.4 (续) (续
• D -> ID_LIST:T ID_LIST -> ID_LIST,ID_LIST|id • D -> { Init(idtable) } ID_LIST:T { for each name in idtable do enter(name, T.type, offset); offset := offset + T.width; end; } ID_LIST -> { Init(idtable1); Init(idtable2) } ID_LIST1,ID_LIST2 { merge(idtable1, idtable2, idtable) } ID_LIST -> id { add(idtable, id.name); }
2
7.1 (续) (续
• (a) 语法树
+ + + -
• (b) 有向无环图
+ +
* + + a
c b +
*
+
a
b c
d
a
b
c
d
3
2011-3-28
luanj@mail.ustc.edu.cn
7.1 (续) (续
• (c) 后缀表示 ab+cd+*-ab+c++ • (d) 三地址代码 t1 := a + b t2 := c + d t3 := t1 * t2 t4 := -t3 t5 := t1 + c t6 := t4 + t5
2011-3-28
luanj@mail.ustc.edu.cn
7
7.4
• 修改图7.4中计算声明的类型和相对地址的翻译方案,允 许名字表而不是单个名字出现在形式为D->id: T的声明中。
P -> DS D -> D;D D -> id:T T -> integer T -> real T -> array[num]of T1 T -> ↑T1 { offset = 0; } { enter(id.name, T.type, offset); offset += T.width; } { T.type = integer; T.width = 4; } { T.type = real; T.width = 8; } { T.type = array(num.val, T1.type); T.width = num.val * T1.width; } { T.type = pointer(T1.type); T.width = 4; }
E → true E → false • 指令解释 指令解释: or: 将栈顶和次栈顶值取出 进行或操作 将结果压栈 将栈顶和次栈顶值取出, 进行或操作,将结果压栈 and: 将栈顶和次栈顶值取出 进行与操作 将结果压栈 将栈顶和次栈顶值取出, 进行与操作,将结果压栈 not: 将栈顶值取出 进行非操作 将结果压栈 将栈顶值取出, 进行非操作,将结果压栈 push name: 将name的值压栈 的值压栈 relop op:将栈顶和次栈顶值取出 判断他们的 关系 将结果压栈 将栈顶和次栈顶值取出, 关系,将结果压栈 将栈顶和次栈顶值取出 判断他们的op关系
luanj@mail.ustc.edu.cn 18
7.9 (续) (续
E → true E → false
2011-3-28
luanj@mail.ustc.edu.cn
12
7.7 (续) (续
• E → E1 or E2 E → E1 and E2 E → not E1 E → ( E1 ) E → id1 relop id2 { emit (‘or’) } { emit (‘and’) } { emit (‘not’) } {} { emit(‘push ‘ || id1.name); emit(‘push ’ || id2.name); emit (‘relop ’ || relop.op) } { emit ( ‘1’ ) } { emit ( ‘0’ ) }
2011-3-28 luanj@mail.ustc.edu.cn 11
7.7
• 修改图7.11的语法制导定义,为栈机器产生代码。
E → E1 or E2 E → not E1 E → ( E1 ) E → id1 relop id2 E → E1 and E2 { E.place := newtemp; emit (E.place, ‘:=’, E1.place, ‘or’, E2.place) } { E.place := newtemp; emit (E.place, ‘:=’, E1.place, ‘and’, E2.place) } { E.place := E1.place } { E.place := newtemp; emit (E.place, ‘:=’, ‘not’, E1.place) } { E.place := newtemp; emit (‘if’, id1.place, relop.op, id2.place,‘goto’, nextstat+3 ); emit (E.place, ‘:=’, ‘0’ ); emit (‘goto’, nextstat + 2 ); emit (E.place, ‘:=’, ‘1’ ) } { E.place := newtemp; emit (E.place, ‘:=’, ‘1’ ) } { E.place := newtemp; emit (E.place, ‘:=’, ‘0’ ) }
2011-3-28
luanj@mail.ustc.edu.cn
9
7.5
• 算符θ作用于表达式e1,e2,...,ek的前缀形式 是θp1p2...pk,其中pi是ei的前缀形式。 (a) 写出a*-(b+c)的前缀形式。 (c) 给出把表达式翻成前缀形式的语法制导 定义。
2011-3-28
luanj@mail.ustc.edu.cn
10
7.5 (续) (续
• (a) *a-+bc • (c) 表达式翻成前缀形式的语法制导定义
E -> E+T | T T -> T*F | F F -> -F | (E) | id L -> En { printf(E.string); } E -> E1 + T { E.string = “+” + E1.string + T.string; } E -> T { E.string = T.string; } T -> T1*F { T.string = “*” + T1.string + F.string; } T -> F { T.string = F.string; } F -> -F1 { F.string = “-” + F1.string; } F -> (E) { F.string = E.string; } F -> id { F.string = id.value; }
2011-3-28 luanj@mail.ustc.edu.cn 4
7.2
• 把C程序 main(){ int i; int a[10]; while(i <= 10) a[i] = 0; } 的可执行语句翻译成: (a) 语法树 (b) 后缀表示 (c) 三地址代码
2011-3-28 luanj@mail.ustc.edu.cn 5
2011-3-28
luanj@mail.ustc.edu.cn
17
7.9 (续) 题目 (续
… .text .align 4 .globl main .type main,@function main: pushl %ebp movl %esp, %ebp subl $8, %esp nop .p2align 4,,7 .L2: cmpl $0, -4(%ebp) jne .L6 cmpl $0, -8(%ebp) jne .L6 jmp .L5 .p2align 4,,7
7.2 (续) (续
• (a) • (b) 语法树 后缀表示
<= while
= 10 array a i
i 10 <= a i array 0 = while
i 0
2011-3-28
luanj@mail.ustc.edu.cn
6
7.2 (续) (续
• (c) 三地址代码 1: if i <= 10 goto 3 2: goto 5 3: a[i] := 0; 4: goto 1 5: return 0
2011-3-28 luanj@mail.ustc.edu.cn 13
7.8
• 表7.4的语法制导定义把E-> id1< id2翻译成 一对语句 if id1<id2 goto ... goto ... 可以用一个语句 if id1>=id2 goto... 来代替,当E是真时执行后继代码。修改表 7.4的语法制导定义,使之产生这种性质的 代码。
2011-3-28
.L6: cmpl $5, -8(%ebp) jg .L4 jmp .L5 .p2align 4,,7 .L5: jmp .L3 .p2align 4,,7 .L4: movl -8(%ebp), %eax movl %eax, -4(%ebp) jmp .L2 .p2align 4,,7 .L3 .L1 leave ret …
编译原理习题课(5) 编译原理习题课(5)
栾 俊 luanj@mail.ustc.edu.cn 3/28/2011
7.1
• 把算术表达式 –(a+b)*(c+d)+(a+b-c) 翻译成: (a) 语法树 (b) 有向无环图 (c) 后缀表示 (d) 三地址代码
2011-3-28
luanj@mail.ustc.edu.cn