开始一个简单的(也许是最简单的)C编译器?

开始一个简单的(也许是最简单的)C编译器?,c,compiler-construction,programming-languages,C,Compiler Construction,Programming Languages,我遇到了这样一个问题: 我很好奇是否有任何教程或参考资料解释如何创建一个简单的C编译器。我的意思是,如果能让我理解算术运算就足够了。读了这篇作者的文章后,我变得非常好奇。写一些能理解自己的东西的想法似乎令人兴奋 为什么我提出这个问题而不是问谷歌?我试过谷歌,第一个链接是Pascal。其余的似乎不相关,并加上。。。我不是计算机科学专业的学生(所以我仍然需要学习像yacc这样的工具是做什么的),我想通过实践来学习这一点,我希望有更多经验的人在这些方面总是比谷歌做得更好。我想读一些与上面列出的文章精神

我遇到了这样一个问题:

我很好奇是否有任何教程或参考资料解释如何创建一个简单的C编译器。我的意思是,如果能让我理解算术运算就足够了。读了这篇作者的文章后,我变得非常好奇。写一些能理解自己的东西的想法似乎令人兴奋

为什么我提出这个问题而不是问谷歌?我试过谷歌,第一个链接是Pascal。其余的似乎不相关,并加上。。。我不是计算机科学专业的学生(所以我仍然需要学习像yacc这样的工具是做什么的),我想通过实践来学习这一点,我希望有更多经验的人在这些方面总是比谷歌做得更好。我想读一些与上面列出的文章精神相同的文章,但至少强调了构建简单C编译器的引导阶段

而且,我不知道最好的学习方法。我是从用C或其他语言构建C编译器开始的吗?我是写C编译器还是其他语言?我觉得,一旦我有了一些探索的方向,这样的问题就会得到更好的回答。有什么建议吗


有什么建议吗?

编译器由三部分组成:

  • 分析器
  • 抽象语法树(AST)
  • 汇编代码生成器
  • 有很多不错的解析器生成器都是从语言语法开始的。也许ANTLR是你开始的好地方。如果您想坚持使用C根,请尝试lex/yacc或bison

    有C的语法,但我认为C的整体是复杂的。你最好从语言的一个子集开始,然后逐步提高

    一旦有了AST,就可以使用它生成要运行的机器代码

    这是可行的,但不是微不足道的

    我也会在亚马逊上查找有关编写编译器的书籍。《龙书》是经典之作,但也有更现代的


    更新:在堆栈溢出方面也有类似的问题,比如。也可以查看这些资源。

    值得一提的是,在一个相对较小的源代码包中,它是一个功能非常全面的C编译器。您可能会从研究该源代码中获益,因为它可能比理解GCC的所有源代码库要容易得多。

    我建议您学习本教程:

    这是一个关于如何实现“小型语言”编译器的小示例。源代码非常小,将一步一步地进行解释

    LLVM(代表程序内部结构的低级虚拟机)库也有C前端库:


    编译器是一个非常大的项目,尽管我想尝试一下也无妨

    我知道至少有一个C编译器是用Pascal编写的,所以这不是你能做的最疯狂的事情。我个人会选择一种更现代的语言来实现我的C编译器项目,这两个都很简单(很容易为Python、露比、C、C++或java提供D/L包),因为它在简历上看起来会更好。 不过,为了将编译器作为初学者项目来完成,您需要喝下所有的


    总是有一些东西在运行,即使它没有什么作用。只需小步向编译器添加内容。(“频繁发布”。)选择一个非常小的语言子集,并首先实现它。(首先只支持
    i=0;
    ,然后从那里展开。)

    编译器是一个复杂的主题,涵盖了

    • 输入处理包括词法分析、语法分析
    • 为使用的每个变量构建符号存储,例如抽象语法树(AST)
    • 从AST树中,根据语法转置并构建机器代码二进制
    这绝非详尽无遗,因为这是一个抽象的鸟瞰图,从山顶上看,它归结为正确的语法符号,并确保格式错误的输入不会丢失,事实上,一个好的输入处理永远不会屈服于它,无论格式多么错误、多么可怕,输入被滥用的情况会被抛出。而且,在决定和知道输出将是什么时,它是否在机器代码中,这意味着您可能需要深入了解处理器指令…包括变量的内存寻址等等

    以下是一些供您开始使用的链接:

    • 有一个杰克·克伦肖的C代码…(我记得几个月前下载过…)
    • 这里有一个类似问题的链接
    • 此外,这里还有另一个小型的用于基本到x86汇编编译器的编译器
    • 找到Hendrix的小型C编译器

      • 学习函数式编程也可能是值得的。函数式语言非常适合在和中编写编译器。我学校的intro compilers课程包含函数式语言的介绍,作业都是用OCaml编写的

        有趣的是,你今天应该问这个问题,因为就在几天前,我写了一个lambda演算解释器。Lambda演算是所有函数式语言的老祖宗。它只有200行长(C++中,包括错误报告,一些漂亮的打印,一些Unicode),并且有两种结构,中间格式可以用来生成代码。 不仅从小处着手,建立最实用的编译器方法,还鼓励良好的、模块化的组织实践。

        这是我的观点(和猜想),如果不理解本科(专上)计算机科学课程中通常包含的数据结构,编写编译器是很困难的。这并不意味着您不能,但您需要了解基本的数据结构,如链表和树

        而不是编写一个完整的或符合标准的C语言编译器(至少在sta中)