2012-01-11 13 views
6

我需要浏览一个C/C++文件并提取类和方法列表以及它们在文件中的位置。如何解析/简单分析来自C#的C/C++代码以获取方法列表

是libclang最好的选择吗?或者这对于任务来说“太多”了?

查找配对括号会更好吗?

如果libclang是选择:有没有办法从c#中调用它?

谢谢!

+0

当然总是有一种方法可以使用C++/CLI从.NET调用C++代码。更便携的解决方案是提供一个围绕libclang的纯C包装(应该相当简单)。但是最好的解决方案是去找一个老版本的Clang,当它的好XML打印机仍然存在的时候。它从Clang中被移除真的很伤心。 – 2012-01-11 11:51:13

+0

另一种选择(有点生疏,但仍适用于大多数情况)是Elsa解析器与gcc预处理器的组合。 – 2012-01-11 11:53:41

+0

你不清楚你想要的答案的确切程度。您可以基于配对括号建立解决方案,90%的时间可能会产生简单的方法/类信息,另外10%会出现严重的错误。你打算如何处理结果? – 2012-01-11 12:00:20

回答

6

您可以考虑在许多平台上提供的ctags。输出很容易解析,并且您需要的信息十分丰富。

更多信息 对于你的问题,我不得不看看许多可用的选项,并在一小段后,我发现它。例如:

ctags -N -x --c-kinds=+p crowd.* 

产生这样的输出

CrowdSim   class  44 crowd.h   class CrowdSim 
CrowdSim   function  47 crowd.h   CrowdSim(const std::string& contentDir) : _contentDir(contentDir) {} 
Particle   function  35 crowd.h   Particle() 
Particle   struct  25 crowd.h   struct Particle 
_contentDir  member  56 crowd.h   std::string _contentDir; 
_crowd_H_  macro  18 crowd.h   #define _crowd_H_ 
_particles  member  57 crowd.h   std::vector<Particle> _particles; 
animTime   member  32 crowd.h   float animTime; 
chooseDestination function  24 crowd.cpp  void CrowdSim::chooseDestination(Particle &p) 
chooseDestination prototype 53 crowd.h   void chooseDestination(Particle &p); 
dx    member  28 crowd.h   float dx, dz; // Destination position 
dz    member  28 crowd.h   float dx, dz; // Destination position 
fx    member  29 crowd.h   float fx, fz; // Force on particle 
fz    member  29 crowd.h   float fx, fz; // Force on particle 
init    function  35 crowd.cpp  void CrowdSim::init() 
init    prototype 49 crowd.h   void init(); 
node    member  31 crowd.h   H3DNode node; 
ox    member  30 crowd.h   float ox, oz; // Orientation vector 
oz    member  30 crowd.h   float ox, oz; // Orientation vector 
px    member  27 crowd.h   float px, pz; // Current postition 
pz    member  27 crowd.h   float px, pz; // Current postition 
update   function  68 crowd.cpp  void CrowdSim::update(float fps) 
update   prototype 50 crowd.h   void update(float fps); 

(注:-x仅供方便用户检查)

+0

看起来这可能是最好的选择。它能够告诉你方法和它的身体在哪里吗?或者只在方法声明的地方?例如 – pablo 2012-01-11 12:09:21

+0

,对于函数CrowdSim :: update,是否可以知道它的正文在哪里? – pablo 2012-01-11 15:35:37

+0

是的,身体是在crowd.cpp行68 – CapelliC 2012-01-11 16:46:44

0

最好使用完整的解析器IMO。您可以使用ANTLR。它具有C/C++语法和C#解析器生成器。

+1

针对C/C++的ANTLR语法不如libclang AFAIK。 libclang为你完成这项工作,如果你想采用ANTLR方式,你必须修饰整个C/C++语法 – pablo 2012-01-11 11:35:42

+1

当有一个预处理器和一个复杂的特定于平台的include路径时,“完全解析器”还远远不够配置存在。 – 2012-01-11 11:52:25

+1

......我不认为ANTLR语法实际上是完整的。发行说明包含作者信息,说他没有真正完成它。 – 2012-01-11 12:16:10

1

不知道什么是最好的选择,但你也可以看看GCC-XMLMono/CXXI以及。后者在内部使用GCC-XML,但也为C++类定义提供了C#接口。

libclang是一个C库,因此应该可以从.NET通过P/Invoke使用,但在C#中重复所有必要的声明可能非常繁琐。

1

另一个角度是为Visual Studio创建扩展。

+0

这当然是一个选择,特别是在最新版本的新东西,但我想有一个VS独立的解决方案。 – pablo 2012-01-11 11:39:04

+0

啊,好的。好吧,我会留下来,如果有人发现它对他们的需求有用。 – justin 2012-01-11 11:44:41

4

要做好这些工作,你真正需要的东西,包括一个完整的C++解析器。

我们的DMS Software Reengineering Toolkit及其C++ Front End可用于此。它可以提供精确的实体声明,包括类型和它们的上下文(class/namespace/...)以及精确的文件位置。 DMS提供对所有这些信息的访问,作为一组AST和相关符号表;你建立自定义代码来导航到你想要的。

根据你的需要,你可能会发现你想要的信息很难用香草C#进行处理。类型信息的辉煌非常复杂,因为C++是一种复杂的语言。如果你想处理这些信息,你会想要“留在”DMS中,所有的机器都存在。如果你想要的只是文本字符串的名称和类型信息,你可以让DMS以这种形式打印这些数据;它有支持这些活动的标准库。中间答案是以XML格式导出数据; DMS提供对导出任意AST片段的直接支持,但只能间接支持将类型信息作为XML编写出来,但它不会很难定制。

编辑:(在回复OP评论的另一个答案)DMS可以提供​​关于方法签名和方法体的精确信息。它具有完整的AST和类型信息。

+0

听起来真棒!现在我需要关于定价的信息...我如何联系你? – pablo 2012-01-11 12:07:25

+0

查看我的电子邮件地址。当然,总是有网站本身: - } – 2012-01-11 12:19:02

+0

您的第一个链接已损坏:O(在此回复中) – pablo 2012-01-11 15:36:31

1

如果你想使用铿锵,我建议你看看this page。它演示了如何从文件中获取所有虚拟方法。一旦你理解了这个简单的例子,你可以创建更复杂的所谓匹配器。