编译原理试题

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

2001年编译原理试题
1.(10分)处于/* 和 */之间的串构成注解,注解中间没有*/。

画出接受这种注解的DFA 的状态转换图。

2.(10分)为语言
L = {a m b n | 0 ≤ m ≤ 2n}(即a 的个数不超过b 的个数的两倍 写一个LR (1)文法,不准超过6个产生式。

(若超过6个产生式,不给分。

若所写文法不是LR (1)文法,最多给5分。

) 3.(10分)构造下面文法的LL (1)分析表。

D → TL T → int | real L → id R R → , id R | ε 4.(15分)就下面文法 S → ( L) | a L → L , S | S ∙ 给出一个语法制导定义,它输出配对括号的个数。

∙ 给出一个翻译方案,它输出每个a 的嵌套深度。

如句子(a, (a, a) ),第一小题的输出是2,第二小题的输出是1 2 2。

9.(10分)如果在A 机器上我们有C 语言编译器CC A ,也有它的源码S A (用C 语言写成)。

如何利用它通过尽量少的工作来得到B 机器的C 语言编译器CC B 。

10.(5分)表达式(λx .(λyz .(x + y ) + z ) 3) 4 5和(λx .(λyz .(x + y ) + z ) 3 5) 4有同样的结果。

在抽象机FAM 上,哪一个表达式对应的目标代码的执行效率高?为什么?
2001年编译原理试题参考答案
1
2.LR (1)文法 LR (1)文法 二义文法 S → AB | aABb S → AB S → AASb | ε A → aaAb | ε A → aaAb | ab | ε A → a | ε B → Bb | ε B → Bb | ε 3. int real id , $ D D →TL D →TL T T →int T →real L L →id R R R →, id R R → ε 4. S ' → S print(S.num) S → (L) S.num := L.num +1 S → a S.num := 0 L → L 1,S L.num := L 1.num + S.num L → S L.num := S.num
*
S ' → {S.depth := 0} S S → {L.depth := S.depth +1} (L) S → a {print(S.depth)} L → {L 1.depth := L.depth} L 1, {S.depth := L.depth} S L → { S.depth := L.depth} S
9. ∙ 修改源码S A 的代码生成部分,让它产生B 机器的代码,称结果程序为S B 。

∙ 将S B 提交给CC A 进行编译,得到一个可执行程序。

∙ 将S B 提交给上述可执行程序进行编译,得到所需的编译器CC B 。

10.第一个表达式在执行λyz .(x + y ) + z ) 3时出现参数个数不足的情况,因此有FUNV AL 的值进入栈顶,然后发现参数个数不足,又把它做成FANV AL 的情况。

而第二个表达式执行的是(λyz .(x + y ) + z ) 3 5,不会出现参数个数不足的情况。

因此第二个表达式的执行效率比第一个表达式的高。

2003年编译原理试题
1.(20分)写出字母表∑ = {a, b}上语言L = {w | w 中a 的个数是偶数}的正规式,并画出接受该语言的最简DFA 。

2.(15分)考虑下面的表达式文法,它包括数组访问、加和赋值: E → E[E] | E + E | E = E | (E) | id
该文法是二义的。

请写一个接受同样语言的LR(1)文法,其优先级从高到低依次是数组访问、加和赋值,并且加运算是左结合,赋值是右结合。

3.(10分)下面是产生字母表∑ = { 0, 1, 2}上数字串的一个文法: S → D S D | 2 D → 0 | 1
写一个语法制导定义,它打印一个句子是否为回文数(一个数字串,从左向右读和从右向左读都一样时,称它为回文数)。

2003年编译原理试题参考答案
1.语言L 的正规式是: (a b *a | b )* 或 b *(a b *a b *)* 接受该语言的最简DFA 是:
2. E → T = E | T T → T + F | F F → F[E] | (E) | id
3.
S ' → S
print(S.val)
b
S → D1 S1 D2S.val = (D1.val = D2.val) and S1.val
S → 2 S.val = true
D → 0 D.val = 0
D → 1 D.val = 1
1.(15分)
(a) 字母表∑ = { ( , ) }上的语言{ ( ), (( )( )), ((( ))), ( )( )( )( )( )}是不是正规语言?为什么?
(b) 正规式(0 | 1)*和( (ε | 0) 1* )*是否等价,说明理由。

2.(15分)接受文法
S → A a | b A c | d c | b d a
A→ d
活前缀的DFA见下图。

请根据这个DFA来构造该文法的SLR(1)分析表,并说明该文法为什么不是SLR(1)文法。

3.(10分)现有字母表∑={ a },写一个和正规式a*等价的上下文无关文法,要求所写的文法既不是LR文法,也不是二义文法。

4.(20分)
(a) 下面的文法定义语言L = { a n b n c m | m, n ≥ 1}。

写一个语法制导定义,其语义规则的作用是:对不属于语言L的子集L1= { a n b n c n | n ≥ 1}的句子,打印出错信息。

S → D C D → a D b | a b C → C c | c
(b) 语句的文法如下:
S →id := E | if E then S | while E do S | begin S ; S end | break
写一个翻译方案,其语义动作的作用是:若发现break不是出现在循环语句中,及时报告错误。

2005年编译原理和技术试题参考答案
1.(a) 语言{ ( ), (( ) ( )), ((( ))), ( ) ( ) ( ) ( ) ( )}是正规语言,因为该语言只包括有限个句子,它可以用正规式定义如下:
( ) | (( )( )) | ((( ))) | ( ) ( ) ( ) ( ) ( )
(b) 我们分析正规式( (ε | 0) 1* )*表示的语言。

可以看出正规式(ε | 0) 1*描述的语言是集合{ε, 1, 11, 111, …, 0, 01, 011, 0111, …},它含长度为1的两个串0和1。

那么,(0 | 1)*所描述的语言是( (ε | 0) 1* )*所描述的语言的子集,因为(0 | 1)*表示字母表{0, 1}上所有串的集合,因此( (ε | 0) 1* )*所描述的语言不可能再有更多的句子,因而也是表示字母表{0, 1}上所有串的集合。

2.分析表如下。

因为有两处有移进-归约冲突,所以该文法不是SLR(1)文法。

注:
3
S → a S a | a | ε
4.(a) 语法制导的定义如下:
S → D C if D.length ≠C.length then print (“error”)
D → a b D.length := 1
D → a D1 b D.length := D1.length + 1
C → c C.length := 1
C → C1 c C.length := C1.length + 1
(b) 翻译方案如下:
S'→ {S.loop := false}S
S →id := E
S →if E then {S1.loop := S.loop}S1
S →while E do {S1.loop := true}S1
S →begin {S1.loop := S.loop}S1 ; {S2.loop := S.loop}S2end
S →break{if not S.loop then print(“error”) }
1、(15分)
(a) 用正规式表示字母表{a, b}上,a不会相邻的所有串。

b*(abb*)*(a| ε)
(b) 画出一个最简的确定有限自动机,它接受所有大于101的二进制整数。

2、(10分)构造下面文法的LL(1)分析表。

S → a B S | b A S | ε
A→ b A A | a
B → a B B | b
3、(10分)下面的文法是二义文法
S → E
E →while E do E | id := E | E + E | id | (E)
请你为该语言重写一个规范的LR(1)文法,它为该语言中的各种运算体现通常的优先级和结合规则。

不需要证明你的文法是规范LR(1)的。

4、(10分)为下面文法写一个语法制导的定义,它完成一个句子的while-do最大嵌套层次的计算并输出这个计算结果。

S → E
E →while E do E | id := E | E + E | id | (E)
8、(5分)把下面左边的文件file1.c提交给编译器,编译器没有报告任何错误。

而把文件file2.c提交给编译器,错误报告如下:
file2.c: 2: error: conflicting types for …func‟
file2.c: 1: error: previous declaration of …func‟
试分析原因。

(在这两个文件中,第1行都是函数func的原型,第2行都是函数func的定义,函数体为空。


file1.c file2.c
int func(double); int func(double);
int func(f) float f; {} int func(float f) {}
9、(5分)教材上第342页倒数第7行说“将C++语言中一个类的所有非静态属性构成一个C语言的结构类型,取类的名字作为结构类型的名字”。

在这一章都学过后,你认为这句话需要修改吗?
参考答案
1、(a) b*(abb*)*(a| ε)
(b) 见下图。

若不允许前缀的无效0,则去掉状态0上的0转换。

号集合LL(1)分析表
3、
S → E E → while E do E | A
A → id := A | T
T → T + F | F F → id | (E)
4、 语法制导的定义如下:
S → E print(S.loop);
E → while E 1 do E 2 E.loop := max(E 1.loop, E 2.loop) +1;
E → id := E E.loop := E 1.loop; E → E 1 + E 2 E.loop := max(E 1.loop, E 2.loop); E → id E.loop := 0; E → (E 1) E.loop := E 1.loop;
8、文件file1.c 中,函数func 的定义采用传统的方式,形式参数f 的类型被提升到double 。

函数原型中该参数也声明成double 类型,两者类型相同,因此没有错误。

而在文件file2.c 中,函数func 的定义采用现在提倡的形式,形式参数的类型就是float ,不会提升。

它的类型和函数原型中声明的类型不相同,所以编译器会报告错误。

9、需要修改,增加虚方法表指针作为第一个域。

2004年编译原理试题
1.(20分)写出字母表∑ = {a, b}上语言L = {w | w 的最后两个字母是aa 或bb }的正规式,并画出接受该语言的最简DFA 。

2.(15分)说明下面的文法不是SLR(1)文法,并重写一个等价的SLR(1)文法。

S → M a | b M c | d c | b d a M → d 3.(10分)为下面的语言写一个无二义的文法:
ML 语言中用分号分隔语句的语句块,例如: ( (s ; s ) ; ( s ; s ; s ) ; s ) ; ( s ; s ) 6.(15分)考虑下面的三地址语句序列: b := 1 b := 2 if w <= x goto L2 e := b goto L2 L1: goto L3 L2: c := 3 b := 4 c := 6 L3: if y <= z goto L4 goto L5
L4: g := g + 1
h := 8
goto L1
L5: h := 9
(1)在该代码中用水平的横线将代码分成基本块,并给每个基本块一个序号。

(2)画出该代码的控制流图,每个基本块就用(1)的序号表示。

(3)若有循环的话,列出构成每个循环的结点。

7.(5分)如果
(1)用编译命令cc test.c会报告有未定义的符号;
(2)用编译命令cc test.c –lusr.a会得到可执行程序(–lusr.a表示连接库libusr.a)。

那么,用编译命令cc test.c –lusr.a –lusr.a是否会报告有多重定义的符号?请说明理由。

2004年编译原理试题参考答案
1.语言L的正规式是:
(a|b)*(aa|bb)
接受该语言的最简DFA是:
2.S‟ → S S → M a | b M c | d c | b d a M → d
因为a是M的后继符号之一,因此在上面最右边一个项目集中有移进-归约冲突。

等价的SLR(1)文法是
S → d a | b d c | d c | b d a
3.SL → S | SL ; S
S → s | ( SL )
6.(1)(2)
b := 1
b := 2
e := b
goto L2 (2)
L1: goto L3 (3)
L2: c := 3
b := 4
c := 6 (4)
L3: if y <= z goto L4 (5)
goto L5 (6)
L4: g := g + 1
h := 8
goto L1 (7)
L5: h := 9 (8)
(3)结点5、7和3构成一个循环,其中5是入口结点。

7.不会。

连接时,第一次遇到库libusr.a便能解决所有的外部引用。

这样在第二次遇到库libusr.a时什么东西也不会加入目标程序。

12.试写出V T={0,1}上下述集合的正则表达式:
⑴ 所有以1开始和结束的符号串。

1(0|1)*1|1
⑵ 恰含有3个1的所有符号所组成的集合。

0*10*10*10*
⑶ 集合{01,1}。

01|1
⑷ 所有以111结束的符号串。

(0|1)*111
⑴ 试写出非负整数集的正则表达式。

0|(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*
⑵ 试写出以非5数字为头的所有非负整数集的正则表达式。

0|(1|2|3|4|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*设V T={a,b},试构造下述正则表达式的确定性有限状态自动机:
⑴ a(a|b)*baa
⑵ (a|b)*bbb *。

相关文档
最新文档