学习编写一个编译器

时间:2008-08-04 22:46:37

标签: compiler-construction language-agnostic

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

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

40 个答案:

答案 0 :(得分:1053)

资源大单:

传奇:

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

答案 1 :(得分:69)

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

尽管如此,一个简单的方法来解决这个问题(我们在编译器类中使用的那个,至少)的一个想法是在上面描述的两个部分中构建编译器。具体来说,只需构建上半部分就可以了解整个过程。

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

我发现有一些关于这个主题的书籍特别有用Compilers Principles and Techniques(或龙书,因为封面上有可爱的龙)。它有一些很棒的理论,绝对能够以一种非常容易理解的方式涵盖无上下文语法。此外,为了构建词法分析器和解析器,您可能会使用* nix工具lex和yacc。而且无关紧要的是,这本名为“lex and yacc”的书在“龙书”为此留下的地方捡到了。

答案 2 :(得分:55)

我认为Modern Compiler Implementation in ML是编写文本的最佳介绍性编译器。还有一个Java version和一个C version,根据您的语言背景,其中任何一个都可能更容易访问。本书包含了许多有用的基本材料(扫描和解析,语义分析,激活记录,指令选择,RISC和x86本机代码生成)和各种“高级”主题(编译OO和函数语言,多态,垃圾收集,优化和单个静态分配形式)到相对较小的空间(约500页)。

我更喜欢现代编译器实现到龙书,因为现代编译器实现调查较少的领域 - 相反,它确实覆盖了编写一个认真,体面的编译器所需的所有主题。在您完成本书之后,如果您需要,您将准备好直接处理研究论文。

我必须承认,我对Niklaus Wirth Compiler Construction.感到非常情有独钟,available online是PDF格式。我发现Wirth的编程美学很简单,但有些人发现他的风格太小(例如Wirth喜欢递归下降解析器,但大多数CS课程专注于解析器生成器工具; Wirth的语言设计相当保守。)编译器构造是一个非常简洁的蒸馏Wirth的基本想法,所以无论你喜欢他的风格与否,我强烈建议你阅读这本书。

答案 3 :(得分:45)

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

如果你想要一本理论上较轻的书,Game Scripting Mastery对你来说可能是一本更好的书。如果你是编译器理论的全新手,它提供了一个更温和的介绍。它没有涵盖更实用的解析方法(选择非预测递归下降而不讨论LL或LR解析),并且我记得,它甚至没有讨论任何类型的优化理论。另外,它不是编译成机器代码,而是编译成一个字节码,该字节码应该在你也写的VM上运行。

这仍然是一个不错的阅读,特别是如果你可以在亚马逊上以便宜的价格买到它。如果您只想轻松介绍编译器,Game Scripting Mastery并不是一个糟糕的方法。如果你想要预先硬核,那么你应该满足于龙书。

答案 4 :(得分:27)

"Let's Build a Compiler"太棒了,但它有点过时了。 (我不是说它使它有点不那么有效。)

或查看SLANG。这类似于“让我们构建一个编译器”,但它是一个更好的资源,特别是对于初学者。这附带一个pdf教程,它教你编译器采用7步法。添加quora链接,因为它具有指向SLANG的所有各种端口的链接,包括C ++,Java和JS,以及python和java中的解释器,最初使用C#和.NET平台编写。

答案 5 :(得分:23)

如果您希望使用功能强大的高级工具,而不是自己构建所有,那么查看this course的项目和读数是一个不错的选择。它是Java解析器引擎ANTLR的作者的语言课程。您可以从the Pragmatic Programmers以PDF格式获取该课程的书籍。

本课程介绍了您在其他地方看到的标准编译器编译器:解析,类型和类型检查,多态,符号表和代码生成。几乎没有涉及的唯一事情就是优化。最终项目是compiles a subset of C的计划。因为你使用像ANTLR和LLVM这样的工具,所以在一天之内编写整个编译器是可行的(我有一个存在的证明,虽然我的意思是~24小时)。它在使用现代工具的实际工程上很重,理论上要轻一点。

顺便说一句,LLVM简直太棒了。在许多情况下,您通常可以编译成汇编程序,而编译到LLVM's Intermediate Representation会更好。它是更高级别的跨平台,LLVM非常擅长从中生成优化的程序集。

答案 6 :(得分:20)

如果你没有时间,我推荐Niklaus Wirth's "Compiler Construction" (Addison-Wesley. 1996),这是一本你可以在一天内阅读的小小册子,但它解释了基础知识(包括如何实现词法分析器,递归下降解析器和你自己的堆栈 - 基于虚拟机)。在那之后,如果你想要深度潜水,就像其他评论者所说的那样无法绕过龙书。

答案 7 :(得分:17)

您可能想要查看Lex / Yacc(或Flex / Bison,无论您想要什么称呼它们)。 Flex是一个词法分析器,它将解析和识别您语言的语义组件(“标记”),Bison将用于定义解析每个标记时会发生什么。这可能是,但绝对不限于打印C代码,编译为C的编译器,或动态运行指令。

This FAQ可以为您提供帮助,而this tutorial看起来非常有用。

答案 8 :(得分:16)

一般来说,编译器没有五分钟的教程,因为这是一个复杂的主题,编写编译器可能需要几个月的时间。你必须自己搜索。

通常会解释Python和Ruby。也许你想从口译员开始。这通常更容易。

第一步是编写正式的语言描述,即编程语言的语法。然后,您必须根据语法将要编译或解释的源代码转换为抽象语法树,这是计算机理解并可以操作的源代码的内部形式。此步骤通常称为解析,解析源代码的软件称为解析器。解析器通常由解析器生成器生成,该生成器将形式语法转换为源或机器代码。对于解析的一个好的,非数学的解释我推荐解析技术 - 实用指南。维基百科对解析器生成器进行了比较,您可以从中选择适合您的解析器生成器。根据您选择的解析器生成器,您将在Internet上找到教程,对于非常流行的解析器生成器(如GNU bison),还有书籍。

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

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

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

如果您要编译语言,那将会更复杂。您必须为不同的计算机体系结构编写后端,并从这些后端的中间表示中生成机器代码。我建议LLVM执行此任务。

关于这个主题有几本书,但我不建议将它们都用于一般用途。他们中的大多数都太学术或太实际。没有“在21天内自学编写编写器”,因此,您必须购买几本书才能更好地理解整个主题。如果您在互联网上搜索,您会看到一些在线书籍和讲义。也许你附近有一所大学图书馆,你可以借阅编辑器的书籍。

如果你打算让你的项目变得严肃,我还建议你在理论计算机科学和图论中有很好的背景知识。计算机科学学位也会有所帮助。

答案 9 :(得分:14)

答案 10 :(得分:11)

John Levine撰写的一本尚未提出但非常重要的书是"Linkers and Loaders"。如果您没有使用外部汇编程序,则需要一种方法来输出可以链接到最终程序的目标文件。即使您使用的是外部汇编程序,您也可能需要了解重定位以及整个程序加载过程如何工作以构建工作工具。本书收集了许多围绕此过程的随机知识,适用于各种系统,包括Win32和Linux。

答案 11 :(得分:10)

如果您愿意使用LLVM,请查看:http://llvm.org/docs/tutorial/。它教您如何使用LLVM的框架从头开始编写编译器,并且不假设您对该主题有任何了解。

教程建议你编写自己的解析器和词法分析器等,但我建议你在得到想法后研究野牛和flex。它们让生活变得更加轻松。

答案 12 :(得分:10)

我记得大约七年前这个问题,当时我还不熟悉编程。

当我问起时我非常小心,令人惊讶的是,我没有像你到这里那样得到批评。然而,他们确实指出了我在“Dragon Book”的方向,这是一本非常好的书,它解释了编写编译器时你需要知道的一切(你当然必须掌握一两种语言)你知道的语言越多越好。)。

是的,许多人说读这本书很疯狂,你不会从中学到任何东西,但我完全不同意这一点。

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

  • 因为它很有趣。
  • 这是教育性的,在学习如何编写编译器时,您将学到很多关于计算机科学和其他在编写其他应用程序时有用的技术。
  • 如果没有人编写编译器,现有语言就不会更好。

我没有马上编写自己的编译器,但在询问后我知道从哪里开始。现在,在学习了许多不同的语言并阅读龙书之后,写作并不是一个问题。 (我也在学习计算机工程,但我对编程知识的大部分都是自学成才。)

总之,龙书是一个很棒的“教程”。但是在尝试编写编译器之前花一些时间掌握一两种语言。不要指望在未来十年左右成为一名编译大师。

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

答案 13 :(得分:10)

我发现Dragon书太难以阅读而过于关注语言理论,这在实践中编写编译器并不是真正需要的。

我会添加Oberon一本书,其中包含一个非常快速和简单的Oberon编译器的完整来源Project Oberon

Alt text

答案 14 :(得分:10)

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

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

答案 15 :(得分:9)

  

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

我在http://compilers.iecc.com/crenshaw/之后第二次@sasb。暂时忘记购买更多书籍。

为什么呢?工具&语言。

所需的语言是Pascal,如果我没记错的话是基于Turbo-Pascal。如果你去http://www.freepascal.org/并下载Pascal编译器就会发生这样的事情。所有的例子直接从页面开始工作〜http://www.freepascal.org/download.var关于Free Pascal的好东西是几乎可以使用任何处理器或操作系统关心。

掌握了课程后,请尝试更高级的Dragon Bookhttp://en.wikipedia.org/wiki/Dragon_book

答案 16 :(得分:9)

我正在研究相同的概念,并找到了Joel Pobar撰写的这篇有前途的文章,

Create a Language Compiler for the .NET Framework - not sure where this has gone

Create a Language Compiler for the .NET Framework - pdf copy of the original doc

他讨论了编译器的高级概念,并继续为.Net框架创建自己的语言。虽然它的目标是.Net框架,但许多概念应该能够被复制。该条款包括:

  1. Langauge定义
  2. 扫描仪
  3. Parser(我主要感兴趣的是)
  4. 定位.Net框架
  5. 代码生成器
  6. 还有其他主题,但你得到了正确的。

    它针对人们开始,用C#编写(不完全是Java)

    HTH

答案 17 :(得分:8)

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

生成C代码就像生成HTML一样简单(只使用print或等效),这反过来比编写C语法分析器或HTML解析器容易得多。

答案 18 :(得分:8)

来自comp.compilers FAQ

Per Brinch Hansen撰写的“编程个人计算机” Prentice-Hall 1982 ISBN 0-13-730283-5

这本不幸的书名 解释了单用户编程环境的设计和创建 对于微观,使用称为爱迪生的Pascal式语言。作者介绍 所有源代码和解释逐步实现的 爱迪生编译器和简单的支持操作系统,都写在 爱迪生本身(除了一个象征性的小支持内核 用于PDP 11/23的汇编程序;也可以为IBM订购完整的源代码 PC)。

这本书最有趣的事情是:1)它的能力 演示如何创建一个完整的,自包含的,自我维护的, 有用的编译器和操作系统,以及2)有趣的讨论 语言设计和规范问题以及第2章中的权衡。

Per Brinch Hansen撰写的“关于Pascal编译器的Brinch Hansen” Prentice-Hall 1985 ISBN 0-13-083098-4

另一种理论上的光 这里是重要的语用学 - 如何编写代码的书。作者介绍了 设计,实现和编译器和p代码的完整源代码 Pascal-(Pascal“减”)的解释器,一个带布尔值和。的Pascal子集 整数类型(但没有字符,实数,子范围或枚举类型), 常量和变量定义以及数组和记录类型(但没有打包, 变体,集合,指针,无名,重命名或文件类型),表达式, 赋值语句,带有值和变量的嵌套过程定义 参数,if语句,while语句和begin-end块(但没有 函数定义,过程参数,goto语句和标签, 案例陈述,重复陈述,陈述和陈述)。

编译器和解释器用Pascal *(Pascal“star”)编写,a Pascal子集扩展了一些Edison风格的功能以进行创建 软件开发系统。用于IBM PC的Pascal *编译器由。出售 作者,但很容易将本书的Pascal编译器移植到任何一个 方便的Pascal平台。

本书使编译器的设计和实现看起来很简单。一世 特别喜欢作者关注质量的方式, 可靠性和测试。编译器和解释器可以很容易地使用 作为更复杂的语言或编译器项目的基础,尤其如此 如果你被迫快速得到一些东西并运行。

答案 19 :(得分:8)

你应该查看Darius Bacon的“ichbins”,这是一个针对C语言的小型Lisp方言的编译器,只需6页以上的代码。它对大多数玩具编译器的优势在于语言足够完整,编译器就在其中编写。 (tarball还包括一个解释器来引导事物。)

关于我在学习Ur-Scheme网页上编写编译器的有用之处还有很多内容。

答案 20 :(得分:7)

抱歉,这是西班牙文,但这是阿根廷名为“CompiladoreseIntérpretes”(编译和口译)的课程的参考书目。

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

  
      
  • C编译器设计。
    Allen I. Holub

      普伦蒂斯霍尔。 1990。

  •   
  • Compiladores。 TeoríayConstrucción。
    Sanchís   Llorca,F.J。,GalánPascual,C。编辑Paraninfo。 1988。

  •   
  • 编译器构造。
    Niklaus Wirth

      Addison-Wesley出版社。 1996。

  •   
  • Lenguajes,GramáticasyAutómatas。 Unenfoquepráctico。
    佩德罗   IsasiViñuela,PalomaMartínez   Fernández,DanielBorrajoMillán。 Addison-Wesley Iberoamericana   (西班牙)。 1997。

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

      普伦蒂斯霍尔。 1992。

  •   
  • 面向对象的编译器构造。
    吉姆福尔摩斯。   
    Prentice Hall,恩格尔伍德   Cliffs,N.J。1995

  •   
  • Compiladores。 Conceptos Fundamentales。
    B. B. Teufel,S。   施密特,T。Teufel。

      Addison-Wesley Iberoamericana。 1995。

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

      John E. Hopcroft。 Jeffref D. Ullman。   
    Addison-Wesley。 1979。

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

      Mc Graw Hill。 1983。

  •   
  • 解析技术。实用指南。
    迪尔格鲁恩,塞尔   雅各布。
    Impreso por los   autores。 1995年
      http://www.cs.vu.nl/~dick/PTAPG.html

  •   
  • Yacc:又一个编译器编译器。
    斯蒂芬   C. Johnson计算科学   技术报告N°32,1975。贝尔   实验室。 Murray Hill,New
      泽西。

  •   
  • Lex:一个词法分析器生成器。
    M. E. Lesk,E。Schmidt。计算科学技术   报告No 1975年,1975年。贝尔实验室。   新泽西州默里山。

  •   
  • lex& YACC。
    John R. Levine,Tony Mason,Doug Brown。
      奥莱利&协会。 1995。

  •   
  • 计算理论的要素。
    Harry R. Lewis,   Christos H. Papadimitriou。   SegundaEdición。普伦蒂斯霍尔。 1998年。

  •   
  • Un Algoritmo Eficiente paralaConstruccióndelGrafo de Dependencia de Control。
      Salvador V. Cavadini。
      Trabajo Final de Grado para obtenerelTítulodeIngenieroenComputación。
      FacultaddeMatemáticaAplicada。   U.C.S.E. 2001。

  •   

答案 21 :(得分:7)

Fraser和Hanson的LCC编译器(wikipedia)(project homepage)在他们的书“A Retargetable C Compiler:Design and Implementation”中有所描述。它非常易读,可以解释整个编译器,直到代码生成。

答案 22 :(得分:7)

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

答案 23 :(得分:6)

  1. 这是一个广泛的主题。不要低估这一点。并且不要低估我不低估它的观点。
  2. 我听说Dragon Book是一个(?)的起点,还有搜索。 :)在搜索方面做得更好,最终将是你的生活。
  3. 构建自己的编程语言绝对是一个很好的练习!但要知道它最终永远不会用于任何实际目的。例外情况很少,非常很远。

答案 24 :(得分:6)

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

Tutorial: Metacompilers Part 1

这完全基于一篇惊人的10页小技术论文:

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

从1964年的诚实到上帝。我在1970年学会了如何构建编译器。当你最终了解编译器如何重新生成时,会有一个令人兴奋的时刻....

我从大学时代就知道网站作者,但我与网站无关。

答案 25 :(得分:5)

如果您有兴趣为函数式语言(而不是程序性语言)编​​写编译器,Simon Peyton-Jones和David Lester的“Implementing functional languages: a tutorial”是一本很好的指南。

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

描述了几种不同类型的编译器,但即使您只遵循所谓的Core模板编译器,您也会非常了解函数编程的内容。

答案 26 :(得分:5)

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

十多年前我收到了一本名为Project Oberon的书,它在编译器上有一些非常好的文字。这本书真正脱颖而出,因为源和解释是非常实用和可读的。完整的文本(2005年版)已经以pdf格式提供,因此您可以立即下载。编译器将在第12章中讨论:

http://www-old.oberon.ethz.ch/WirthPubl/ProjectOberon.pdf

Niklaus Wirth,JürgGutknecht

(治疗方法并不像他关于编译器的书那样广泛)

我已经阅读了几本关于编译器的书籍,我可以在龙书上读到第二本书,花在这本书上的时间非常值得。

答案 27 :(得分:4)

您可以使用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";
        }
    }
    
  2. 现在使用此类运行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();
    }
    

答案 28 :(得分:4)

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

阅读它。

如果你愿意的话,可以使用它,但是看看另一个关于如何编写更大更完整的编译器的参考文献。

阅读On Trusting Trust,了解可以在此域中执行的不明显事项。

答案 29 :(得分:4)

到目前为止,列表中没有包含这本书:

Basics of Compiler Design (Torben Mogensen) (来自哥本哈根大学计算机科学系)

我也有兴趣了解编译器并计划在未来几年内进入该行业。就我所见,本书是开始学习编译器的理想理论书。它可以免费复制和复制,干净而精心编写,并以简单的英语提供给您,无需任何代码,但仍然通过说明和图表等方式呈现机制。值得一看。

答案 30 :(得分:3)

我编写了一个关于编译器设计的在线教程,标题为“让我们构建一个脚本引擎编译器,以及一个名为Bxbasm的本机代码编译器”。 在线文档位于: http://geocities.com/blunt_axe_basic/tutor/Bxb-Tutor.doc

以zip格式提供的文档,支持文件和编译器位于: http://geocities.com/blunt_axe_basic

此外: http://tech.groups.yahoo.com/group/QDepartment

史蒂夫A.

答案 31 :(得分:3)

龙书太复杂了。所以忽略它作为起点。这很好,一旦你有一个起点就会让你思考很多,但是对于初学者来说,也许你应该简单地尝试使用RD,LL或LR解析技术编写一个数学/逻辑表达式求值程序,并写入所有内容(lexing / parsing)也许是手工编写的C / Java。这本身很有趣,可以让您了解编译器中涉及的问题。然后你可以使用一些脚本语言跳转到你自己的DSL(因为处理文本通常更容易),就像有人说的那样,用脚本语言本身或C生成代码。你应该使用flex / bison / antlr等来如果要在c / java中执行此操作,请执行lexing / parsing。

答案 32 :(得分:3)

我很惊讶它没有被提及,但Donald Knuth的计算机编程艺术最初是作为一种关于编译器编写的教程编写的。

当然,Knuth博士对主题进行深入研究的倾向导致编译器编写教程扩展到估计9卷,其中只有三卷实际上已经发布。这是对编程主题的一个相当完整的阐述,涵盖了编写编译器时需要了解的所有内容。

答案 33 :(得分:3)

列表中缺少:垃圾收集:Jones和Lins的自动动态内存管理算法。

(假设您正在编写编译器运行时系统,并且您正在实现垃圾收集语言。

答案 34 :(得分:2)

作为一个起点,最好创建一个递归下降解析器(RDP)(假设你想创建自己的BASIC风格并构建一个BASIC解释器)来理解如何编写编译器。 我在Herbert Schild的C Power Users中找到了最好的信息,第7章。本章引用了H. Schildt的另一本书“C完整参考”,他解释了如何创建一个计算器(一个简单的表达式解析器)。我发现eBay上的这两本书都很便宜。 如果您访问www.osborne.com或登记www.HerbSchildt.com,您可以查看该书的代码。 我在他的最新着作

中找到了与C#相同的代码

答案 35 :(得分:2)

最快的方法是通过两本书:

JP Bennett的1990版An Introduction to Compiling Techniques, a First Course using ANSI C, LeX, and YaCC - 示例代码,解析理论和设计的完美平衡 - 它包含一个用C,lex和yacc编写的完整编译器,用于简单的语法

Dragon Book(旧版) - 主要是前书中未涵盖的功能的详细参考

答案 36 :(得分:1)

如果你像我一样,没有正式的计算机科学教育,并且对此感兴趣 建立/想知道编译器的工作原理:

我推荐“Java编程语言处理器:编译器和解释器”, 对于自学成才的计算机程序员来说,这是一本很棒的书。

从我的观点来看,理解那些基本语言理论,自动化机器和设定理论并不是一个大问题。问题是如何将这些东西变成代码。上面的书告诉你如何编写解析器,分析上下文和生成代码。如果你无法理解这本书,那么我不得不说,放弃构建一个编译器。这本书是我读过的最好的编程书。

还有一本书,也很好, 中的编译器设计。有很多代码,它告诉你有关如何构建编译器和词法分析器工具的一切。

构建编译器是一种有趣的编程实践,可以教你大量的编程技巧。

不要购买Dragon book。这是浪费金钱和时间,不适合从业者。

答案 37 :(得分:1)

如果你不是只是在寻找书籍,而且对那些有关于这个主题的文章的网站感兴趣,我也写过关于创建编程语言的各个方面的博客。大多数帖子都可以在我的博客"Language Design" category中找到。

特别是,我将手动生成Intel机器代码,自动生成机器或字节码,创建字节码解释器,编写面向对象的运行时,创建简单的加载器以及编写简单的标记/清除垃圾收集器。所有这一切都以非常务实和务实的方式进行,而不是让你厌倦了很多理论。

希望得到有关这些的反馈。

答案 38 :(得分:1)

每当我想尝试一种新的语言想法时,我只需编写一个简单的解析器,并让它生成一些易于获得良好编译器的语言,例如C.

您认为C ++是如何完成的?

答案 39 :(得分:0)

  • 首先确保您可以在Stack Overflow上回答大部分标记为C ++的问题。
  • 之后,您应该确保了解其他编译器如何工作并理解其部分源代码。
  • 您会注意到您需要汇编程序并开始学习汇编程序,直到您可以使用该标记回答许多问题。
  • 如果你走到这一步,你会发现几年过去了,并意识到这样一个项目有多大,并且可能会从当时的问题微笑(如果此页面仍然存在的话)...