如何编写一个编译器,java解释器和编译器的区别和联系,如何编写一个编译器,java解释器和编译器的区别与联系

  如何编写一个编译器,java解释器和编译器的区别和联系,如何编写一个编译器,java解释器和编译器的区别与联系

  简单介绍一下编程方法的历史变迁。

  -埃里克奥肖内西(作者)

  计算机诞生的早期,硬件很贵,程序员相对便宜。这些廉价的程序员连“程序员”的头衔都没有,数学家和电工经常扮演他们的角色。早期的计算机是用来快速解决复杂的数学问题的,所以数学家自然适合“编程”。

  什么是程序?我们先来看看背景。电脑自己什么都做不了。这些行动需要程序。该程序可以被认为是一个非常准确的食谱。配方读取输入并生成相应的输出。配方的每一步都由操作数据的命令组成。虽然听起来有点复杂,但你可能知道下一句是什么意思。

  1=3的加号是“命令”,数字1和2是数据。数学上的等号表示等式两边的部分“等价”,但在大多数编程语言中,在变量上使用等号表示“赋值”。当计算机执行上述语句时,这个加法的结果“3”将被存储在内存的某个地方。

  计算机知道如何使用数字进行数学运算,以及如何在内存结构中移动数据。这里不展开内存。知道内存一般分为“快/小空间”和“慢/大空间”两类。CPU读写寄存器速度很快,但空间很小,相当于速记笔记。主存通常空间很大,但读写速度远不及寄存器。在程序执行期间,CPU继续将其所需的数据从主存储器移动到寄存器,并将其结果返回到主存储器。

  那时候电脑贵,人力便宜。程序员需要花费大量时间将手写公式翻译成计算机可执行指令。第一台计算机只有一个非常糟糕的用户界面,有些只有前面板上的拨动开关。这些开关代表存储“单元”中的每个“0”和“1”。程序员必须配置内存单元,选择存储位置,然后将该单元提交给内存。这是一个耗时且容易出错的过程。

  程序员Betty Jean Infinite Juice(左)和atgddx Bilas(右)在操作。

  后来有个电工觉得自己的时间宝贵,就写了一个程序,可以把人能读懂的“菜谱”等输入内容转换成计算机可读的版本。这就是第一个“汇编”,在当时引起了很大的争议。这些昂贵机器的所有者不想将计算资源浪费在人们已经可以完成的任务上(尽管速度慢且容易出错)。但随着时间的推移,人们发现使用汇编语言在速度和正确性上都优于手工编写机器语言,增加了计算机的“实际工作量”。

  虽然汇编程序相对于在机器面板上切换位的状态已经有了很大的进步,但是这种编程方式还是很专业的。上面的加法示例在汇编语言中看起来很相似:

  01mov r0,102 mov R1,203 add r0,R1,R204 MOV 64,r005 STO R2,R0都是计算机指令。前面是指令的缩写,后面是指令操作的数据。applet首先将值1“移动”到寄存器R0,然后将值2移动到寄存器R1。第03行将两个寄存器R0和R1的值相加,并将结果保存在R2寄存器中。最后,第04行和第05行决定了结果应该放在主存的什么地方。这是地址64。管理存储在内存中的数据的位置是编程过程中最耗时和最容易出错的部分之一。

  编译器比手写的计算机指令要好得多,但早期的程序员想像以前写公式一样写程序。这种需求推动了高级编译语言的发展,有些已经成为历史,有些至今仍在使用。例如,尽管ALGO已经成为历史,但像Fortran和C这样的语言仍在继续解决实际问题。

  ALGO和Fortran编程语言树

  这些“高级”语言使程序员更容易编写程序。在C语言中,加法过程如下。

  int x;x=1 ^ 2;第一条语句显示了程序使用的内存块。在这个例子中,这个内存应该是一个整数,名字应该是x,第二句是加法。尽管写得与此相反。一个C程序员说是“把X代入1 ^ 2的结果”。注意,程序员不需要决定X在内存中的存储位置,这个任务会传递给编译器。

  这个新程序叫做“编译器”,可以把用高级语言编写的程序转换成汇编语言,然后用汇编程序把汇编语言转换成机器可读的程序。这种程序组合通常被称为“工具链”,因为一个程序的输出仍然是另一个程序的输入。

  编译语言相对汇编语言的优势体现在从一台电脑迁移到另一台不同型号或品牌的电脑上。在计算机的早期,许多公司制造不同类型的计算机硬件,包括IBM、DEC、德州仪器、UNIVAC和惠普。所有这些电脑除了需要连接电源之外,几乎没有什么共同之处。而且将一个程序从一台计算机翻译到另一台计算机通常需要几年时间。

  有了高级语言,只需要把编译器的工具链移植到新的平台上。有了可用的编译器,用高级语言编写的程序最多只需稍加修改就可以在新计算机上重新编译。高级语言的编译真的是革命性的成就。

  1983

  IBM PC XT的发布是硬件价格下降的早期例子。

  程序员的生活得到了很大的改善。相比之下,通过高级语言表达他们想要解决的问题,事情就简单多了。随着半导体技术的进步和集成芯片的发明,计算机硬件的价格大幅下降。计算机变得越来越快,功能越来越强,而且便宜得多。从某个时间点(可能是20世纪80年代末),事情发生了逆转,程序员变得比他们使用的硬件更有价值。

  随着时间的推移,一种新的编程方法出现了。一种叫做“解释器”的特殊程序可以直接读取一个程序,并将其转换成计算机指令以便立即执行。类似于编译器,解释器读取程序并将其转换成中间形式。但与编译器不同,解释器直接执行程序的这种中间形式。解释性语言每次执行都要经历这个过程;编译器只需要编译一次,然后计算机每次只需要执行编译好的机器指令。

  顺便说一句,这个特性就是让人觉得解释性程序运行缓慢的原因。然而,现代计算机的性能如此强大,以至于大多数人都无法区分编译程序和解释程序。

  解释程序(有时称为“脚本”)甚至更容易移植到不同的硬件平台上。因为脚本不包含任何特定于机器的指令,所以同一版本的程序无需任何修改就可以直接在许多不同的计算机上运行。当然,首先要把解释器移植到新机器上。

  一种流行的解释语言是perl。perl中加法问题的完整表达如下:

  $x=1 2虽然这个程序看起来和C语言的版本差不多,操作上也没有太大区别,但是缺少初始化变量的语句。实际上,还有一些其他的区别(超出了本文的范围),但你应该已经注意到,我们编写计算机程序的方式与数学家用笔和纸编写数学表达式的方式非常接近。

  虚拟机的最新编程方法是虚拟机(VM)。虚拟机分为两类:系统虚拟机和进程虚拟机。这两种虚拟机都提供了不同级别的“真实”计算硬件的抽象,但是它们的范围是不同的。虚拟机是一种替代物理硬件的软件,而过程虚拟机被设计成以“独立于系统”的方式执行程序。所以在这个例子中,进程虚拟机(以后我会指这种类型的虚拟机)的作用范围和解释器类似,因为程序是先编译成中间形式,然后虚拟机执行这个中间形式。

  虚拟机和解释器的主要区别在于,虚拟机创建了一个虚拟CPU和一组虚拟指令集。有了这个抽象,我们就可以编写前端工具,把不同语言的程序编译成虚拟机可以接受的程序。也许最流行和最知名的虚拟机是Java虚拟机(JVM)。本来JVM在90年代只支持Java语言,现在可以运行很多流行的编程语言,包括Scala、Jython、JRuby、Clojure、Kotlin等等。还有一些其他不太常见的例子,这里就不说了。最近才知道,我最喜欢的语言Python不是解释性语言,而是运行在虚拟机上的语言!

  虚拟机仍然在延续历史趋势,即程序员在使用特定领域的编程语言解决问题时,需要的特定计算平台的知识越来越少。

  就是这样。我希望你喜欢这篇简短的文章,它简要介绍了软件背后的工作原理。接下来你还想让我讨论其他话题吗?请在评论中告诉我。

  via:https://open source . com/article/19/5/primer-汇编器-编译器-解释器

  作者:Linux中国

如何编写一个编译器,java解释器和编译器的区别和联系,如何编写一个编译器,java解释器和编译器的区别与联系