编译原理,陈意云 ,课后答案

合集下载

编译原理陈意云课后答案.ppt

编译原理陈意云课后答案.ppt

5
3.2
• 考虑文法 S -> aSbS|bSaS|ε (a) 为句子abab构造两个不同的最左推导, 以说明此文法二义 (b) 为abab构造对应的最右推导 (c) 为abab构造对应的分析树 (d) 这个文法产生的语言是什么
2019/3/22
luanj@
6
3.2 (续)
luanj@ 9
2019/3/22
3.4 (续)
• 该文法没有体现运算符 |、*、() 、并置的优 先级,因而是二义的。
R=>R|R=> a|R =>a|R*=>a|b* R=>R*=>R|R*=>a|R*=>a|b*
• E -> E’|’T | T T -> TF | F F -> F* | (E) | a | b
• (1) S=>aSbS=>abS=>abaSbS=>ababS=>abab (2) S=>aSbS=>abSaSbS=>abaSbS=>ababS=>abab • S=>aSbS=>aSb=>abSaSb=> abSab =>abab (2)
S a S ε b a S ε (1) 描述的语言是a,b数目相等的串 S b S ε S
S
( L S a L , ( L S a
2019/3/22 luanj@ 3
) S L , ) S a
3.1 (续) - (a,((a,a),(a,a)))
S =>(L) =>(L,S) =>(S,S) =>(a,S) =>(a,(L)) =>(a,(L,S)) =>(a,(S,S)) =>(a,((L),S)) =>(a,((L,S),S)) =>(a,((S,S),S)) =>(a,((a,S),S)) =>(a,((a,a),S)) =>(a,((a,a),(L))) =>(a,((a,a),(L,S))) =>(a,((a,a),(S,S))) =>(a,((a,a),(a,S))) =>(a,((a,a),(a,a))) S =>(L) =>(L,S) =>(L,(L)) =>(L,(L,S)) =>(L,(L,(L))) =>(L,(L,(L,S))) =>(L,(L,(L,a))) =>(L,(L,(S,a))) =>(L,(L,(a,a))) =>(L,(S,(a,a))) =>(L,((L),(a,a))) =>(L,((L,S),(a,a))) =>(L,((L,a),(a,a))) =>(L,((S,a),(a,a))) =>(L,((a,a),(a,a))) =>(S,((a,a),(a,a))) =>(a,((a,a),(a,a)))

中国科学技术大学陈意云编译原理全套参考资料chapter4

中国科学技术大学陈意云编译原理全套参考资料chapter4

中国科学技术大学陈意云编译原理全套参考资料chapter4中国科学技术大学陈意云编译原理全套参考资料chapter4 第四章语法制导的翻译在3.7节用Yacc写的例子中,我们看到一种有用的描述形式:语言结构的属性附加在代表语言结构的文法符号上,这些属性值由附加在文法产生式的语义动作来计算,这些语义动作在归约对应的产生式时进行计算,由此得到结果。

这种描述形式可用来描述编译器的语义分析,因此本章系统地研究这种称之为“语法制导下的语言翻译”的描述方法及其实现。

它的语义动作(有时称为语义规则)的计算可以产生代码、把信息存入符号表、显示出错信息、或完成其它工作。

语义规则的计算结果就是我们所要的记号流的翻译。

本章讨论语义规则和产生式相联系的两种方式:语法制导的定义和翻译方案。

语法制导定义是较抽象的翻译说明,它隐蔽了一些实现细节;而翻译方案陈述了一些实现细节,主要是指明了语义规则的计算次序。

在第五章说明语义检查和第七章描述中间代码生成时,大量使用这两种方法。

本章还讨论语法制导定义和翻译方案的实现方法。

概念上的方法是,首先分析输入的记号串,建立分析树,然后从分析树得到描述结点属性间依赖关系的有向图,从这个依赖图得到语义规则的计算次序,然后进行计算,最终得到翻译的结果。

实际的实现并不需要按上面步骤逐步进行,本章将讨论几种不同限制下的实现方法。

4.1 语法制导的定义语法制导的定义是上下文无关文法的推广,其中每个文法符号都有一个属性集合,它分成两个子集,分别叫做该文法符号的综合属性集合和继承属性集合。

如果我们把分析树上的结点看成是保存对应文法符号的属性的记录,那么属性对应记录的域。

属性可以表示任何东西:串、数、类型、内存单元,或其它想表示的东西。

分析树结点的属性值由该结点所用产生式的语义规则定义。

在语法制导定义中,我们把其中的文法称为基础文法。

本节介绍语法制导定义的形式及其概念上的实现模型。

4.1.1 语法制导定义的形式在语法制导定义中,每个文法符号有一组属性,每个文法产生式A , ,有一组形式为b := f (c, c, …, c )的语义规则,其中f 是函数,b和c, c, …, c 是该产生式的文法符号的12k12k属性,并且:(1) 如果b是A的属性,c , c , …, c 是产生式右部文法符号的属性或A的其它属12k性,那么b叫做文法符号A的综合属性。

5编译原理,陈意云 ,课后答案5

5编译原理,陈意云 ,课后答案5

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@
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, ); }

编译原理陈意云_课后答案2.

编译原理陈意云_课后答案2.

2021/4/13
luanj@
22
3.15
• (a) 用3.1的文法构造(a,(a,a))的最右推导, 说出每个右句型的句柄
• (b) 给出对应(a)的最右推导的移进-归约分 析器的步骤
• (c) 对照(b)的移进-归约,给出自下而上构 造分析树的步骤。
2021/4/13
➢ 期望的是: if expr then if expr then matched_stmt else if expr then matched_stmt else stmt
2021/4/13
luanj@
13
3.5 (续)
• 一种推导,和期望的不一样
➢ stmt
=> matched_stmt => if expr then matched_stmt else stmt => if expr then if expr then matched_stmt else stmt else stmt => if expr then if expr then matched_stmt else if expr then stmt else stmt => if expr then if expr then matched_stmt else if expr then matched_stmt else stmt
2021/4/13
luanj@
S
( L) L,S
S ( L)
aL
,
S
S
( L)
( L) L , S
L , SS
a
S
aa
4
a
3.1 (续)
• 描述的语言: 括号匹配的串,串中的各项由”,”隔开,

5编译原理,陈意云 ,课后答案5

5编译原理,陈意云 ,课后答案5

2019/2/12
luanj@
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, ); }
编译原理习题课(5)
栾 俊 luanj@ 2019/2/12
7.1
• 把算术表达式 –(a+b)*(c+d)+(a+b-c) 翻译成: (a) 语法树 (b) 有向无环图 (c) 后缀表示 (d) 三地址代码
2019/2/12
luanj@
{ enter(, 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; }
2019/2/12 luanj@ 11

编译原理

编译原理

《编译原理》课后习题答案第 1 章引论第 1 题解释下列术语:(1)编译程序(2)源程序(3)目标程序(4)编译程序的前端(5)后端(6)遍(1)编译程序:如果源语言为高级语言,目标语言为某台计算机上的汇编语言或机器语言,则此翻译程序称为编译程序。

(2)源程序:源语言编写的程序称为源程序。

(3)目标程序:目标语言书写的程序称为目标程序。

(4)编译程序的前端:它由这样一些阶段组成:这些阶段的工作主要依赖于源语言而与目标机无关。

通常前端包括词法分析、语法分析、语义分析和中间代码生成这些阶段,某些优化工作也可在前端做,也包括与前端每个阶段相关的出错处理工作和符号表管理等工作。

(5)后端:指那些依赖于目标机而一般不依赖源语言,只与中间代码有关的那些阶段,即目标代码生成,以及相关出错处理和符号表操作。

(6)遍:是对源程序或其等价的中间语言程序从头到尾扫视并完成规定任务的过程。

第 2 题一个典型的编译程序通常由哪些部分组成?各部分的主要功能是什么?并画出编译程序的总体结构图。

一个典型的编译程序通常包含 8 个组成部分,它们是词法分析程序、语法分析程序、语义分析程序、中间代码生成程序、中间代码优化程序、目标代码生成程序、表格管理程序和错误处理程序。

其各部分的主要功能简述如下。

词法分析程序:输人源程序,拼单词、检查单词和分析单词,输出单词的机内表达形式。

语法分析程序:检查源程序中存在的形式语法错误,输出错误处理信息。

语义分析程序:进行语义检查和分析语义信息,并把分析的结果保存到各类语义信息表中。

中间代码生成程序:按照语义规则,将语法分析程序分析出的语法单位转换成一定形式的中间语言代码,如三元式或四元式。

中间代码优化程序:为了产生高质量的目标代码,对中间代码进行等价变换处理。

目标代码生成程序:将优化后的中间代码程序转换成目标代码程序。

表格管理程序:负责建立、填写和查找等一系列表格工作。

表格的作用是记录源程序的各类信息和编译各阶段的进展情况,编译的每个阶段所需信息多数都从表格中读取,产生的中间结果都记录在相应的表格中。

中国科学技术大学陈意云编译原理全套参考资料陈意云编译原理全套参考资料chapter8

中国科学技术大学陈意云编译原理全套参考资料陈意云编译原理全套参考资料chapter8

基本块和流图
8.3.4 下次引用信息 为每个三地址语句x := y op z决定x、y和z的 下次引用信息
i: x := y op z ...
没有对x的赋值
j: … := x … ...
没有对x的赋值
k: … := … x
基本块和流图
• 对每个基本块从最后一个语句反向扫描到第 一个语句,可以得到下次引用信息
若R0,R1和R2分别含a,b和c的地址,则
MOV *R1, *R0
ADD *R2, *R0
代价= 2
目标机器
a := b + c, a、b和c都静态分配内存单元
若R0,R1和R2分别含a,b和c的地址,则
MOV *R1, *R0
ADD *R2, *R0
代价= 2
若R1和R2分别含b和c的值,并且b的值在这个
目标机器
8.2.1 目标机器的指令系统
选择可作为几种微机代表的寄存器机器
四字节组成一个字,有n个通用寄存器R0,R1, …,Rn-1。
二地址指令 op 源,目的
MOV {源传到目的}
ADD {源加到目的}
SUB
{目的减去源}
目标机器
地址模式和它们的汇编语言形式及附加代价
模式
形式 地址
附加代价
绝对地址 M
基本块和流图
8.3.1 基本块 基本块:连续的语句序列,控制流从它的开始
进入,并从它的末尾离开
再用有向边表示基本块之间的控制流信息,就 能得到程序的流图
基本块和流图
三地址语句序列的划分基本块 • 首先确定所有的入口语句
–序列的第一个语句是入口语句 –能由条件转移语句或无条件转移语句转到的语句
是入口语句 –紧跟在条件转移语句或无条件转移语句后面的语

编译原理课后答案

编译原理课后答案

<表达式>AVV ------ *第二早1、 L(G[S])={ abc }2、 L(G[N])={ n 位整数或空字符串| n>0}3、 G[E] : E —>E+D | E-D | DD —>0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 94、 L(G[Z])={ a n b n | n>0 }5、(1)考虑不包括“ 0”的情况G[S]: S — >0S | ABC | 2 | 4| 6 | 8A —>1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9B —>AB | 0B | &C —>0 | 2 | 4 | 6 | 8考虑包括“ 0”的情况: G[S]: S — >AB | CB —>AB | CA —>0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 C —>0 | 2 | 4 | 6 | 8(2)方法1:G[S]: S — > ABC | 2 | 4 | 6 | 8A —>1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9B —>AB | 0B | &C —>0 | 2 | 4 | 6 | 8方法2:G[S]: S — >AB | CB —> AB | 0B |C | 0A —> 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 C —>2 | 4 | 6 | 8&设<表达式 >为E , <项>为T , <因子〉为F ,注:推导过程不能省略,以下均为最 左推导(1) E => T => F => i(4) E => E+T => T+T => T*F+T => F*F+T => i*F+T => i*i+T => i*i+F => i*i+i (6) E => E+T => T+T => F+T => i+T => i+T*F => i+F*F => i+i*F => i+i*I8、 是有二义性的,因为句子abc 有两棵语法树(或称有两个最左推导或有两个最右 推导)ii<表达式>最左推导1: S => Ac => abc最左推导2:S => aB => abc9、⑴a a(2) 该文法描述了变量a和运算符+、*组成的逆波兰表达式10、(1)该文法描述了各种成对圆括号的语法结构(2)是有二义性的,因为该文法的句子()()存在两种不同的最左推导:最左推导1:S => S(S)S => (S)S => ()S => ()S(S)S => ()(S)S => ()()S => ()() 最左推导2:S => S(S)S => S(S)S(S)S => (S)S(S)S=> ()S(S)S => ()(S)S => ()()S => ()()11、⑴因为从文法的开始符E出发可推导出E+T*F,推导过程如下:E => E+T =>E+T*F,所以E+T*F 是句型。

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

VC 非法访问)
17.07.2020
.
5
6.3
• 一个C程序如下:
typedef struct _a{ char c1; long I; char c2; double f;
} a; typedef struct _b{
char c1; char c2; long l; double f; } b; main(){ printf(“Size of double, long, char = %d,%d,%d\n”, sizeof(double), sizeof(long), sizeof(char)); printf(“Size of a, b = %d,%d\n”, sizeof(a), sizeof(b)); } 该程序在SPARC/Solaris工作站上运行结果如下:
编译原理习题课(4)
栾俊 luanj@
17.07.2020
6.1
• 使用Pascal的作用域规则,确定下面程序中用于名字a,b 的每个出现的声明。程序输出整数1,2,3,4
program a (input output); procedure b (u, v, x, y : integer); var a : record a, b : integer end; b : record b, a : integer end; begin with a do begin a := u; b := v end; with b do begin a := x; b := y end; writeln (a.a, a.b, b.a, b.b) end; begin b(1, 2, 3, 4) end.
|1.0
|
• GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
17.07.2020
.ห้องสมุดไป่ตู้
8
6.4
• 下面给出一个C程序及其在X86/Linux下的编译结 果,根据所生成的汇编程序来解释程序中4个变量 的存储分配、作用域、生成期和置初始值方式的 区别
static long aa = 10;
该程序经以前的某些C编译器编译后,运行结果为: cp1 = abcdefghij cp2 = ghij
试分析为什么cp2被修改
17.07.2020
.
4
6.2 (续)
• C语言中,字符串会添加‘\0’作为串的结束符,因此, 串”12345”存储为”12345\0”,而串”12345\0abc\0”打 印出来的只有12345
Size of double, long, char = 8,4,1 Size of a, b = 24,16 试分析为什么
17.07.2020
.
6
6.3 (续)
• 数据对齐:为了寻址方便
• A: char long char
OXXX OOOO OXXX XXXX
double
OOOO OOOO
• B: char char long double
17.07.2020
.
2
6.1 (续)
• with a a:=u b:=v with b a:=x b:=y
a—record a—a.a b—a.b b—record a—b.a b—b.b
17.07.2020
.
3
6.2
• 考虑下面的C程序 main(){ char * cp1, * cp2; cp1 = “12345”; cp2 = “abcdefghij”; strcpy(cp1, cp2); printf(“cp1 = %s \n cp2 = %s \n”, cp1, cp2); }
short bb = 20;
func(){ static long cc = 30;
short dd = 40;
} 生成的汇编代码:
17.07.2020
.
9
6.4 (续)
.file "static.c“ .version “01.01” gcc2_compiled:
.data .align 4 .type aa,@object .size aa,4 aa: .long 10 .globl bb .align 2 .type bb,@object .size bb,2 bb: .value 20 .align 4 .type cc.2,@object .size cc.2,4
O OXX OOOO OOOO OOOO
• 可以用gcc –S命令查看编译后的汇 编码 VC下可以在debug模式下,菜单栏 View->Debug Windows中 Dissassenbly查看编译后的汇编码
• GCC: (GNU) 3.2.2 (Red Hat Linux 3.2.2-5)结果为20,16
17.07.2020
cc.2: .long 30 .text .align 4
.globl func .type func,@function
func: pushl %ebp movl %esp, %ebp subl $4, %esp movw $40, -2(%ebp)
.L1: leave ret
• 常量区连续分配
• 因而本题中”12345”和”abcdefghij”存储为 1 2 3 4 5 \0 a b c d e f g h i j \0
cp1
cp2
拷贝后结果为
a b c d e f g h i j \0 f g h i j \0
cp1
cp2
• 现代编译器编译通过,执行时会出错。(GCC: 段错误 /
.Lfe1: .size func,.Lfe1-func .ident "GCC: (GNU) egcs-2.91.66
19990314/Linux(egcs-1.1.2 release)”
.
10
6.4 (续)
.file "static.c“
.version “01.01”
17.07.2020
.
7
6.3 (续)
• #include <stdio.h> static struct _a{ char c1; long i; char c2; double f; } a = {'A', 1, 'B', 1.0};
• VC6下,Debug模式Memory窗口查看
|A
|1
|B
相关文档
最新文档