寻找一个C#代码解析器

9
我正在寻找一组类(最好在.net框架中),可以解析C#代码并返回带参数的函数列表,具有方法、属性等的类。理想情况下,它应该提供构建自己的智能感知所需的所有内容。
我有一种感觉,.net框架中应该有这样的东西,考虑到它们提供的所有反射内容,但如果没有,那么开源替代品就足够了。
我试图构建的基本上是像Snippet Compiler这样的东西,但有一个小变化。我试图首先获取代码DOM。
我尝试通过谷歌搜索,但不确定这个术语的正确名称,所以没有结果。
编辑:由于我正在寻找用于类似智能感知的处理,实际编译代码将不起作用,因为它很可能是不完整的。抱歉,我应该首先提到这一点。

它是否必须与非完整代码或带有错误的代码(即无法使用普通编译器编译的代码)一起工作?这通常是 IntelliSense 风格解析器的要求。 - Dean Harding
是的,它应该可以在不完整的代码上工作。我正在寻找即时的东西。 - Blindy
6个回答

5

.NET的CodeDom命名空间提供了代码语言解析器的基本API,但它们没有实现。Visual Studio通过其自己的语言服务来完成这项工作。这些服务在可再发行框架中不可用。

你可以...

  1. 编译代码,然后在生成的程序集上使用反射
  2. 查看像Mono C#编译器这样的东西,它创建这些语法树。它可能不像CodeDom那样是一个高级API,但也许你可以使用它。

可能有CodePlex上的一些类似的东西或类似的网站。

更新
请参阅此相关帖子。C#的解析器


+1 用于更新 - 它包含可行的解决方案 - John K

2
如果您需要在不完整的代码或有错误的代码上工作,那么我认为您基本上是自己一个人(也就是说,您将无法使用CSharpCodeCompiler类或类似的东西)。像ReSharper这样的工具会自己进行解析,但那是专有的。您可能可以从Mono编译器开始,但根据我的经验,编写一个适用于不完整代码的解析器与编写一个仅应在不完整代码上输出错误的解析器是完全不同的事情。如果您只需要类和方法的名称(元数据),那么您可能可以“手动”解析,但我想这取决于您需要多准确的结果。

是的,我开始考虑手动解析它。不过不确定使用泛型会有多难。 - Blindy

2

Mono项目GMCS编译器包含一个相当可重用的C#4.0解析器。而且,编写适合自己特定需求的解析器相对容易。例如,你可以重用这个:http://antlrcsharp.codeplex.com/


这些现成的解析器的问题在于它们无法处理不完整(因此无效)的代码。它们的目的是创建足够详细的语法树以生成代码,而不是为智能感知提供数据。 - Blindy
没错。但是,由于它们是可重用的,人们可以轻松地进行调整。ANTLR 可用于部分解析。但当然最通用的选项是 PEG,因此如果您可以获得一个适用于 .NET 的体面的 PEG 实现,并且您可以移植现有的 ANTLR 解析器,那么您将获得一个快速且易于使用的通用解决方案。例如,来自 http://www.meta-alternative.net/mbase.html 的 Packrat 解析器能够从任何通用语法中生成文本编辑器的语法高亮模式,并且它能够很好地处理不完整或无效的输入。 - SK-logic

1

你尝试过使用Microsoft.CSharp.CSharpCodeProvider类吗?这是一个完整的C#代码提供程序,支持CodeDom。您只需要在文本流上调用.Parse(),就可以获得CodeCompileUnit。

var codeStream = new StringReader(code);
var codeProvider = new CSharpCodeProvider();

var compileUnit = codeProvider.Parse(codeStream);

// compileUnit contains your code dom

嗯,既然上面的方法不可行(我刚测试过),那么以下文章可能会引起兴趣。我很久以前就将其加为书签,所以我相信它只支持C# 2.0,但仍可能值得一试:

直接从C#或VB.NET生成代码DOM


这个功能没有被任何代码 DOM 提供程序实现,会抛出一个 NotImplementedException 异常。 - Josh
@Josh:看来你是对的。我刚试了一下,确实失败了。太遗憾了。 - jrista

1

请查看Microsoft.CSharp命名空间中的CSharpCodeCompiler。您可以使用CSharpCodeCompiler进行编译,并使用CompilerResults.CompiledAssembly访问结果程序集。通过该程序集,您将能够获取类型,并通过反射获取所有属性和方法信息。

性能将相当平均,因为每当更改内容时,您都需要编译所有源代码。我不知道是否有任何方法可以让您增量编译代码片段。


1

对于Blindy来说可能有点晚了,但我最近发布了一个C#解析器,非常适合处理代码片段并保留注释: C# Parser and CodeDOM

它可以处理C# 4.0版本和新的“async”特性。虽然是商业软件,但价格仅是其他商业编译器的一小部分。

我真的认为很少有人意识到解析C#变得多么困难,特别是如果您需要正确解析符号引用(通常需要),除非您只是在进行格式化。尝试阅读并完全理解500多页语言规范中的类型推断部分。然后,沉思这个事实:规范实际上并不完全正确(如Eric Lippert本人所提到的)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接