㈠ 编译器的发展史
编译器
编译器,是将便于人编写,阅读,维护的高级计算机语言翻译为计算机能识别,运行的低级机器语言的程序。编译器将源程序(Source program)作为输入,翻译产生使用目标语言(Target language)的等价程序。源程序一般为高级语言(High-level language),如Pascal,C++等,而目标语言则是汇编语言或目标机器的目标代码(Object code),有时也称作机器代码(Machine code)。
一个现代编译器的主要工作流程如下:
源程序(source code)→预处理器(preprocessor)→编译器(compiler)→汇编程序(assembler)→目标程序(object code)→连接器(链接器,Linker)→可执行程序(executables)
目录 [隐藏]
1 工作原理
2 编译器种类
3 预处理器(preprocessor)
4 编译器前端(frontend)
5 编译器后端(backend)
6 编译语言与解释语言对比
7 历史
8 参见
工作原理
翻译是从源代码(通常为高级语言)到能直接被计算机或虚拟机执行的目标代码(通常为低级语言或机器言)。然而,也存在从低级语言到高级语言的编译器,这类编译器中用来从由高级语言生成的低级语言代码重新生成高级语言代码的又被叫做反编译器。也有从一种高级语言生成另一种高级语言的编译器,或者生成一种需要进一步处理的的中间代码的编译器(又叫级联)。
典型的编译器输出是由包含入口点的名字和地址以及外部调用(到不在这个目标文件中的函数调用)的机器代码所组成的目标文件。一组目标文件,不必是同一编译器产生,但使用的编译器必需采用同样的输出格式,可以链接在一起并生成可以由用户直接执行的可执行程序。
编译器种类
编译器可以生成用来在与编译器本身所在的计算机和操作系统(平台)相同的环境下运行的目标代码,这种编译器又叫做“本地”编译器。另外,编译器也可以生成用来在其它平台上运行的目标代码,这种编译器又叫做交叉编译器。交叉编译器在生成新的硬件平台时非常有用。“源码到源码编译器”是指用一种高级语言作为输入,输出也是高级语言的编译器。例如: 自动并行化编译器经常采用一种高级语言作为输入,转换其中的代码,并用并行代码注释对它进行注释(如OpenMP)或者用语言构造进行注释(如FORTRAN的DOALL指令)。
预处理器(preprocessor)
作用是通过代入预定义等程序段将源程序补充完整。
编译器前端(frontend)
前端主要负责解析(parse)输入的源程序,由词法分析器和语法分析器协同工作。词法分析器负责把源程序中的‘单词’(Token)找出来,语法分析器把这些分散的单词按预先定义好的语法组装成有意义的表达式,语句 ,函数等等。 例如“a = b + c;”前端词法分析器看到的是“a, =, b , +, c;”,语法分析器按定义的语法,先把他们组装成表达式“b + c”,再组装成“a = b + c”的语句。 前端还负责语义(semantic checking)的检查,例如检测参与运算的变量是否是同一类型的,简单的错误处理。最终的结果常常是一个抽象的语法树(abstract syntax tree,或 AST),这样后端可以在此基础上进一步优化,处理。
编译器后端(backend)
编译器后端主要负责分析,优化中间代码(Intermediate representation)以及生成机器代码(Code Generation)。
一般说来所有的编译器分析,优化,变型都可以分成两大类: 函数内(intraproceral)还是函数之间(interproceral)进行。很明显,函数间的分析,优化更准确,但需要更长的时间来完成。
编译器分析(compiler analysis)的对象是前端生成并传递过来的中间代码,现代的优化型编译器(optimizing compiler)常常用好几种层次的中间代码来表示程序,高层的中间代码(high level IR)接近输入的源程序的格式,与输入语言相关(language dependent),包含更多的全局性的信息,和源程序的结构;中层的中间代码(middle level IR)与输入语言无关,低层的中间代码(Low level IR)与机器语言类似。 不同的分析,优化发生在最适合的那一层中间代码上。
常见的编译分析有函数调用树(call tree),控制流程图(Control flow graph),以及在此基础上的 变量定义-使用,使用-定义链(define-use/use-define or u-d/d-u chain),变量别名分析(alias analysis),指针分析(pointer analysis),数据依赖分析(data dependence analysis)等等。
上述的程序分析结果是编译器优化(compiler optimization)和程序变形(compiler transformation)的前提条件。常见的优化和变新有:函数内嵌(inlining),无用代码删除(Dead code elimination),标准化循环结构(loop normalization),循环体展开(loop unrolling),循环体合并,分裂(loop fusion,loop fission),数组填充(array padding),等等。 优化和变形的目的是减少代码的长度,提高内存(memory),缓存(cache)的使用率,减少读写磁盘,访问网络数据的频率。更高级的优化甚至可以把序列化的代码(serial code)变成并行运算,多线程的代码(parallelized,multi-threaded code)。
机器代码的生成是优化变型后的中间代码转换成机器指令的过程。现代编译器主要采用生成汇编代码(assembly code)的策略,而不直接生成二进制的目标代码(binary object code)。即使在代码生成阶段,高级编译器仍然要做很多分析,优化,变形的工作。例如如何分配寄存器(register allocatioin),如何选择合适的机器指令(instruction selection),如何合并几句代码成一句等等。
编译语言与解释语言对比
许多人将高级程序语言分为两类: 编译型语言 和 解释型语言 。然而,实际上,这些语言中的大多数既可用编译型实现也可用解释型实现,分类实际上反映的是那种语言常见的实现方式。(但是,某些解释型语言,很难用编译型实现。比如那些允许 在线代码更改 的解释型语言。)
历史
上世纪50年代,IBM的John Backus带领一个研究小组对FORTRAN语言及其编译器进行开发。但由于当时人们对编译理论了解不多,开发工作变得既复杂又艰苦。与此同时,Noam Chomsky开始了他对自然语言结构的研究。他的发现最终使得编译器的结构异常简单,甚至还带有了一些自动化。Chomsky的研究导致了根据语言文法的难易程度以及识别它们所需要的算法来对语言分类。正如现在所称的Chomsky架构(Chomsky Hierarchy),它包括了文法的四个层次:0型文法、1型文法、2型文法和3型文法,且其中的每一个都是其前者的特殊情况。2型文法(或上下文无关文法)被证明是程序设计语言中最有用的,而且今天它已代表着程序设计语言结构的标准方式。分析问题(parsing problem,用于上下文无关文法识别的有效算法)的研究是在60年代和70年代,它相当完善的解决了这个问题。现在它已是编译原理中的一个标准部分。
有限状态自动机(Finite Automaton)和正则表达式(Regular Expression)同上下文无关文法紧密相关,它们与Chomsky的3型文法相对应。对它们的研究与Chomsky的研究几乎同时开始,并且引出了表示程序设计语言的单词的符号方式。
人们接着又深化了生成有效目标代码的方法,这就是最初的编译器,它们被一直使用至今。人们通常将其称为优化技术(Optimization Technique),但因其从未真正地得到过被优化了的目标代码而仅仅改进了它的有效性,因此实际上应称作代码改进技术(Code Improvement Technique)。
当分析问题变得好懂起来时,人们就在开发程序上花费了很大的功夫来研究这一部分的编译器自动构造。这些程序最初被称为编译器的编译器(Compiler-compiler),但更确切地应称为分析程序生成器(Parser Generator),这是因为它们仅仅能够自动处理编译的一部分。这些程序中最着名的是Yacc(Yet Another Compiler-compiler),它是由Steve Johnson在1975年为Unix系统编写的。类似的,有限状态自动机的研究也发展了一种称为扫描程序生成器(Scanner Generator)的工具,Lex(与Yacc同时,由Mike Lesk为Unix系统开发)是这其中的佼佼者。
在70年代后期和80年代早期,大量的项目都贯注于编译器其它部分的生成自动化,这其中就包括了代码生成。这些尝试并未取得多少成功,这大概是因为操作太复杂而人们又对其不甚了解。
编译器设计最近的发展包括:首先,编译器包括了更加复杂算法的应用程序它用于推断或简化程序中的信息;这又与更为复杂的程序设计语言的发展结合在一起。其中典型的有用于函数语言编译的Hindley-Milner类型检查的统一算法。其次,编译器已越来越成为基于窗口的交互开发环境(Interactive Development Environment,IDE)的一部分,它包括了编辑器、连接程序、调试程序以及项目管理程序。这样的IDE标准并没有多少,但是对标准的窗口环境进行开发已成为方向。另一方面,尽管近年来在编译原理领域进行了大量的研究,但是基本的编译器设计原理在近20年中都没有多大的改变,它现在正迅速地成为计算机科学课程中的中心环节。
在九十年代,作为GNU项目或其它开放源代码项目的一部分,许多免费编译器和编译器开发工具被开发出来。这些工具可用来编译所有的计算机程序语言。它们中的一些项目被认为是高质量的,而且对现代编译理论感性趣的人可以很容易的得到它们的免费源代码。
大约在1999年,SGI公布了他们的一个工业化的并行化优化编译器Pro64的源代码,后被全世界多个编译器研究小组用来做研究平台,并命名为Open64。Open64的设计结构好,分析优化全面,是编译器高级研究的理想平台。
编译器是一种特殊的程序,它可以把以特定编程语言写成的程序变为机器可以运行的机器码。我们把一个程序写好,这时我们利用的环境是文本编辑器。这时我程序把程序称为源程序。在此以后程序员可以运行相应的编译器,通过指定需要编译的文件的名称就可以把相应的源文件(通过一个复杂的过程)转化为机器码了。
编译器工作方法
首先编译器进行语法分析,也就是要把那些字符串分离出来。然后进行语义分析,就是把各个由语法分析分析出的语法单元的意义搞清楚。最后生成的是目标文件,我们也称为obj文件。再经过链接器的链接就可以生成最后的可执行代码了。有些时候我们需要把多个文件产生的目标文件进行链接,产生最后的代码。我们把一过程称为交叉链接。
㈡ 请问,编译软件最早是由谁发明出来的
Grave of Grace
后记
Grace Hopper是个非常amazing的人 (常被称为Amazing Grace),崇拜她的人相当多。虽然她的事迹很多,但是还有很多有类似事迹的人并没有像她这样受到众人的崇拜。由其中一点我们可以看出来:从1947年开始 (二战结束后第二年),她获得了第一个荣誉博士学位 (宾州大学),从那以后,她先后被40多所大学授予荣誉博士学位,其中包括芝加哥大学、华盛顿大学、马里兰大学等知名学府。各种妇女社会团体和学术组织都曾授予Grace各种称号和奖励。1991年,布什总统在白宫授予她的“美国国家技术奖” (National Medal of Technology) 是其中的最高奖项,她也是至今惟一获此殊荣的美国女性。她的名言有很多,她自己最喜欢的,也是她最喜欢对所谓的“年轻人”说的 (在她年老时,她所谓的年轻人就是“年龄不到我的一半的人就叫做年轻人”),这句话是:
“A ship in port is safe, but that is not what ships are built for.”
语录
下面Grace的语录中有几句比较有意思的话。
From then on, when anything went wrong with a computer, we said it had bugs in it.
The most dangerous phrase in the language is, “We’ve always done it this way.”
Humans are allergic to change. They love to say, “We’ve always done it this way.” I try to fight that. That’s why I have a clock on my wall that runs counter-clockwise.
Leadership is a two-way street, loyalty up and loyalty down. Respect for one’s superiors; care for one’s crew.
One accurate measurement is worth a thousand expert opinions.
Someday, on the corporate balance sheet, there will be an entry which reads, “Information”; For in most cases, the information is more valuable than the hardware which processes it.
We’re flooding people with information. We need to feed it through a processor. A human must turn information into intelligence or knowledge. We’ve tended to forget that no computer will ever ask a new question.
To me programming is more than an important practical art. It is also a gigantic undertaking in the foundations of knowledge.
They told me computers could only do arithmetic.
In pioneer days they used oxen for heavy pulling, and when one ox couldn’t budge a log, they didn’t try to grow a larger ox. We shouldn’t be trying for bigger computers, but for more systems of computers.
Life was simple before World War II. After that, we had systems.
We went overboard on management and forgot about leadership. It might help if we ran the MBAs out of Washington.
At any given moment, there is always a line representing what your boss will believe. If you step over it, you will not get your budget. Go as close to that line as you can.
I seem to do a lot of retiring.
I handed my passport to the immigration officer, and he looked at it and looked at me and said, “What are you?”
参考
维基网络:
http://en.wikipedia.org/wiki/Grace_Hopper
国立中央大学数学系:
http://li.math.ncu.e.tw/bcc16/pool/3.06.shtml
耶鲁大学计算机系:
http://cs-www.cs.yale.e/homes/tap/Files/hopper-story.html
计算机先驱:
http://202.207.0.245:9001/jisuanjifazhanshi/xianqu/18.htm
This entry was posted in网络3Cand taggedcompiler,debug,Grace Murray Hopper,传记,发明,编译器,起源. Bookmark thepermalink.Post a commentor leave a trackback:Trackback URL.
㈢ 最早的C语言编译器是什么做的
汇编。这真的是最早最早的。
准确的来说,这和编译器的开发有关,不用说太细,很麻烦怕你不懂。你现在假设第一个编译器是用会变写出来的,它的功能很简单,就是解释简单一种类似于C语言的高级语言,但是这种所谓的高级语言还没有完全拥有C语言的所有特性。只有比较简单核心功能,比如能把文本文件的高级语言转换成机器代码并且执行。
有了这个原型之后,就可以用这个编译器来解释简单C程序,就可以用C重写编写一个新的编译器,这样就有更多的C的功能。于是,从此之后就用现有的编译器解释更复杂的语言,用更复杂的语言写出更好的编译器,然后不断这样迭代。这确实是编译器的演变。
然后最后一个问题就是当一个新的CPU发明过后,怎么办,需要重写又从汇编开始写编译器吗?答案是不用。假设你有一个CPU A执行一些代码,你用汇编写了一个基础的C编译器,然后用C写出了更复杂的编译器,接受更复杂的C功能,然后不断循环演化。现在你有了CPU B,CPU B和CPU A执行两套完全不同的代码,那如何让CPU B的机器也可以变异C语言呢?因为现在A上面已经可以运行非常复杂的C语言程序了,所以你可以在A上面开发一个编译器把C语言程序转化为CPU B的执行代码。然后用这个程序,直接编译你的C语言编译器,再把这个程序转换到有B命令集的电脑上面,这样你就开发出了B电脑需要的C语言编译器。
所以除非你真的是活在非常早起的人类。否在现在的编译器基本上都利用这种原理直接编译已经用C语言或者其它高级语言写好的代码来产生新的编译器就行了。理论上可以只使用C语言来开发C的编译器,不过处于一些历史原因和底层效率等因素的考量,部分代码还是使用汇编来实现的。
我举得不过是一个例子,不一定是真实的C语言编译的进化,何况有这么多不同的C语言编译器,每一个的发展历史都有小的不同。但是基本上都是利用了这种编译器编译新的编译器的思想来实现了。而这样回溯回去,最早的编译器只能使用汇编来些。而其实最早的汇编语言的编译器就只能使用机器语言来写了。不过都是先处理简单的转换任务,有了这个核心功能过后,就可以写程序转换更复杂的语法。然后越来越复杂。就有了各种各样的高级语言编译器了。
㈣ 第一个编译器是靠什么编出来的
linux自带了gcc编译器,直接使用gcc
test.c命令编译生成a.out可执行文件,或者使用命令gcc
-
o
test
test.c编译生成test可执行文件,这样避免了覆盖前面的a.out,新手就先用自带的练手了,很方便的,我也是刚学的,共勉哈
㈤ 世界上第一个语言编译程序是用什么语言编写的
数字电子计算机,在1946年诞生,那时还没有编译程序,一台计算机就是一个程序,修改程序,就是直接修该内存的指令(电路).后来,出现了汇编程序(当然用机器语言写的),汇编语言就出现了,在后来就有了高级语言.至于第一个编译程序,严格来说汇编程序也是编译程序,所以是用机器语言写的.
㈥ 第一个C语言编译器是怎样编写的
任何一个功能
任何一个语言 都能实现
所以 关键的不在于语言 而在于 算法
C语言被人设计出来
设计了它的语法和规则
然后 根据这个规则,用B语言(Ken Thompson发明的B语言,而 B语言则源自BCPL语言。) 加汇编 编写了第一个C的编译器
没用多久
因为C语言更好用
于是 后续的C语言编译器 都是C语言自己写的了。
㈦ 第一个java编译器是那一年推出的
1995年5月
jdk 就是 一个编译器
只是要手动在dos下面去编译而已
所以 java 是1995年5月发布的
同时 也发布了jdk 所以 编译器就产生了
㈧ 世界上第一款编译器是如何打造的
想起示波器了,在还没有调试工具软件之前
㈨ 世界上第一个编译器是用什么编译器编译出来的
最初的语言 就是01代码
也就是机器语言
是不需要编译的
第一个编译器 就是这样一点点写出来的,是汇编到二进制的编译器
所以 第一个编译器本身不需要编译,直接运行即可。
㈩ 编译器的历史
20世纪50年代,IBM的John Backus带领一个研究小组对FORTRAN语言及其编译器进行开发。但由于当时人们对编译理论了解不多,开发工作变得既复杂又艰苦。与此同时,Noam Chomsky开始了他对自然语言结构的研究。他的发现最终使得编译器的结构异常简单,甚至还带有了一些自动化。Chomsky的研究导致了根据语言文法的难易程度以及识别它们所需要的算法来对语言分类。正如Chomsky架构(Chomsky Hierarchy),它包括了文法的四个层次:0型文法、1型文法、2型文法和3型文法,且其中的每一个都是其前者的特殊情况。2型文法(或上下文无关文法)被证明是程序设计语言中最有用的,而且今天它已代表着程序设计语言结构的标准方式。分析问题(parsing problem,用于上下文无关文法识别的有效算法)的研究是在60年代和70年代,它相当完善的解决了这个问题。它已是编译原理中的一个标准部分。
有限状态自动机(Finite Automation)和正则表达式(Regular Expression)同上下文无关文法紧密相关,它们与Chomsky的3型文法相对应。对它们的研究与Chomsky的研究几乎同时开始,并且引出了表示程序设计语言的单词的符号方式。
人们接着又深化了生成有效目标代码的方法,这就是最初的编译器,它们被一直使用至今。人们通常将其称为优化技术(Optimization Technique),但因其从未真正地得到过被优化了的目标代码而仅仅改进了它的有效性,因此实际上应称作代码改进技术(Code Improvement Technique)。
当分析问题变得好懂起来时,人们就在开发程序上花费了很大的功夫来研究这一部分的编译器自动构造。这些程序最初被称为编译器的编译器(Compiler-compiler),但更确切地应称为分析程序生成器(Parser Generator),这是因为它们仅仅能够自动处理编译的一部分。这些程序中最着名的是Yacc(Yet Another Compiler-compiler),它是由Steve Johnson在1975年为Unix系统编写的。类似的,有限状态自动机的研究也发展了一种称为扫描程序生成器(Scanner Generator)的工具,Lex(与Yacc同时,由Mike Lesk为Unix系统开发)是这其中的佼佼者。
在20世纪70年代后期和80年代早期,大量的项目都贯注于编译器其它部分的生成自动化,这其中就包括了代码生成。这些尝试并未取得多少成功,这大概是因为操作太复杂而人们又对其不甚了解。
编译器设计最近的发展包括:首先,编译器包括了更加复杂算法的应用程序它用于推断或简化程序中的信息;这又与更为复杂的程序设计语言的发展结合在一起。其中典型的有用于函数语言编译的Hindley-Milner类型检查的统一算法。其次,编译器已越来越成为基于窗口的交互开发环境(Interactive Development Environment,IDE)的一部分,它包括了编辑器、连接程序、调试程序以及项目管理程序。这样的IDE标准并没有多少,但是对标准的窗口环境进行开发已成为方向。另一方面,尽管在编译原理领域进行了大量的研究,但是基本的编译器设计原理在近20年中都没有多大的改变,它正迅速地成为计算机科学课程中的中心环节。
在20世纪90年代,作为GNU项目或其它开放源代码项目标一部分,许多免费编译器和编译器开发工具被开发出来。这些工具可用来编译所有的计算机程序语言。它们中的一些项目被认为是高质量的,而且对现代编译理论感兴趣的人可以很容易的得到它们的免费源代码。
大约在1999年,SGI公布了他们的一个工业化的并行化优化编译器Pro64的源代码,后被全世界多个编译器研究小组用来做研究平台,并命名为Open64。Open64的设计结构好,分析优化全面,是编译器高级研究的理想平台。
编译器相关专业术语: 1. compiler编译器;编译程序 2. on-line compiler 连线编译器 3. precompiler 预编译器 4. serial compiler 串行编译器 5. system-specific compiler 特殊系统编译器 6. Information Presentation Facility Compiler 信息展示设施编译器 7. Compiler Monitor System 编译器监视系统