学习编写编译器[关闭]


699

首选语言:C / C ++,Java和Ruby。

我正在寻找一些有用的书籍/教程,以了解如何仅出于教育目的编写自己的编译器。我最熟悉C / C ++,Java和Ruby,因此我更喜欢涉及这三种资源之一的资源,但是任何好的资源都是可以接受的。


ANTLR一路走来。下面提出的所有资源对我来说似乎都是过大的。ANTLR始终是编译器设计师的最佳朋友。A
A_Var 2010年

如果您的主要重点是学习编译思路的总体工作原理,则可以查看SICP并缩写为SICP(基于Scheme(列表)的计算机程序的结构化解释),但可以讲授一般原理。 mitpress.mit.edu/sicp。一位在公司工作的资深人士向我推荐了这本书,并做这些作品的汇编和解释是谋生的!
Nishant

一个无耻的插件:我对类似问题的回答
9000

我在我的博客上写了一篇有关创建编译器的文章:orangejuiceliberationfront.com/how-to-write-a-compiler实际上侧重于基础知识和入门。那里有更多与编译器/代码生成/解析器/语言设计相关的文章。
uliwitness 2014年

Answers:


1084

资源大清单:

传说:

  • ¶链接到PDF文件
  • $链接到印刷书籍

22
我读过Let's Build a Compiler[ Compilers.iecc.com/crenshaw/]系列文章,它确实是不错的文章,也是一个不错的起点。
TheVillageIdiot

5
我认为值得一提的是Coursera的编译器课程。它具有不错的视频,并逐步介绍了创建类似语言的Java /简单编译器的过程。Coursera编译器链接
QuantumKarl

1
我想使这个答案尽可能保持原始,因此我决定在此处发布此参考:tutorialspoint.com/compiler_design/index.htm我对这个网站的喜欢之处在于它不参与实际编写任何代码创建一个编译器,但是它确实将编译器分为以下几个部分:阶段和阶段。它确实描述了逻辑和算法设计方法,没有任何特定的语言范式,因为它表示任意语言和字母的表示法。它是一本快速阅读的书,但为您提供了每个零件需要的概念。
弗朗西斯·库格勒

70

我认为这是一个非常模糊的问题。只是因为涉及的话题很深。但是,编译器可以分解为两个独立的部分。上半部分和下半部分。上半部通常采用源语言并将其转换为中间表示,下半部负责平台特定的代码生成。

尽管如此,一种用于实现该主题的简便方法的想法(至少在我们的编译器类中使用了该想法)是在上述两部分中构建编译器。具体来说,仅通过构建上半部分就可以对整个过程有所了解。

仅做上半部分就可以使您获得编写词法分析器和解析器的经验,并生成一些“代码”(我提到的中间表示形式)。因此,它将采用您的源程序并将其转换为另一种表示形式,并进行一些优化(如果需要),这是编译器的核心。然后,下半部分将采用该中间表示形式,并生成在特定体系结构上运行程序所需的字节。例如,下半部分将采用您的中间表示形式并生成PE可执行文件。

关于该主题的一些书对我特别有用,是《编译器原理和技巧》(或《龙书》,这是由于封面上有可爱的龙)。它有一些很棒的理论,并且确实以一种真正可访问的方式涵盖了上下文无关文法。同样,为了构建词法分析器和解析器,您可能会使用* nix工具lex和yacc。不足为奇的是,这本名为《lex and yacc》的书在这本《龙书》停下来的地方找到了。


55

我认为ML中的现代编译器实现是编写文本的最佳入门编译器。也有Java版本C版本,鉴于您的语言背景,这两种版本可能更易于访问。本书包含许多有用的基本资料(扫描和解析,语义分析,激活记录,指令选择,RISC和x86本机代码生成)和各种“高级”主题(编译OO和功能语言,多态性,垃圾回收,优化和静态分配表格)放入相对较小的空间(约500页)。

我更喜欢《现代编译器实现》而不是《 Dragon》一书,因为《现代编译器》实现只研究了很少的领域,相反,它确实涵盖了编写严肃,体面的编译器所需的所有主题。阅读完本书后,如果需要,您将可以直接处理研究论文,以进行更深入的了解。

我必须承认,我对Niklaus Wirth的Compiler Construction情有独钟它以PDF格式在线提供。我发现Wirth的编程美学简直很美,但是有些人觉得他的风格太小了(例如Wirth偏爱递归下降解析器,但是大多数CS课程都侧重于解析器生成器工具; Wirth的语言设计相当保守。)编译器构造是非常简洁的提炼关于Wirth的基本思想,因此无论您是否喜欢他的风格,我都强烈建议您阅读本书。



我强烈建议不要使用C版本的“现代编译器实现”,由于C的原因,它会因底层细节而瘫痪。这会使本书完全混乱。Java 1st不太好,因为其OO设计很差,Java 2nd ed不再与Tiger语言有关。因此,我强烈推荐ML之一:不必精通ML就能理解它。ML绝对适合该工作。
akim '16

44

我同意《龙书》的参考;IMO,它是编译器构造的权威指南。不过,请为一些核心理论做好准备。

如果您想要一本理论上较浅的书,那么Game Scripting Mastery可能是一本更好的书。如果您是编译器理论的新手,那么它会为您提供较温和的介绍。它没有涵盖更实用的解析方法(在不讨论LL或LR解析的情况下选择非预测性递归下降),并且正如我记得的那样,它甚至没有讨论任何优化理论。另外,它可以编译为字节码,而不是编译为机器码,而该字节码应该在还要编写的VM上运行。

它仍然是不错的读物,特别是如果您可以在Amazon上以便宜的价格买到它。如果只希望对编译器进行简单介绍,那么掌握Game Scripting并不是一个坏方法。如果您想成为硬派,那么您应该比《龙书》更满意。


1
游戏脚本精通是一种很好的学习资源,因为完成后您将拥有一个可玩的,可编写脚本的2D冒险游戏。这使每项练习都专注于特定目的,并使读者保持动力。
高高的拱门

1
Dragon过于注重基于语法的解析。如果您不打算解析诸如C ++之类的绝对不可能的东西,或者使用解析器生成器,但是可以使用例如手工制作的LL语法,那么您可能希望寻找一些可以处理更高百分比的编译器字段的东西,而不是语法转换和证明
Marco van de Voort

27

“让我们构建一个编译器”很棒,但是有点过时了。(我并不是说这会使它的有效性降低一点。)

或查看SLANG。这类似于“让我们构建一个编译器”,但是对于初学者而言,它是更好的资源。随附pdf教程,该教程采用7步方法来教您编译器。添加quora链接,因为它具有到C ++,Java和JS中SLANG的所有各个端口的链接,还具有最初使用C#和.NET平台编写的python和Java解释器。


5
我同意这个系列虽然仍然有用,但有点过时了。但是,我最大的抱怨是它试图直接输出为汇编语言,而不是构建任何类型的解析树,这意味着(与第一篇文章相反),它对于编写不是很有用口译员。
a_m0d

23

如果您要使用功能强大的高级工具而不是自己构建所有内容,那么遍历项目和本课程的阅读材料是一个不错的选择。这是Java解析器引擎ANTLR的作者编写的语言课程。您可以从Pragmatic Programmers获得该课程的PDF书籍。

该课程介绍了您在其他地方看到的标准编译器编译器内容:解析,类型和类型检查,多态性,符号表和代码生成。几乎没有的唯一内容是优化。最终项目是一个编译C子集的程序。因为您使用的是ANTLR和LLVM之类的工具,所以在一天之内就可以编写整个编译器是可行的(尽管我确实有大约24小时的时间,但我已经证明了这一点。使用现代工具进行实际工程的工作量很大,理论上也较轻。

顺便说一句,LLVM简直太棒了。在许多情况下,您通常可以编译成汇编,因此最好改为编译为LLVM的中间表示。它是更高级别的,跨平台的,并且LLVM非常擅长从中生成优化的装配。


第一个链接已死。
林恩

20

如果您没有时间,我会推荐Niklaus Wirth的“编译器构造”(Addison-Wesley。1996),这是一本可以在一天内阅读的小小册子,但是它解释了基础知识(包括如何实现词法分析器,递归下降解析器,和您自己的基于堆栈的虚拟机)。此后,如果您想深入研究,就没有其他评论者建议的围绕《龙》的书。


如果您没有太多时间,请不要编写编译器。
Ingo 2012年

17

您可能想要研究Lex / Yacc(或Flex / Bison,无论您想称呼它们如何)。Flex是一个词法分析器,它将分析和识别您语言的语义成分(“令牌”),而Bison将用于定义解析每个令牌时发生的情况。对于可以编译为C的编译器或动态运行指令,这可能是但绝对不限于打印C代码。

该常见问题解答应为您提供帮助,本教程看起来非常有用。


17

一般而言,对于编译器而言,没有五分钟的教程,因为这是一个复杂的主题,编写编译器可能需要几个月的时间。您将必须进行自己的搜索。

通常会解释Python和Ruby。也许您也想从翻译开始。通常比较容易。

第一步是编写正式的语言描述,即您的编程语言的语法。然后,您必须根据语法将要编译或解释的源代码转换为抽象语法树,这是计算机可以理解并可以对其进行操作的源代码的内部形式。此步骤通常称为解析,而解析源代码的软件称为解析器。解析器通常由解析器生成器生成,解析器生成器将形式语法转换为源代码或其他机器代码。有关解析的一个很好的非数学解释,我建议您使用“解析技术-实用指南”。Wikipedia对解析器生成器进行了比较,您可以从中选择最适合自己的解析器。根据您选择的解析器生成器,

为您的语言编写解析器可能非常困难,但这取决于您的语法。因此,我建议您保持语法简单(与C ++不同);LISP就是一个很好的例子。

在第二步中,将抽象语法树从树结构转换为线性中间表示。经常引用Lua的字节码作为一个很好的例子。但是中间表示确实取决于您的语言。

如果要构建解释器,则只需解释中间表示。您也可以及时编译它。我建议使用LLVM和libjit进行即时编译。为了使该语言可用,您还必须包括一些输入和输出功能以及一个小的标准库。

如果要编译语言,它将更加复杂。您将不得不为不同的计算机体系结构编写后端,并从这些后端的中间表示形式生成机器代码。我建议为此任务使用LLVM。

关于此主题的书籍很少,但我不推荐它们作为一般用途。他们大多数都太学术或太实用。没有“在21天之内教您自己编写编译器”的知识,因此,您必须购买几本书才能对整个主题有很好的理解。如果您搜索Internet,则会发现一些在线书籍和讲义。也许您附近有一个大学图书馆,您可以在其中借用有关编译器的书籍。

如果您要使您的项目认真,我还建议您具有理论计算机科学和图论方面的良好背景知识。计算机科学学位也将有所帮助。


++没错,了解所有这些知识是件好事,这可能是一项艰巨的工作,但我还从一些专家那里学到了如何不做大事。知道事物是件好事,而在大多数情况下,最好是何时不使用它们。
Mike Dunlavey


11

一本尚未提出但很重要的书是John Levine的“链接器和加载器”。如果不使用外部汇编器,则需要一种输出可以链接到最终程序中的目标文件的方法。即使您使用的是外部汇编程序,您也可能需要了解重定位以及整个程序加载过程如何工作以制作可用的工具。本书收集了有关此过程的大量随机知识,涉及各种系统,包括Win32和Linux。


10

Dragon Book绝对是“构建编译器”书,但是如果您的语言不像当前的一代语言那么复杂,那么您可能需要查看Design Patterns的Interpreter 模式

本书中的示例设计了一种类似于正则表达式的语言,并且经过了深思熟虑,但是正如他们在书中所说的那样,这对于思考过程是有好处的,但实际上仅对小语言有效。但是,使用这种模式为小语言编写解释器要比必须学习所有不同类型的解析器(yacc和lex等)要快得多。


10

如果您愿意使用LLVM,请查看以下网址:http : //llvm.org/docs/tutorial/。它教您如何使用LLVM的框架从头开始编写编译器,并且不假定您具有有关该主题的任何知识。

本教程建议您编写自己的解析器和词法分析器等,但是我建议您一旦了解了这一点,便要研究bison和flex。它们使生活变得更加轻松。


但是设置Visual Studio的文档写得不好,没有任何示例
SpicyWeenie 2014年

10

我发现《龙》一书太难读了,过多地关注语言理论,而在实践中实际上并不需要编写语言。

我要添加一本Oberon书,其中包含了一个惊人的快速和简单的Oberon编译器Project Oberon的完整资料

替代文字


10

我记得大约七年前,我刚接触编程时曾问过这个问题。

当我问的时候,我非常小心,令人惊讶的是,我受到的批评没有您来这里的那么多。但是,他们的确向我指出了“ 龙书 ” 的方向,这是一本非常出色的书,它解释了编写编译器所需的一切(当然,您必须精通一两种语言。)语言,更好的语言。)

是的,很多人都说读那本书是疯狂的,您不会从中学到任何东西,但是我完全不同意。

许多人还说编写编译器是愚蠢且毫无意义的。好吧,编译器开发有用的原因有很多:

  • 因为很有趣。
  • 这是有教育意义的,在学习如何编写编译器时,您将学到很多有关计算机科学和其他技术的知识,这些技术在编写其他应用程序时很有用。
  • 如果没有人编写编译器,那么现有的语言将再好不过。

我没有立即编写自己的编译器,但是在询问之后我知道从哪里开始。而现在,在学习了许多不同的语言并阅读了《龙书》之后,写作并不是什么大问题。(我也在学习计算机工程atm,但是我对编程的大部分了解都是自学的。)

总之,《龙书》是一个很棒的“教程”。但是在尝试编写编译器之前,请花一些时间精通一两种语言。不过,不要期望在未来十年左右的时间里成为编译器专家。

如果您想学习如何编写解析器/解释器,这本书也很好。


9

“ ...让我们构建一个编译器...”

我第二次通过@sasb http://compilers.iecc.com/crenshaw/。暂时不要购买更多书籍。

为什么?工具和语言。

所需的语言是Pascal,如果我没记错的话,则基于Turbo-Pascal。如果您访问http://www.freepascal.org/并下载Pascal编译器,则会发生所有示例直接从页面运行的情况,即http://www.freepascal.org/download.var。 Pascal是几乎可以使用的任何处理器或操作系统,都可以使用它。

一旦你掌握了教训然后尝试更先进的龙书http://en.wikipedia.org/wiki/Dragon_book


9

我正在研究相同的概念,并且发现了Joel Pobar的这篇很有前途的文章,

为.NET Framework创建语言编译器-不确定它的去向

为.NET Framework创建语言编译器-原始文档的pdf副本

他讨论了编译器的高级概念,并着手为.Net框架发明自己的语言。尽管它的目标是.Net框架,但许多概念都应该能够复制。该文章涵盖:

  1. 语言定义
  2. 扫描器
  3. 解析器(主要是我感兴趣的位)
  4. 面向.Net框架
  5. 代码生成器

还有其他主题,但是您公正。

它的目标读者是用C#编写的(不是Java)

高温超导

骨头


“不是Java”是什么意思?
Hejazzman

哈哈,对不起,我的意思是它是为.Net编写的,其原理与Java类似。两者都是JIT风格。:)
dbones

8

创建编译器的一种简单方法是使用bison和flex(或类似方法),构建树(AST)并在C语言中生成代码。生成C代码是最重要的步骤。通过生成C代码,您的语言将自动在具有C编译器的所有平台上运行。

生成C代码与生成HTML一样容易(只需使用打印或等效的HTML),比编写C解析器或HTML解析器容易得多。


8

来自comp.compilers常见问题解答

Per Brinch Hansen Prentice-Hall 1982年的“对个人计算机进行编程” ISBN 0-13-730283-5

这本不幸的书标题解释了如何使用类似于Pascal的语言称为Edison的微机单用户编程环境的设计和创建。作者提供了Edison编译器和简单的支持操作系统的逐步实现的所有源代码和说明,所有这些均由Edison本身编写(除了用PDP 11/23的符号汇编程序编写的小型支持内核;还可以为IBM PC订购完整的源代码)。

本书最有趣的事情是:1)能够演示如何创建完整,自包含,自维护,有用的编译器和操作系统的能力,以及2)关于语言设计和规范问题以及交易的有趣讨论。第二章。

Per Brinch Hansen Prentice-Hall 1985年的“ Pascal编译器上的Brinch Hansen” ISBN 0-13-083098-4

另一本理论上的轻量级实用文章是这本书的编码方法。作者介绍了Pascal-(Pascal“减”)的编译器和p代码解释器的设计,实现和完整源代码,Pascal是布尔型和整数类型(但没有字符,实数,子范围或枚举类型)的Pascal子集。 ,常量和变量定义以及数组和记录类型(但不包括打包,变体,集合,指针,无名,重命名或文件类型),表达式,赋值语句,带有值和变量参数的嵌套过程定义,if语句,while语句,和开始到结束块(但没有函数定义,过程参数,goto语句和标签,case语句,repeat语句,for语句和with语句)。

编译器和解释器使用Pascal *(Pascal“星号”)编写,Pascal子集具有一些Edison样式的功能扩展,用于创建软件开发系统。作者出售了用于IBM PC的Pascal *编译器,但是很容易将本书的Pascal-编译器移植到任何方便的Pascal平台上。

本书使编译器的设计和实现看起来容易。我特别喜欢作者关注质量,可靠性和测试的方式。编译器和解释器可以很容易地用作更复杂的语言或编译器项目的基础,尤其是当您被迫快速启动并运行某些东西时。


8

您应该在6页以上的代码中签出Darius Bacon的“ ichbins ”,它是针对Lisp的小型方言(针对C)的编译器。与大多数玩具编译器相比,它的优点是语言足够完整,可以用它编写编译器。(压缩包还包括一个引导程序来引导事物。)

关于在我的Ur-Scheme网页上学习编写编译器的有用知识,还有很多东西。


8
  1. 这是一个广阔的主题。不要小看这一点。并且不要低估我的观点,不要低估它。
  2. 我听说《龙书》是一个(“?”)学习的起点。:)善于搜索,最终将成为您的生活。
  3. 构建自己的编程语言绝对是一个好练习!但是要知道,最终它永远不会用于任何实际目的。例外情况很少,而且相差远。

4
如果您还没有读过《龙书》。请不要推荐它。实际上,您是否曾经实现过编译器?

是的,顾名思义,《龙书》是一个怪物。非常深入,但是仍然是很好的资源。我不建议初学者使用它
扎卡里·默里

2
@Neil:您还没有用Google搜索,对吗?大声笑。blog.280z28.org但是,我还没有读过那本书。
山姆·哈威尔2009年

我目前正在阅读(龙书),同时也在阅读Lex / Yacc,我发现这本书相当不错。亲自。
Simeon朝圣者

1
公平地说,我以“我听到...”开头。:)#1和#3是我觉得进门非常重要的要点,但很少被提及。
山姆·哈威尔2009年

8

Fraser和Hanson 的LCC编译器(wikipedia)(项目主页)(github.com/drh/lcc)在他们的书“ A Retargetable C Compiler:设计和实现”中进行了描述。它非常易读,可以解释整个编译器,直至代码生成。


这似乎是一个非常好的资源,谢谢。
gideon'8

7

Python捆绑了用Python编写的python编译器。您可以看到源代码,它包括解析,抽象语法树,发出代码等所有阶段。


7

抱歉,它是西班牙文,但这是阿根廷一门名为“ Compiladores eIntérpretes”(编译器和口译员)的课程的目录。

该课程从形式语言理论到编译器构建,这些都是您至少需要构建简单编译器的主题:

  • C.
    Allen I. Holub

    Prentice-Hall的编译器设计。1990年。

  • 编译器。TeoríayConstrucción。
    SanchísLlorca,FJ,GalánPascual,C。社论Paraninfo。1988年。

  • 编译器构造。
    尼克劳斯·沃思·

    艾迪生·韦斯利。1996年。

  • Lenguajes,Gramáticas和Autómatas。Un enfoquepráctico。
    Pedro IsasiViñuela,帕洛玛·马丁内斯·费尔南德斯,丹尼尔·博拉霍·米兰。Addison-Wesley Iberoamericana(西班牙)。1997年。

  • 编译器设计的艺术。理论与实践。
    托马斯·皮特曼,詹姆斯·彼得斯。

    普伦蒂斯厅。1992年。

  • 面向对象的编译器构造。
    吉姆·福尔摩斯。
    1995年,新泽西州恩格尔伍德悬崖,普伦蒂斯·霍尔(Prentice Hall)

  • 编译器。Conceptos基础。
    B. Teufel,S。Schmidt,T。Teufel。

    艾迪生-韦斯利Iberoamericana。1995年。

  • 自动机理论,语言和计算简介。

    约翰·霍普克罗夫特。Jeffref D. Ullman。
    艾迪生-韦斯利。1979年。

  • 正式语言简介。
    GyörgyE.Révész。

    Mc Graw Hill。1983年。

  • 解析技术。实用指南。
    迪克·格鲁尼(Dick Grune),塞里尔·雅各布(Ceriel Jacobs)。
    自动播放。1995
    http://www.cs.vu.nl/~dick/PTAPG.html

  • Yacc:另一个编译器。
    Stephen C. Johnson
    计算科学技术报告,1975年第32期。贝尔实验室。
    新泽西州默里山。

  • Lex:词法分析器生成器。
    我莱斯克,E。施密特。1975年第39号计算机科学技术报告。贝尔实验室。新泽西州默里山。

  • lex&yacc。
    约翰·莱文,托尼·梅森,道格·布朗。
    O'Reilly&Associates。1995年。

  • 计算理论的要素。
    哈里·刘易斯(Harry R. Lewis),克里斯托斯(Christos H.)SegundaEdición。学徒大厅。1998。

  • 控制权的基本构成法》。
    萨尔瓦多·卡瓦迪尼(Salvador V.Cavadini)。
    Trabajo Final de Grado para obtener elTítulode Ingeniero enComputación。
    Facultad deMatemáticaAplicada。UCSE 2001。


6

如果您想了解更多有关编译器(和元编译器)的信息,则不是一本书,而是一本技术论文和一个非常有趣的学习经验...该网站指导您构建一个完全独立的编译器系统,该系统可以编译自身和其他语言:

教程:元编译器第1部分

这全部基于一篇令人惊叹的10页技术论文:

Val Schorre META II:一种面向语法的编译器编写语言

从1964年诚实起见。我从1970年开始学习如何构建编译器。当您终于想知道编译器如何重新生成自身时,会有一个令人叹为观止的时刻。

我从大学时代就认识该网站的作者,但与该网站无关。


就像其他人所说的那样,我认为寿司是单身汉的最后一项工作,它需要知道很多数学,计算机科学等概念。
ingconti 2014年

如果您不了解这些主题,则不应该真正尝试构建一个认真的编译器。但是,如果您有2-3年的计算机科学本科教育(编程,数据结构,汇编语言),则MetaII论文将为您工作。
Ira Baxter 2014年

5

我也喜欢Crenshaw教程,因为它非常清楚地表明,编译器只是另一个程序,它读取一些输入并写入一些输出。

阅读。

如果需要的话,请尝试使用它,然后再看看另一篇有关如何真正编写更大,更完整的编译器的参考。

并阅读On Trusting Trust,以获取有关可以在此域中完成的显而易见的事情的线索。


5

如果您有兴趣为功能语言(而不是程序语言)编写编译器,Simon Peyton-Jones和David Lester的“ 实现功能语言:教程 ”是一个很好的指南。

功能评估工作原理的概念基础由简单但功能强大的功能语言(称为“核心”)中的示例提供指导。此外,还使用Miranda(一种与Haskell非常相似的纯功能语言)中的代码示例解释了Core语言编译器的每个部分。

描述了几种不同类型的编译器,但是即使您仅遵循所谓的Core模板编译器,您也将对使函数式编程产生影响的内容有很好的了解。


5

您可以使用Apache Software Foundation的BCEL。使用此工具可以生成类似汇编程序的代码,但是它是带有BCEL API的Java。您可以学习如何生成中间语言代码(在这种情况下为字节码)。

简单的例子

  1. 使用此函数创建一个Java类:

    public String maxAsString(int a, int b) {
        if (a > b) {
            return Integer.valueOf(a).toString();
        } else if (a < b) {
            return Integer.valueOf(b).toString();
        } else {
            return "equals";
        }
    }
    

现在使用此类运行BCELifier

BCELifier bcelifier = new BCELifier("MyClass", System.out);
bcelifier.start();

您可以在控制台上看到整个类的结果(如何构建字节码MyClass.java)。该函数的代码是这样的:

private void createMethod_1() {
  InstructionList il = new InstructionList();
  MethodGen method = new MethodGen(ACC_PUBLIC, Type.STRING, new Type[] { Type.INT, Type.INT }, new String[] { "arg0", "arg1" }, "maxAsString", "MyClass", il, _cp);

  il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load first parameter to address 1
  il.append(InstructionFactory.createLoad(Type.INT, 2)); // Load second parameter to adress 2
    BranchInstruction if_icmple_2 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPLE, null); // Do if condition (compare a > b)
  il.append(if_icmple_2);
  il.append(InstructionFactory.createLoad(Type.INT, 1)); // Load value from address 1 into the stack
  il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
  il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  InstructionHandle ih_13 = il.append(InstructionFactory.createLoad(Type.INT, 1));
  il.append(InstructionFactory.createLoad(Type.INT, 2));
    BranchInstruction if_icmpge_15 = InstructionFactory.createBranchInstruction(Constants.IF_ICMPGE, null); // Do if condition (compare a < b)
  il.append(if_icmpge_15);
  il.append(InstructionFactory.createLoad(Type.INT, 2));
  il.append(_factory.createInvoke("java.lang.Integer", "valueOf", new ObjectType("java.lang.Integer"), new Type[] { Type.INT }, Constants.INVOKESTATIC));
  il.append(_factory.createInvoke("java.lang.Integer", "toString", Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  InstructionHandle ih_26 = il.append(new PUSH(_cp, "equals")); // Return "equals" string
  il.append(InstructionFactory.createReturn(Type.OBJECT));
  if_icmple_2.setTarget(ih_13);
  if_icmpge_15.setTarget(ih_26);
  method.setMaxStack();
  method.setMaxLocals();
  _cg.addMethod(method.getMethod());
  il.dispose();
}

5

这里有很多很好的答案,所以我想我将再添加一个到列表中:

十多年前,我有一本书叫做Project Oberon,该书的编译器文字非常好。本书的真正意义在于其源代码和说明非常动手且易于阅读。全文(2005年版)已提供pdf版本,因此您可以立即下载。第12章讨论了编译器:

http://www.ethoberon.ethz.ch/WirthPubl/ProjectOberon.pdf

尼古拉斯·沃斯(Jirg Gutknecht)

(这种处理方法没有他关于编译器的书那样广泛)

我已经读过几本有关编译器的书,并且我可以第二本龙书,花在这本书上的时间非常值得。


4

到目前为止,这本书未包含在清单中:

编译器设计基础(Torben Mogensen) (来自哥本哈根大学计算机科学系)

我也对学习编译器感兴趣,并计划在未来几年内进入该行业。就我所知,这本书是开始学习编译器的理想理论书籍。它是免费复制和复制,整洁且精心编写的,并以纯正的英语形式(不含任何代码)提供给您,但仍通过说明和图表等方式展示其原理。值得一看。


谢谢您将其添加到列表中:)
Anton
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.