4

我刚刚开始我的毕业项目,该项目应该持续 6 个月。该项目的目标是为一种脚本语言实现一个 .Net 编译器。我在课程中将编译器构造作为一个主题,并且知道如何实现编译器的基本步骤,但是我们使用 Bison 和简单的编译器以及 GCC 作为后端,因此我对实现编译器知之甚少在.Net平台上。

在对这个主题进行了一些研究之后,我发现了以下代码生成的替代解决方案(我不是在谈论编译器的其他重要部分,比如解析器——它超出了这里的范围):

  1. 使用Reflection.Emit直接生成代码。
  2. 在 Reflection.Emit 上使用通用编译器接口抽象来自动化某些代码生成。
  3. 在运行时使用CodeDOM进行 C# 和 VB 编译。
  4. 有一个新出现的 C#“编译器即服务”,称为Roslyn,现在可作为 CTP 使用。
  5. DLR提供对动态代码生成的支持,并具有一些用于通过表达式树等生成运行时代码的接口。
  6. Mono 附带Mono.Cecil库,该库似乎也具有一些代码生成功能。

我项目的主要目标是更深入地研究 .Net,学习编译器构造并为我的工作取得好成绩。第二个目标是提出一个编译器实现,以后可以在许可的开源许可下向社区开放。

那么,什么是最有趣、最有教育意义、最有趣和最有前途的方法呢?如果我有更多时间,我肯定会尝试所有这些,但我需要在 6 个月内提交我的工作以获得积极的成绩......

提前谢谢你,亚历山大。

4

3 回答 3

5

如果您想要更简单的方法并且您的语言可以合理地翻译成 C#,我建议您生成 C# 代码(或类似代码)并编译它。罗斯林可能是最擅长的。显然,CCI 也可以使用CCI Code来做到这一点,但我从未使用过。我不会推荐 CodeDOM,因为它不支持静态类或扩展方法等功能

如果你想要更多的控制或者你想要去低级,你可以使用 Reflection.Emit 直接生成 CIL。但这将是(更多)工作,特别是如果您不熟悉 CIL。我认为 Cecil 可以以相同的方式使用,但它是用于其他用途的,我认为它与 Reflection.Emit 相比没有任何优势。

顾名思义,DLR 是动态语言的意思。它使用的Expressions 可以用于代码生成,但我认为它们最擅长在运行时生成相对简单的方法。当然,如果您的语言是动态的,DLR 本身就会非常有用。

于 2011-11-10T09:25:36.127 回答
2

Boo是一种针对 CLI 的语言/编译器。它似乎是开源的,因此您可以研究他们如何完成它。

于 2011-11-09T23:07:23.267 回答
2

回到我写编译器的时候,我会写到汇编语言(即汇编语言源代码),然后通过系统的汇编器运行。这样我就可以很容易地看到我正在生成什么。mov ax, bx阅读(x86 程序集)比解码 HEX 操作码要容易得多。

如果不允许我在最终产品中使用汇编器,我会使用汇编输出开发编译器,然后一旦一切正常,我就创建了一个二进制输出路径。美妙之处在于,我只需要更改实际的字节输出(操作码和二进制值而不是文本)。

我建议为您的项目做类似的事情。最初开发它以输出可以使用 ILASM 组装的 MSIL。这样,您可以通过读取生成的代码轻松验证代码生成器的输出。一旦您确信您的代码生成器正在工作,请添加一个将使用Reflection.Emit或通用编译器基础结构的输出选项。

于 2011-11-09T23:48:01.067 回答