问题 如何用C / ++编写一个简单的编译器? [重复]


可能重复:
学习编写编译器 

嗨Stack Overflow,现在不要误会我的意思,我不打算为C ++编写一个编译器(虽然我打算用C ++编写)或Java或其他一些高级复杂的编程语言。我只想学习将基本指令集转换为Windows可执行文件的基础知识(比如说,只是一个带有5-6个函数的简单语言,完全自定义)。另外,我不想下载任何库或头文件。如果您可以将我链接到任何非常基本的示例源或教程,将不胜感激!


1518
2017-10-15 23:43


起源

这是我从未真正找到任何解释的东西。对不起我造成了facepalm =(
原始版本 学习编写编译器。简单来说,你想要Crenshaw教程,但是对于简单的你也是如此 别 想做c ++ ...... - dmckee
@dmckee +1不想要C ++ - 复杂到足以需要解析树的编译器需要大量的树操作,以及C ++(和Java,以及ML / Haskell系列之外的任何语言以及类似灵感的语言,如Scala)树木操纵真的很臭。 - Michael Ekstrand
@Michael:你不想做c ++的原因是,在你允许模板之前,c ++有一个地狱语法。 - dmckee
“简单”和“编译器”这两个词并不属于同一个句子。构建具有非常有限的特征的小编译器是一个数量级。 - ubiquibacon


答案:


杰克克伦肖的 让我们构建一个编译器 从一开始就是一个很好的教程。他是一位优秀的作家,使这个主题易于理解。


6
2017-10-15 23:48





要解析输入,您应该阅读 递归下降解析 (这些可能是最容易手工实现的解析器),尽管你还需要某种类型的词法分析器来为你的解析器生成令牌。它们可以手工编码(我已经完成了),虽然它更容易使用类似的词法分析器 lex 要么 flex

解析输入后,您需要将其转换为适当的输出。我无法帮助你,因为我不太了解Windows工具链。 “简单”的方法是生成程序集并通过NASM,MASM或编译器环境随附的任何汇编程序运行它。如果您的语言足够简单,您可以在解析器代码中生成程序集。


4
2017-10-15 23:49



多谢男人,我个人之所以想要学习这个(以及我讨厌图书馆的原因),是因为我喜欢自己写东西,这是我想要理解的话题。 lexing,我理解,这是文本从文本到可执行代码的神秘点。另一方面,我想感谢你的链接。


以下是编写基本编译器所需的内容:

  1. 分析器。您将需要解析您的语言,并创建一个抽象语法树。您可能想学习编写解析器。您可以手动编写解析器代码,也可以使用解析器生成器,例如lex / yacc。
  2. 部件。您需要从语法树生成汇编指令。
  3. 指令系统。您需要将程序集转换为机器代码,在某些特定指令集中(典型的Intel和AMD CPU使用x86指令集;或者,您可以定位Java VM的指令集或.NET的IL)。

3
2017-10-15 23:49



-1 Lex不是解析器。 - alternative
@mathepic:我没有声称它是一个解析器。 - Lie Ryan
我打算说解析器生成器。 - alternative


实际上,你需要的最重要的是弄清楚.exe文件的二进制格式(除非你打算使用现有的链接器,此时我认为你需要输出也具有二进制格式的obj文件)。

你还需要处理大量的汇编,除非你已经非常熟悉x86指令集,否则我会尝试别的东西。

以下是一些可能性:

  • 曾经有一种叫做“Tiny C”的东西 - 我猜是这样的: http://bellard.org/tcc。 Tiny C是一个足够好的编译器来构建自己,但不是那么复杂,以至于很难理解。这是一个简单的“如何构建编译器”课程。在8088上被它搞砸了。

  • “嵌入式”cpu的输出。它们往往具有简单的汇编语言和非常明确定义的可执行格式。这将是一个很好的起点。

  • 输出C代码而不是二进制代码。这肯定是作弊,但你可以专注于你的语言,而不是太担心汇编语言。

  • 最后,如果你真的想直接创建.exe,首先编写一个产生“Hello world”exe的应用程序。不要打扰它“编译”任何东西,只需手动编辑代码,将其转换为exe格式并运行它 - 在这样做时你会知道你把所有的位排成一行并进入正确的位置,然后你可以放心地在编译器上启动。

在此之后,然后通过这里给出的许多程序来创建语言 - 但是如果你只是想看看它是如何工作的,我肯定会先做一些小的迭代,不要担心你是什么将碰到你遇到它。


2
2017-10-16 00:13





我会推荐www.antlr.org。我在C#工作,但它支持C,Java,Python等。


0
2017-10-15 23:52





要了解如何在C ++中构建编译器与C或Pascal不同,请尝试使用Boost 精神 解析器框架。

这假设您熟悉C ++。

为了学习创建编译器,我建议使用比C ++更简单的语言,然后推进到C ++。

干杯&hth。,


0
2017-10-16 00:17