2014-12-02 137 views
3

我很好奇使用正则表达式解析C++代码。我迄今(使用红宝石)什么可以让我解压类的声明及其父类(如果有的话):Ruby正则表达式:解析C++类

/(struct|class)\s+([^{:\s]+)\s*[:]?([^{]+)\s*\{/ 

这里是Rubular的example。注意我可以正确捕获“声明”和“继承”部分。

我被卡住的地方在于捕获类本体。如果我用原来的正则表达式的以下扩展:

/(struct|class)\s+([^{:\s]+)\s*[:]?([^{]+)\s*\{[^}]*\};/ 

然后我可以捕捉类体只有它不包含任何大括号,因此任何类或函数的定义。 在这一点上,我尝试了很多东西,但没有一个让这个更好。例如,如果我在正则表达式中包含body可以包含大括号的事实,它将捕获第一个类声明,然后捕获所有后续的类,就好像它们是第一个类的body的一部分一样!

我错过了什么?

回答

1

group capturing可能帮助:

#     named v backref   v 
/(struct|class)\s+(?<match>{((\g<match>|[^{}]*))*})/m 

在这里,我们找到了一个下面struct/class声明匹配花括号。你可能会想要调整正则表达式,我发布了这个解决方案尽可能清晰。

0

什么我可以为您提供这样的:

(struct|class)\s+([^{:\s]+)\s*[:]?([^{]+)\{([^{}]|\{\g<4>\})*\}; 

哪里\g<4>是第四捕获组,这是([^{}]|\{\g<4>\})的递归应用。

将非正则语言与正则表达式匹配永远不会很漂亮。您可能需要考虑切换到正确的递归下降解析器,特别是如果您打算对刚刚捕获的内容执行某些操作。

4

正则表达式不是解析代码的推荐方法。

在编译或运行代码之前,大多数编译器和解释器都使用lexers和解析器将代码转换为abstract syntax tree

Ruby有几个词法宝石,比如this,你可以尝试并纳入你的项目。

+1

一般而言,这是正确的。然而,在某些情况下,正则表达式可能会“足够好”。例如。对一些代码进行快速的启发式分析。 – 2014-12-02 11:09:42

+1

@undur_gongor - 陈述OP的第一句话 - “我很好奇使用正则表达式来解析C++代码” - 这听起来像是一般,因为他们来:)。我同意,只要代码不是任意的(你确切地说来自哪里以及它是如何构造的),使用正则表达式来阅读HTML或代码的一些任务已经足够了 – 2014-12-02 11:13:31

+0

谢谢你。虽然你的回答看起来很有启发性,但我只是“玩”了解析C++代码的可能性(例如计算一个类中的方法数量等)。我会接受mudasobwa的回答,因为它帮助了我很多,但请记住您宝贵的建议;) – 2015-01-09 15:47:04