关于编译器的一点理解

参考书目:《Operating Systems Principles and Design》(操作系统原理与设计) ISBN 978-7-302-27489-6

编译器,以某种语言X的形式存在,负责把A语言翻译成B语言,往往B语言的等级是低于A语言的(若B语言的等级高于A语言,应该是类似与反汇编这类)。

本文的相关内容参考了书的53页。

假定:我们假定C(X,Y,Z)是一个编译器,这个编译器用Z语言写成,负责将X语言翻译成Y语言。如上文所说,Y的等级往往是低于X的等级的。

书中给出了三个例子,这里也就介绍书中的三个例子。

Case1:

假定我们已经有了C(L,A,A),我们要设计一个C(L,B,B)。

A可以是直接在机器上运行的低级语言,也可以是高级语言,其实A是高级语言也没有关系,只是需要更多的步骤来让A最终可以在机器上运行。

简单起见,可以认为我们现在已经拥有了一个机器,叫做机器A,机器A上可以直接运行A语言写的程序,我们现在得到的是一个可以在机器A上运行(因为是用A语言写成的)的编译器,目标是设计出一个编译器,这个编译器是用B语言写成(若B是低级的语言,则该编译器可以直接运行的机器B上),可以将L语言的代码翻译成B语言的代码。

为了实现最终的目标,步骤是这样的:

(a)我们首先实现一个C(L,B,L),因为L是相对较高级的语言,所以用L来实现编译器会比较容易。而且,我们实现这个编译器的目的是为了利用我们事先得到的编译器C(L,A,A)。

现在我们可以将我们实现的这个编译器使用C(L,A,A)进行编译,我们会得到一个C(L,B,A),即,可以在机器A上运行,能将L语言的代码翻译成B语言的编译器。在这里,我们偶然的得到了一个交叉编译器,但是还没有实现目标。

(b)现在我们将我们之前实现的C(L,B,L)使用C(L,B,A)进行编译,C(L,B,A)会将C(L,B,L)的代码翻译成B语言,而C(L,B,L)的功能不变(还是将L语言翻译成B语言),现在我们已经得到C(L,B,B)

 

Case2:

假定我们还是拥有C(L,A,A),我们要设计一个C(L',A,A)。

设计过程是这样的,先实现C(L',A,L),即用L语言写成的,能将L'语言翻译成A语言的编译器。

然后将这个编译器使用我们预先得到的C(L,A,A)进行编译,编译器的代码变成了A语言,功能不变,我们得到了目标C(L',A,A)。

 

Case3:

假定我们现在没有编译器,要设计的是C(L,A,A)。

设计过程是这样的:

(a)先选L语言的一个子集,假定这个子集是S,然后用S实现编译器C(L,A,S)。原因也是使用高级的语言比较容易实现编译器,不然就可以直接使用A语言实现C(L,A,A)了。

(b)现在我们需要用A语言实现C(S,A,A),因为A是低级语言,只实现L语言的子集会比完全实现L语言要容易。然后我们就把C(L,A,S)使用C(S,A,A)进行编译,得到目标C(L,A,A)。

 

总结:

尽可能利用已有的编译器; 尽可能使用相对较为高级的语言来实现编译器; 当不得不使用某种低级语言来实现某种高级语言的编译器时,可以选择该高级语言的一个子集作为中介。

当然,直接使用低级语言来完整地实现某种高级语言的编译器也是可行的,大概工作量会很大吧。

 

posted @ 2016-04-22 21:22  张不正  阅读(298)  评论(0编辑  收藏  举报
返回顶部