Compiler construction 编写编译器。。。什么';是的,还有什么';怎么了?

Compiler construction 编写编译器。。。什么';是的,还有什么';怎么了?,compiler-construction,resources,bison,flex-lexer,Compiler Construction,Resources,Bison,Flex Lexer,好吧,在我寻找编写编译器所必需的东西的过程中,我遇到了一些障碍。似乎我发现的每一种技术或工具都有一些不同之处 我现在使用Bison和Flex,但我觉得这种方法已经过时了。这是真的吗?这是一种很好的向前兼容的方式来继续编写一种成熟的编程语言吗 在不同概念和工具(ANTLR、LL(k)、GLR、LALR、LLVM、Flex、Bison)的海洋中,编写编译器的当前趋势和最佳实践是什么?《龙书》过时了吗?< /P> < Pl>,Flex和Byson并没有什么错误,但是如果你正在寻找一些最新的(和面向对象

好吧,在我寻找编写编译器所必需的东西的过程中,我遇到了一些障碍。似乎我发现的每一种技术或工具都有一些不同之处

我现在使用Bison和Flex,但我觉得这种方法已经过时了。这是真的吗?这是一种很好的向前兼容的方式来继续编写一种成熟的编程语言吗


在不同概念和工具(ANTLR、LL(k)、GLR、LALR、LLVM、Flex、Bison)的海洋中,编写编译器的当前趋势和最佳实践是什么?《龙书》过时了吗?< /P> < Pl>,Flex和Byson并没有什么错误,但是如果你正在寻找一些最新的(和面向对象的),你可以考虑。

< P>我不能对各种方法进行比较,但是ANTLR组已经覆盖了一个很宽的范围:


其中包括大多数目前常见的。ANTLR还支持多种输出语言。我们计划解决一种类似CSS的语言

有人认真问过《龙之书》是否过时了吗?这是一个开创性的工人。我无法告诉你,仅仅从前两章我就学到了多少(因为我已经忘记了它…巴-达姆-巴姆)

每一项技术(也许除了goto声明)都有批评者和支持者。不要被“做出正确的工具选择”所困扰,而是全力以赴地学习概念并以合理的方式实现它们。我是说,拜托,伙计,即使你选择了世界上最完美的工具,你认为你会像现在的FORTRAN一样建造一个受人喜爱、崇拜和尊重的东西……我是说,我们喜欢它……对吗

当然不是人…这么多的学习来自于犯错误。那是你学到最多的地方


你能行

除非您想编写一个真正简单的编译器,否则您的重点是错误的

编写编译器只是编写解析器的一小部分。拥有一个解析器就像 当攀登珠穆朗玛峰时,攀登喜马拉雅山的山麓。你登上山麓山顶,然后向上看。。。只剩下20000英尺了,你只完成了真正简单的部分。你会注意到,登上山麓山顶所需的技术比走完剩下的路所需的技术要简单得多

(仅供参考:目前最好的解析技术是 在不破坏语法的情况下接受模糊语法。GLR更容易解析C++。 这违背了C++难以解析的民间定理。 来自试图使用YACC和ANTLR解析它的人)

要构建编译器,您需要大量的机器:

  • AST大厦
  • 符号表构造
  • 控制流分析
  • 数据流分析
  • 程序代码基本上表示为数据流计算(SSA或三元组)
  • 目标机的模型
  • 将程序代码映射到机器指令的一种方法
  • 寄存器分配
  • 优化:不断传播,循环展开
我们甚至没有得到接近全局的流分析、全局优化或特殊处理 适用于涉及SIMD指令或缓存优化的现代指令集。 ... 这一清单不胜枚举。《龙之书》很好地介绍了基本主题,但没有涉及任何高级主题。你会想要库珀的“编译器工程”和穆奇尼克的“高级编译器设计”作为参考,如果你在开始之前浏览过它们就好了


构建一个现代编译器是一项相当了不起的工程。

要构建一个编译器,我强烈建议站在巨人的肩膀上。有很多好东西可以组合在一起制作编译器。我一直在为C/C++兼职编写编译器。它使用GLR进行解析,构建AST,使用SSA作为中间形式,进行过程间优化,并为X86、ARM、MIPS、PowerPC、Sparc和其他程序生成代码

秘密?我从几个来源借用了代码

  • 预处理器和来自clang的错误报告
  • Elkhound和Elsa编译器生成器和C/C++编译器
  • 用于优化和代码生成的LLVM系统
在兼职工作中,我已经能够整理出一套相当有用的工具系统。如果我试着从头开始,我现在几乎没有完成解析器


我假设你和我处于相同的位置:你想编写一个编译器来获得乐趣,并至少了解它的每个阶段。因此,您不希望只为现有编译器编写插件。您希望避免使用太多现有的编译器模块,除非您能够准确地理解它们在做什么。在我的例子中,我使用的是
bison
,这是一个轻微的例外,因为它至少做了一些我认为理所当然的事情(我在大学里学习过语法等,但那是很久以前的事了)。另一方面,解析器生成器非常常见,这是一个值得关注的编译器阶段:
bison
可能会阻止我编写大量解析代码,但它给了我编写解析器操作代码的机会

与一些建议相反,我想说的是,您可以在不完全了解输入和目标语言的情况下开始。除了一些例外,语言特性在以后添加起来并不难。我发现的一个例外是控制流:如果您编写大多数后续操作来处理树形表单,则很难满足诸如
break
continue
goto
(甚至是结构化表单)之类的语句。所以我建议在做太多之前,先把tree翻译成CFG

  • 为一些相当稳定的输入子集编写解析器
  • 添加构建有用的内存表示形式的操作(典型