关于语言不可知:学习编写编译器

Learning to write a compiler

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

我正在寻找一些有用的书籍/教程,关于如何编写自己的编译器,只是为了教育目的。我最熟悉C/C++、Java和Ruby,所以我更喜欢包含三个资源之一的资源,但是任何好的资源都是可以接受的。


资源大清单:

  • 编译器教育的NanoPass框架?
  • 高级编译器设计与实现$
  • 编译器构造的增量方法?
  • Antlr 3.x视频教程
  • 编译器设计基础
  • 构建鹦鹉编译器
  • 编译程序基础
  • 编译器构造$
  • 编译器设计与构造$
  • 用C编写编译器$
  • 制作口译员
  • C语言的编译器设计?
  • 编译器:原理、技术和工具——又名"龙书";被广泛认为是编译器写作的"书"。
  • 工程编译器$
  • 程序设计语言基础
  • Flipcode文章存档(查找"实现Jan Niestadt的脚本引擎")。
  • 掌握游戏脚本$
  • 如何在C中从头构建虚拟机?
  • 实现功能语言
  • 实现编程语言(使用BNFC)
  • 使用C 4.0实现编程语言
  • 解释器模式(在设计模式$中描述)指定了一种用语言评估句子的方法。
  • 语言实现模式:创建您自己的特定于域的通用编程语言
  • 让我们用Jack Crenshaw构建一个编译器-pdf?版本(示例采用Pascal,但信息通常适用)
  • 链接器和加载器$(谷歌图书)
  • 小片口齿不清$
  • LLVM教程
  • 现代编译器在ML $中实现了Java $$和c$版本,被广泛认为是一本非常好的书。
  • 面向对象编译器构造$
  • 解析技术-实用指南
  • 奥伯伦项目?-看第13章
  • 为个人计算机编程$
  • 程序语言:应用和解释
  • 兔子:计划的编纂者?
  • 信任的思考——快速指南
  • 为.NET框架滚动您自己的编译器-来自msdn的快速教程
  • 计算机程序的结构和解释
  • 类型和编程语言
  • 想写一个编译器吗?-快速指南
  • 用Ruby自下而上编写编译器

传说:

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


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

尽管如此,解决这个问题的一个简单方法(至少在我的编译器类中使用的方法)是在上面描述的两个部分中构建编译器。具体来说,通过构建上半部分,您将对整个过程有一个很好的了解。

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

一些关于这个主题的书,我发现特别有用的是编纂者的原则和技巧(或龙书,由于封面上有可爱的龙)。它有一些很好的理论,并且以一种非常容易理解的方式明确地涵盖了上下文无关语法。另外,为了构建词汇分析器和解析器,您可能会使用*nix工具lex和yacc。令人不解的是,这本名为《雷克斯和雅克》的书在龙书的这一部分中被删去了。


我认为ML中的现代编译器实现是编写文本的最好的入门编译器。有一个Java版本和一个C版本,任何一个都可以在你的语言背景下更容易访问。本书将大量有用的基础材料(扫描和解析、语义分析、激活记录、指令选择、RISC和x86本机代码生成)和各种"高级"主题(编译OO和函数语言、多态性、垃圾收集、优化和单个静态分配表)打包到相对较少的空间中。(500页)。

我更喜欢现代编译器实现,而不是《龙书》,因为现代编译器实现调查的领域更少——相反,它确实涵盖了编写一个严肃、体面的编译器所需的所有主题。在你读完这本书之后,如果你需要的话,你将准备好直接处理研究论文。

我必须承认我对尼克劳斯·沃特的编译器结构有一个严重的弱点。它以PDF格式在线提供。我发现wirth的编程美学很简单,但是有些人觉得他的风格太小(例如wirth喜欢递归下降解析器,但大多数cs课程都集中在解析器生成器工具上;wirth的语言设计相当保守。)编译器构造是对wirth基本思想的一种非常简洁的提炼,因此无论不管你喜不喜欢他的风格,我强烈推荐你读这本书。


我同意龙书的参考;在我看来,它是编译器构造的最终指南。不过,准备好一些核心理论。

如果你想要一本理论上更轻松的书,那么游戏脚本的掌握也许对你来说是一本更好的书。如果你是编译器理论的新手,它会提供一个更温和的介绍。它不包括更实用的解析方法(选择非预测递归下降而不讨论ll或lr解析),我记得,它甚至没有讨论任何类型的优化理论。另外,它不是编译成机器代码,而是编译成一个字节码,这个字节码应该在您也编写的VM上运行。

它仍然是一本不错的书,尤其是如果你能在亚马逊上便宜买到它。如果你只想简单地介绍编译器,那么掌握游戏脚本并不是一个糟糕的方法。如果你想成为硬核的前面,那么你应该满足于无非是龙书。


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

或者看看俚语。这类似于"让我们构建一个编译器",但对于初学者来说,这是一个更好的资源。这是一个PDF教程,它采用7步的方法教你一个编译器。添加了QuoLink链接,因为它有链接到所有不同的俚语端口的链接,在C++、Java和JS中也是Python和Java的解释器,最初是使用C.Y.NET和.NET平台编写的。


如果您希望使用强大的、更高级的工具,而不是自己构建所有东西,那么浏览本课程的项目和阅读资料是一个不错的选择。这是一个由Java分析器引擎ANTLR作者编写的语言课程。你可以从务实的程序员那里得到一本PDF格式的课程书。

本课程将介绍您在其他地方看到的标准编译器编译器的内容:解析、类型和类型检查、多态性、符号表和代码生成。几乎唯一没有涉及的就是优化。最后一个项目是编译C的一个子集的程序。因为您使用诸如antlr和llvm之类的工具,所以在一天内编写整个编译器是可行的(我有一个存在证明,尽管我的意思是24小时)。它对使用现代工具的实际工程很重要,理论上稍微轻一点。

顺便说一句,LLVM简直太棒了。在许多情况下,您通常可以编译到汇编,而最好编译到LLVM的中间表示。它具有较高的层次、跨平台性,LLVM非常擅长从中生成优化的装配。


如果你有一个很小的时间,i Niklaus Wirth的"编译器"建设(Addison Wesley。一本小册子,1996),小小的一天,你可以读,但它解释了《基础(包括如何实现递归下降解析器的lexer,栈,和你自己的虚拟机)。在这之后,如果你想要一个深潜水,有没有其他的方式。commenters suggest的龙争虎斗的书。


你可能想看看lex/yacc(或者flex/bison,随便你怎么称呼它们)。flex是一个词法分析器,它将解析和标识语言的语义组件("tokens"),而bison将用于定义解析每个token时会发生什么。对于编译为C或动态运行指令的编译器来说,这可能是(但绝对不限于)打印出C代码。

这个常见问题解答应该对您有所帮助,本教程看起来非常有用。


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

通常解释python和ruby。也许你也想从一个翻译开始。一般来说比较容易。

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

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

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

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

如果您要编译该语言,它将更加复杂。您必须为不同的计算机体系结构编写后端,并从这些后端中的中间表示生成机器代码。我为这项任务推荐LLVM。

关于这个主题有几本书,但我不能推荐其中任何一本供一般使用。他们中的大多数人太学术或太实际。没有"21天自学编译器写作",因此,你必须买几本书才能很好地理解整个主题。如果你在网上搜索,你会看到一些在线书籍和讲稿。也许你附近有一所大学图书馆,你可以在那里借一些关于编译器的书。

如果你想让你的项目认真进行的话,我也推荐你有良好的计算机理论和图论背景知识。计算机科学学位也会有所帮助。


看看下面这本书。作者是安特尔的创造者。

语言实现模式:创建您自己的特定于域的通用编程语言。

alt text


约翰·莱文的《链接器和加载器》是一本尚未提出但非常重要的书。如果您不使用外部汇编程序,您将需要一种方法来输出一个可以链接到最终程序的对象文件。即使您使用的是外部汇编程序,您可能也需要了解重新定位以及整个程序加载过程是如何工作的,以生成一个工作工具。这本书收集了很多关于这个过程的随机知识,适用于各种系统,包括win32和linux。


龙书绝对是"构建编译器"的书,但是如果您的语言没有当前一代语言那么复杂,您可能需要从设计模式中查看解释器模式。

书中的例子设计了一个规则的表达式,就像语言一样,并经过深思熟虑,但是正如他们在书中所说,它有利于通过这个过程进行思考,但实际上只对小语言有效。然而,用这种模式为一种小语言编写一个解释器要比学习所有不同类型的解释器、yacc和lex等快得多。


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

本教程建议您编写自己的解析器和lexer等,但我建议您在得到这个想法后再研究bison和flex。它们使生活变得如此简单。


我记得七年前我刚开始编程时问这个问题。当我问的时候我很小心,很奇怪我没有你那么多的批评。然而,他们确实向我指出了"龙书"的方向,在我看来,这是一本非常好的书,它解释了编写编译器所需要知道的一切(当然,你必须掌握一两种语言)。你知道的语言越多,就越快乐。

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

许多人还说编写编译器既愚蠢又毫无意义。好吧,编译器开发有用的原因有很多:-因为它很有趣。-这是有教育意义的,当你学习如何编写编译器时,你会学到很多关于计算机科学和其他在编写其他应用程序时有用的技术。-如果没有人编写编译器,现有的语言也不会变得更好。

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

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

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


我发现书《龙多太硬太多的重点放在阅读和语言理论,是不是真的需要在实践中写的编译器。

我会添加一个包含完整的源代码,书上几乎一定是有效和简单的编译器奥伯伦Oberon项目。

Alt text


"... Let's Build a Compiler ..."

第二个是http://compilers.iecc.com/crenshaw/,作者是@sasb。暂时别买更多的书了。

为什么?工具和语言。

所需语言为Pascal,如果我记得正确,则基于turbo Pascal。如果你去http://www.free pascal.org/下载pascal编译器,就会发生这种情况。所有的例子都可以直接从http://www.freepascal.org/download.var页面下载。关于free pascal,最重要的是你几乎可以使用任何你喜欢的处理器或操作系统。

一旦你掌握了这些课程,那就试试更高级的"龙书"~http://en.wikipedia.org/wiki/dragon_book


我正在研究同样的概念,发现了乔尔·波巴的这篇有前途的文章,

为.NET框架创建一个语言编译器-不确定它的位置

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

他讨论了编译器的高级概念,并着手为.NET框架开发自己的语言。虽然它的目标是.NET框架,但许多概念应该能够被复制。文章内容包括:

  • 语言定义
  • 扫描仪
  • 解析器(我主要感兴趣的位)
  • 以.NET框架为目标
  • 代码生成器
  • 还有其他的主题,但是你得到了公正。

    它的目标是用C语言编写的人(不太Java)

    高温高压

    骨头


    你应该看看DariusBacon的"ichbins",它是一个针对C语言的小Lisp方言的编译器,代码只有6页多。与大多数玩具编译器相比,它的优势在于语言足够完整,编译器是用它编写的。(tarball还包括一个解释程序来引导该东西。)

    关于在我的UR方案网页上学习编写编译器,我发现有更多有用的东西。


    从comp.compilers常见问题:

    "计算机编程人员通过"brinch汉森Prentice Hall 730283 1982年ISBN 0 13 5

    这个不幸的同名图书介绍了在设计和创作a单用户编程环境生物显微镜,使用一类叫做爱迪生Pascal语言。作者介绍所有的源代码和"讲"一步一步的实现.爱迪生和简单的编译器支持的操作系统,所有写在小爱迪生(除了本身支持内核符号写在a汇编语言的PDP 11/23;完整的源代码可以在IBM序PC)。

    最有趣的事情是:(1)本书是它的能力表明如何创建一个完整的,独立的,自我维持,编译器和操作系统有用的,和有趣的讨论(2)语言的设计和规范问题和权衡在2章。

    "brinch汉森在Pascal编译器通过brinch汉森"redPrentice Hall 083098 1985 ISBN 0 13 4

    另一个光开关理论重金属在pragmatics这里的如何,它的代码的书。作者提出的。设计,实施,和完整的源代码,编译代码A和P帕斯卡(Pascal翻译为"减"),A与Pascal子集的布尔和整数类型(但没有人物,subranged实数,或enumerated类型)常数与变量和数组,但没有填充,记录类型(集,命中,变体,nameless,更名为文件类型),或表达的赋值语句,嵌套过程定义和变量的值if语句,while语句的参数,和结束块(但没有开始函数定义语句,goto语句的程序参数,和标签CASE语句,for语句,重复语句和语句)。

    在编译器和解释器是用Pascal(帕斯卡*"星"),A一个扩展的Pascal子集的一些风格特点为"爱迪生软件开发系统。A *的Pascal编译器的IBM PC是卖给red作者,但它易于端口书的Pascal编译器的任何Pascal和平台。

    本书设计与实施使得A的外观简单的编译器。i样的方式特别是与作者有关的质量,的可靠性,和测试。在编译器和解释器很容易使用的CAN为一个或更多的参与的基础语言的编译器项目。如果你得到的东西被压到启动和运行。


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

    生成C代码和生成HTML一样简单(只需使用print或等效工具),而生成HTML又比编写C解析器或HTML解析器容易得多。


    弗雷泽和汉森的LCC编译器(维基百科)(项目主页)在他们的书"可重定目标的C编译器:设计和实现"中进行了描述。它非常易读,可以解释整个编译器,直到代码生成。


    对不起,这是西班牙语的,但这是一门叫做"Compiladores e int_rpretes"(编译器和口译员)的阿根廷课程的参考书目。

    本课程从形式语言理论到编译器构造,您至少需要构建一个简单的编译器:

    • Compilers Design in C.
      Allen I. Holub
      Prentice-Hall. 1990.

    • Compiladores. Teoría y Construcción.
      Sanchís
      Llorca, F.J. , Galán Pascual, C. Editorial Paraninfo. 1988.

    • Compiler Construction.
      Niklaus Wirth
      Addison-Wesley. 1996.

    • Lenguajes, Gramáticas y Autómatas. Un enfoque práctico.
      Pedro
      Isasi Vi?uela, Paloma Martínez
      Fernández, Daniel Borrajo Millán. Addison-Wesley Iberoamericana
      (Espa?a). 1997.

    • The art of compiler design. Theory and practice.
      Thomas
      Pittman, James Peters.
      Prentice-Hall. 1992.

    • Object-Oriented Compiler Construction.
      Jim Holmes.

      Prentice Hall, Englewood
      Cliffs, N.J. 1995

    • Compiladores. Conceptos Fundamentales.
      B. Teufel, S.
      Schmidt, T. Teufel.
      Addison-Wesley Iberoamericana. 1995.

    • Introduction to Automata Theory, Languages, and Computation.
      John E. Hopcroft. Jeffref D. Ullman.

      Addison-Wesley. 1979.

    • Introduction to formal languages.
      Gy?rgy E. Révész.
      Mc Graw Hill. 1983.

    • Parsing Techniques. A Practical Guide.
      Dick Grune, Ceriel
      Jacobs.
      Impreso por los
      autores. 1995
      http://www.cs.vu.nl/~dick/PTAPG.html

    • Yacc: Yet Another Compiler-Compiler.
      Stephen
      C. Johnson
      Computing Science
      Technical Report No 32, 1975. Bell
      Laboratories. Murray Hill, New
      Jersey.

    • Lex: A Lexical Analyzer Generator.
      M. E. Lesk, E. Schmidt. Computing Science Technical
      Report No 39, 1975. Bell Laboratories.
      Murray Hill, New Jersey.

    • lex & yacc.
      John R. Levine, Tony Mason, Doug Brown.
      O’Reilly & Associates. 1995.

    • Elements of the theory of computation.
      Harry R. Lewis,
      Christos H. Papadimitriou.
      Segunda Edición. Prentice Hall. 1998.

    • Un Algoritmo Eficiente para la Construcción del Grafo de Dependencia de Control.
      Salvador V. Cavadini.
      Trabajo Final de Grado para obtener el Título de Ingeniero en Computación.
      Facultad de Matemática Aplicada.
      U.C.S.E. 2001.


    python与用python编写的python编译器捆绑在一起。您可以看到源代码,它包括所有阶段,从解析、抽象语法树、发出代码等。砍掉它。


  • 这是一个大问题。不要低估这一点。不要低估我的观点,不要低估它。
  • 我听说龙书是一本?开始的位置,以及搜索。:)更好地搜索,最终它将是你的生活。
  • 构建自己的编程语言绝对是一个很好的练习!但要知道,它最终不会用于任何实际目的。这方面的例外情况非常少。

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

    教程:元编译器第1部分

    这都是基于一篇令人惊叹的10页小技术论文:

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

    从诚实到上帝,1964年。早在1970年,我就从中学习了如何构建编译器。当您终于摸索编译器如何自我重新生成时,会有一个激动人心的时刻……

    我从大学时代就认识这个网站的作者,但我和这个网站没有任何关系。


    如果您对为函数式语言(而不是过程式语言)编写编译器感兴趣,西蒙·佩顿·琼斯和大卫·莱斯特的《实现函数式语言:教程》是一本很好的指南。

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

    描述了几种不同类型的编译器,但即使您只遵循所谓的核心模板编译器,您也将非常了解什么使函数式编程起作用。


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

    十多年前我有一本书叫ProjectOberon,里面有一些非常好的编译器文本。这本书真正突出的意义是,来源和解释是非常亲手和可读的。完整的文本(2005版)已提供PDF格式,因此您可以立即下载。编译器将在第12章中讨论:

    http://www-old.oberon.ethz.ch/wirthpubl/projectoberon.pdf

    Niklaus Wirth,J_rg Gutknecht

    (治疗不如他那本关于编纂者的书广泛)

    我读过几本关于编纂者的书,我可以仅次于龙书,花在这本书上的时间是非常值得的。


    到目前为止,这本书还没有列入名单:

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

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


    我也喜欢a href="http://compilers.iecc.com/crenshaw/">crenshaw教程/aa,因为它非常清楚编译器只是另一个读取一些输入并写出一些输出的程序。

    读它。

    如果你愿意的话,可以使用它,但是看看另一个参考资料,看看到底有多大和更完整的编译器被编写出来。

    并阅读a href="http://cm.bell-labs.com/who/ken/trust.html">on trusting trust/aa,了解在这个领域可以做的不明显的事情。


    你可以通过Apache软件基金会使用BCEL。通过这个工具,你可以生成类似汇编的代码,但是它是带有BCEL API的Java。您可以学习如何生成中间语言代码(在本例中是字节代码)。

    简单实例

  • 用这个函数创建一个Java类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    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();
    }

    龙书太复杂了。所以忽略它作为起点。它是好的,一旦你已经有了起点,你就会思考很多,但是对于初学者来说,也许你应该简单地尝试用RD、LL或LR语法分析技术来编写一个数学/逻辑表达式计算器。这本身很有意思,并让您了解编译器中涉及的问题。然后,您可以使用一些脚本语言跳进自己的DSL(因为在这些过程中处理文本通常更容易),就像某人所说的,在脚本语言本身或C.中生成代码,如果您要在C/Java中进行,就应该使用Flex/BISO/ANTLR等来进行词法分析。


    我写了一个关于编译器设计的在线教程,标题是"让我们构建一个脚本引擎编译器,以及一个名为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


    我很惊讶没人提到它,但唐纳德·克努斯的《计算机编程艺术》最初是作为一种编译器写作教程而写的。

    当然,Knuth博士对主题的深入研究使得编译器编写教程扩展到了估计的9卷,其中只有三卷已经出版。这是一个关于编程主题的相当完整的阐述,涵盖了关于编写编译器的所有知识,非常详细。


    一个列表:垃圾收集:自动动态内存管理算法的研究,由琼斯和林家。

    (如果你写的编译器和运行时系统,那你实现一垃圾收集的语言。


    作为一个起点,最好创建一个递归下降解析器(RDP)(假设您想创建自己的basic风格并构建一个basic解释器)来理解如何编写编译器。我在Herbert Schild的C Power用户第7章中找到了最好的信息。本章引用了H.Schildt的另一本书《C完整参考》,他在书中解释了如何创建计算器(一个简单的表达式解析器)。我在易趣上发现这两本书都很便宜。如果您访问www.osborne.com或登录www.herbschildt.com,您可以查看书籍的代码。我在他最近的一本书中找到了同样的密码,但是C


    的方法是通过两quickest书籍:

    到1990年版本的介绍编译技术,使用ANSI C的第一课程,Lex和Yacc的JP,贝内特一个完美的平衡的例子代码解析理论和设计,它包含一个完整的编译器lex和yacc写在C,一个简单的语法

    (旧版)》图书详细资料为主要特征的A需要覆盖在前书


    如果你不仅在找书,而且对有关于这个主题的文章的网站感兴趣,我已经在博客上介绍了创建编程语言的各个方面。大多数文章都可以在我的博客的"语言设计"类别中找到。

    特别是,我介绍了手动生成Intel机器代码、自动生成机器或字节码、创建字节码解释器、编写面向对象的运行时、创建简单的加载程序以及编写简单的标记/扫描垃圾收集器。所有这些都是以一种非常实际和务实的方式进行的,而不是用大量的理论让你感到厌烦。

    感谢您对这些问题的反馈。


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

    你认为C++是怎么做的?


    如果你像我一样,没有正规的计算机科学教育,并且对构建/想知道编译器是如何工作的:

    我推荐"Java中的编程语言处理器:编译器和解释器",一本自学的计算机程序员的好书。

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

    还有一本书,也是很好的,C语言的编译器设计。有很多代码,它告诉你关于如何构建编译器和lexer工具的一切。

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

    不要买龙书。这是浪费金钱和时间,而不是一个从业者。


    • 首先,确保您可以回答在堆栈溢出上标记C++的大部分问题。
    • 在此之后,您应该确保了解其他编译器的工作方式,并了解它们的源代码的[部分]。
    • 您会注意到您需要汇编程序,并将开始学习汇编程序,直到您可以用那个标记回答许多问题。
    • 如果你走了这么远的路,你会发现好几年过去了,你会意识到这样一个项目有多大,并且可能会对你过去提出的问题微笑(如果这个页面当时仍然存在的话)。