• 关于编译器的一点理解


    参考书目:《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)。

    总结:

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

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

  • 相关阅读:
    php 可变函数用法
    javascript语法里一些难点问题
    jquery技巧总结
    Bootstrap学习笔记
    Linux下中文文件名乱码问题的详解
    php中iconv函数使用方法,解决中文乱码
    web制作、开发人员需知的Web缓存知识
    鲍鱼开始讲八皇后了
    鲍鱼开始讲八皇后了
    double links....baoyuzuoye
  • 原文地址:https://www.cnblogs.com/vanwoos/p/5422802.html
走看看 - 开发者的网上家园