从扫描范围开始。您需要在浏览文件时计算左大括号 { 和右大括号 },以便您知道您在哪个范围内。您还需要在扫描文件时解析 // 和 /* ... */ ,因此您可以判断某些内容何时出现在注释中,而不是真正的代码。还有#if,但你必须编译代码才能知道如何解释这些。
然后,您需要在一些范围开括号之前立即解析文本以找出它们是什么。您的函数可能在全局范围、类范围或命名空间范围内,因此您必须能够解析命名空间和类以识别您正在查看的范围类型。您通常可以使用相当简单的解析(大多数程序员使用类似的样式 - 例如,很少有人在“class Fred”和它的左大括号之间放置空行。但他们可能会写“class Fred {”。那里也有可能他们会在线路上添加额外的垃圾 - 例如'模板类__DECLSPEC MYWEIRDMACRO Fred {'。但是,您可以使用一个非常简单的“该行是否包含两边都有空格的'class'这个词?在大多数情况下都可以使用的启发式方法。
好的,所以您现在知道您在一个命名空间和一个类中,并且您找到了一个新的开放范围。它是一种方法吗?
方法的主要识别特征是:
- 返回类型。这可以是任何字符序列,也可以是许多标记(“__DLLEXPORT const unsigned myInt32typedef * &”)。除非你编译整个项目,否则你没有机会。
- 函数名。单个令牌(但要注意“operator =”等)
- 一对包含零个或多个参数或“void”的括号。这是你最好的线索。
- 函数声明将不包括某些在许多范围之前的保留字(例如枚举、类、结构等)。并且它可能会使用一些您不能绊倒的保留字(模板、常量等)。
So you could search up for a blank line, or a line ending in ; { or } that indicates the end of the previous statement/scope. Then grab all the text between that point and the open brace of your scope. Then extract a list of tokens, and try to match the parameter-list brackets. Check that none of the tokens are reserved words (enum, struct, class etc).
This will give you a "reasonable degree of confidence" that you have a method. You don't need much parsing to get a pretty high degree of accuracy. You could spend a lot of time finding all the special cases that confuse your "parser", but if you are working on a reasonably consistent code-base (i.e. just your own company's code) then you'll probably be able to identify all the methods in the code fairly easily.