Ruby正则表达式:解析C++类

3

我想了解使用正则表达式解析C ++代码的方法。目前我已经用Ruby编写了一些代码,可以提取类声明及其父类(如果有的话):

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

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

我卡住的地方是在于捕获类主体。如果我使用以下扩展原始正则表达式:

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

如果类的主体不包含任何大括号,那么我可以捕获该类的主体内容,但如果包含大括号,则无法捕获该类或函数定义。目前为止,我已经尝试了许多方法,但都没有取得更好的效果。

例如,如果我在正则表达式中包含主体可以包含大括号这一事实,它将捕获第一个类声明,然后将所有后续类作为第一个类的主体的一部分捕获!

我错过了什么?

3个回答

3

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

大多数编译器和解释器在编译或运行代码之前使用词法分析器和解析器将代码转换为抽象语法树

Ruby有一些词法分析器宝石,比如this,您可以尝试并将其合并到您的项目中。


1
一般来说,这是正确的。然而,在某些情况下,正则表达式可能只是“足够好”。例如,用于对某些代码进行快速启发式分析。 - undur_gongor
1
@undur_gongor - 引用OP的第一句话 - "我很好奇如何使用正则表达式解析C++代码" - 这听起来非常普遍 :). 我同意对于某些任务,使用正则表达式读取HTML或代码是足够的,只要代码不是任意的(你确切地知道它来自哪里,以及它是如何构建的)。 - Uri Agassi
谢谢Uri。虽然你的答案很有启发性,但我只是在“玩弄”解析C++代码的可能性(例如计算类中方法的数量等)。我会接受mudasobwa的答案,因为它对我帮助很大,但我会记住你宝贵的建议 ;) - Яois
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Яois

1

这个捕获组可能会有帮助:

#                   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>\})

使用正则表达式匹配非规则语言从来不是什么美观的事情。如果你打算对刚刚捕获的内容进行一些操作,你可能会考虑转换到适当的递归下降解析器。


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