从.Net程序集中获取AST,无需源代码(IL代码)

NKn*_*rer 5 il abstract-syntax-tree mono.cecil roslyn nrefactory

我想分析.Net程序集与C#,VB.NET或其他任何语言无关.
我知道Roslyn和NRefactory,但他们似乎只在C#源代码级别上工作?CodePlex上
还有" 通用编译器基础设施:代码模型和AST API "项目,该项目声称"支持一种表示与语言无关的结构化形式的代码块的分层对象模型",它完全符合我的要求.
但是,我无法找到任何有用的文档或实际执行此操作的代码.
有什么建议如何存档?
Mono.Cecil可以做点什么吗?

小智 0

据我所知,不可能从二进制(没有源)构建 AST,因为 AST 本身是由解析器生成的,作为源编译过程的一部分。Mono.Cecil 不会有帮助,因为你只能用它们修改操作码/元数据,而不能分析程序集。

但由于它是 .NET,因此您可以在 ildasm 的帮助下从 dll 转储 IL 代码。然后,您可以将生成的源传递给任何连接了 CIL 字典的解析器,并从解析器获取 AST。问题是,据我所知,解析器只有一种公开可用的 CIL 语法,因此您实际上别无选择。而且 ECMA-355 足够大,因此编写自己的语法是个坏主意。所以我只能建议你一种解决方案:

  1. 将程序集传递给 ildasm.exe 以获取 CIL。
  2. 然后将 CIL 传递给ANTLR v3解析器,并连接CIL 语法(注意它有点过时 - 语法创建于 2004 年,最新的 CIL 规范是 2006 年,但 CIL 并没有真正改变太多)
  3. 之后就可以自由访问ANTLR生成的AST了

请注意,您将需要 ANTLR v3 而不是 v4,因为语法是为第三版本编写的,并且如果不充分了解 ANTLR 语法,则几乎不可能将其移植到 v4。

另外,您还可以尝试在 github(CoreCLR 的一部分)上查看新的 Microsoft ryujit编译器源代码 - 我不确定它是否有帮助,但理论上它必须包含 CIL 语法和解析器实现,因为它与 CIL 代码一起使用。但它是用 CPP 编写的,拥有庞大的代码库,并且由于处于积极的开发阶段而缺乏文档,因此可能更容易坚持使用 ANTLR。