当谈到正则表达式时,我在学习曲线上的某个地方,我需要使用它们来自动修改一堆C头中的函数原型.有没有人知道一个不错的正则表达式来查找C头中的任何和所有函数原型,同时排除其他所有内容?
编辑:最初不清楚的三件事:
我不关心C++,只关心C.这意味着没有模板等担心.
该解决方案必须使用typedef和structs,不仅限于基本的C类型.
这是一种一次性的事情.它不需要漂亮.只要它有效,我不在乎它有多大,但我不想要一个复杂,难以实施的解决方案.
Quassnoi.. 17
您可以使用ANSI C yacc/lex语法实现解析器.
您可以使用ANSI C yacc/lex语法实现解析器.
要正确执行此操作,您需要根据C语言语法进行解析.但是,如果这只是针对C语言而且仅针对头文件,也许你可以采取一些快捷方式,并且没有完全成熟的BNF.
^ \s* (unsigned|signed)? \s+ (void|int|char|short|long|float|double) # return type \s+ (\w+) # function name \s* \( [^)]* # args - total cop out \) \s* ;
这绝不是正确的,需要工作.但如果你愿意付出一些努力并改进它,它可能代表一个起点.它可以被跨越行,函数指针参数,MACROS和许多其他东西的函数定义所打破.
请注意,BNF 可以转换为正则表达式.它将是一个庞大而复杂的正则表达式,但它是可行的.
对于一次性练习,您可能最好从简单开始并查看您必须扫描的代码.选择三个最差的标题,生成一个正则表达式或一系列正则表达式来完成这项工作.您必须决定是否以及如何处理包含函数声明的注释(实际上,包含注释的函数声明).处理:
extern void (*function(int, void (*)(int)))(int);
(这可能是标准C函数signal()
)因为嵌套括号而在正则表达式中很难.如果你没有任何这样的函数原型,那么花时间研究如何处理它们就浪费了时间.类似的注释适用于指向多维数组的指针.您可能会有简约的风格习惯来简化您的生活.您不能使用C99(C++)注释; 你不需要围绕它们编码.你可能不会在一行中放置多个声明,无论是否有共同类型 - 所以你不必处理它.
extern int func1(int), func2(double); double func3(int); // Nasty!
假设您的代码格式化为
type name function_name(variables **here, variables &here) { code }
这是Powershell的单线程:
ls *.c, *.h | sls "^(\w+( )?){2,}\([^!@#$+%^]+?\)"
返回结果如下:
... common.h:37:float max(float a, float b) common.h:42:float fclamp(float val, float fmin, float fmax) common.h:51:float lerp(float a, float b, float b_interp) common.h:60:float scale(float val, float valmin, float valmax, float min, float max) complex.h:3:typedef struct complex { complex.h:8:double complexabs(complex in) complex.h:13:void complexmult(complex *out, complex a, complex b) complex.h:20:void complexadd(complex *out, complex a, complex b) complex.h:27:int mandlebrot(complex c, int i) ...
要了解刚才没有文件具体的行中,添加format-table -property line
(或简称ft -p line
):
ls *.c, *.h | sls "^(\w+( )?){2,}\([^!@#$+%^]+?\)" | format-table -p line
哪个回报:
Line ---- void render(SDL_Surface *screen) void saveframe(SDL_Surface *screen) int handleevents(SDL_Surface *screen) int WinMain(/*int argc, char* args[]*/) void printscreen(SDL_Surface *screen, unsigned int exclude) void testsection(char name[]) void sdltests(SDL_Surface *screen, SDL_Window *window, int width, int height) int WinMain(/*int argc, char *argv[]*/) int random(int min, int max) { int main(int argc, char *argv[])
奖励:正则表达式的解释:
^(\w+(\s+)?){2,}\([^!@#$+%^]+?\) ^ Start of a line ( ){2,} Create atom to appear to or more times (as many as possible) \w+(\s+)? A group of word characters followed by an optional space \( \) Literal parenthesis containing [^!@#$+%^]+? A group of 0 or more characters that AREN'T in “!@#$+%^”