您现在的位置是:首页 >

开发一个编译器 编译器详细资料大全

火烧 2022-11-05 19:13:53 1064
编译器详细资料大全 简单讲,编译器就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言)”的程式。一个现代编译器的主要工作流程:原始码 ource code → 预处理器 re ro

编译器详细资料大全  

简单讲,编译器就是将“一种语言(通常为高级语言)”翻译为“另一种语言(通常为低级语言)”的程式。一个现代编译器的主要工作流程:原始码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) → 目标代码 (object code) → 连结器 (Linker) → 可执行程式 (executables)

高级计算机语言便于人编写,阅读交流,维护。机器语言是计算机能直接解读、运行的。编译器将汇编或高级计算机语言源程式(Source program)作为输入,翻译成目标语言(Target language)机器代码的等价程式。原始码一般为高级语言 (High-level language), 如Pascal、C、C++、Java、汉语编程等或汇编语言,而目标则是机器语言的目标代码(Object code),有时也称作机器代码(Machine code)。

对于C#、VB等高级语言而言,此时编译器完成的功能是把源码(SourceCode)编译成通用中间语言(MSIL/CIL)的位元组码(ByteCode)。最后运行的时候通过通用语言运行库的转换,编程最终可以被CPU直接计算的机器码(NativeCode)。

开发一个编译器 编译器详细资料大全

基本介绍

中文名:编译器外文名:Compiler别称:解码器表达式:原始码→预处理器 → 编译器 → 目标代码提出者:葛丽丝·霍普提出时间:20世纪50年代末套用学科:计算机适用领域范围:计算机,单片机,程式语言 工作原理,种类,处理器,前端,后端,代码分析,工作方法,编译器最佳化,进行对比,历史,

工作原理

编译是从原始码(通常为高级语言)到能直接被计算机或虚拟机执行的目标代码(通常为低级语言或机器语言)的翻译过程。然而,也存在从低级语言到高级语言的编译器,这类编译器中用来从由高级语言生成的低级语言代码重新生成高级语言代码的又被叫做反编译器。也有从一种高级语言生成另一种高级语言的编译器,或者生成一种需要进一步处理的的中间代码的编译器(又叫级联)。编译器 典型的编译器输出是由包含入口点的名字和地址, 以及外部调用(到不在这个目标档案中的函式调用)的机器代码所组成的目标档案。一组目标档案,不必是同一编译器产生,但使用的编译器必需采用同样的输出格式,可以连结在一起并生成可以由用户直接执行的EXE, 所以我们电脑上的档案都是经过编译后的档案。

种类

编译器可以生成用来在与编译器本身所在的计算机和作业系统(平台)相同的环境下运行的目标代码,这种编译器又叫做“本地”编译器。另外,编译器也可以生成用来在其它平台上运行的目标代码,这种编译器又叫做交叉编译器。交叉编译器在生成新的硬体平台时非常有用。“源码到源码编译器”是指用一种高级语言作为输入,输出也是高级语言的编译器。例如: 自动并行化编译器经常采用一种高级语言作为输入,转换其中的代码,并用并行代码注释对它进行注释(如OpenMP)或者用语言构造进行注释(如FORTRAN的DOALL指令)。 编译器

处理器

作用是通过代入预定义等程式段将源程式补充完整。

前端

前端主要负责解析(parse)输入的原始码,由语法分析器和语意分析器协同工作。语法分析器负责把原始码中的‘单词’(Token)找出来,语意分析器把这些分散的单词按预先定义好的语法组装成有意义的表达式,语句 ,函式等等。 例如“a = b + c;”前端语法分析器看到的是“a, =, b , +, c;”,语意分析器按定义的语法,先把他们组装成表达式“b + c”,再组装成“a = b + c”的语句。 前端还负责语义(semantic checking)的检查,例如检测参与运算的变数是否是同一类型的,简单的错误处理。最终的结果常常是一个抽象的语法树(abstract syntax tree,或 AST),这样后端可以在此基础上进一步最佳化,处理。 title

后端

编译器后端主要负责分析,最佳化中间代码(Intermediate representation)以及生成机器代码(Code Generation)。 一般说来所有的编译器分析,最佳化,变型都可以分成两大类: 函式内(intraprocedural)还是函式之间(interprocedural)进行。很明显,函式间的分析,最佳化更准确,但需要更长的时间来完成。

代码分析

编译器分析(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-threadedcode)。 编译器 机器代码的生成是最佳化变型后的中间代码转换成机器指令的过程。现代编译器主要采用生成汇编代码(assembly code)的策略,而不直接生成二进制的目标代码(binary object code)。即使在代码生成阶段,高级编译器仍然要做很多分析,最佳化,变形的工作。例如如何分配暂存器(register allocatioin),如何选择合适的机器指令(instruction selection),如何合并几句代码成一句等等。

工作方法

首先编译器进行语法分析,也就是要把那些字元串分离出来。 然后进行语义分析,就是把各个由语法分析分析出的语法单元的意义搞清楚。 最后生成的是目标档案,也称为obj档案。 再经过连结器的连结就可以生成最后的EXE档案了。 有些时候需要把多个档案产生的目标档案进行连结,产生最后的代码。这一过程称为交叉连结。

编译器最佳化

应用程式之所以复杂, 是由于它们具有处理多种问题以及相关数据集的能力。实际上, 一个复杂的应用程式就象许多不同功能的应用程式“ 贴上” 在一起。源档案中大部分复杂性来自于处理初始化和问题设定代码。这些档案虽然通常占源档案的很大一部分, 具有很大难度, 但基本上不花费C PU 执行周期。 尽管存在上述情况, 大多数Makefile档案只有一套编译器选项来编译项目中所有的档案。因此, 标准的最佳化方法只是简单地提升最佳化选项的强度, 一般从O 2 到O 3。这样一来, 就需要投人大量 精力来调试, 以确定哪些档案不能被最佳化, 并为这些档案建立特殊的make规则。 一个更简单但更有效的方法是通过一个性能分析器, 来运行最初的代码, 为那些占用了85 一95 % CPU 的源档案生成一个列表。通常情况下, 这些档案大约只占所有档案的1%。如果开发人员立刻为每一个列表中的档案建立其各自的规则, 则会处于更灵活有效的位置。这样一来改变最佳化只会引起一小部分档案被重新编译。进而,由于时间不会浪费在最佳化不费时的函式上, 重编译全部档案将会大大地加快。

进行对比

许多人将高阶程式语言分为两类:编译型语言和直译型语言。然而,实际上,这些语言中的大多数既可用编译型实现也可用直译型实现,分类实际上反映的是那种语言常见的实现方式。(但是,某些直译型语言,很难用编译型实现。比如那些允许 线上代码更改 的直译型语言。)

历史

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),这是因为它们仅仅能够自动处理编译的一部分。这些程式中最著名的是Ya(Yet Another Compiler-compiler),它是由Steve Johnson在1975年为Unix系统编写的。类似的,有限状态自动机的研究也发展了一种称为扫描程式生成器(Scanner Generator)的工具,Lex(与Ya同时,由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 编译器监视系统  
永远跟党走
  • 如果你觉得本站很棒,可以通过扫码支付打赏哦!

    • 微信收款码
    • 支付宝收款码