当前位置:  开发笔记 > 编程语言 > 正文

正则表达式拉出C函数原型声明?

如何解决《正则表达式拉出C函数原型声明?》经验,为你挑选了4个好方法。

当谈到正则表达式时,我在学习曲线上的某个地方,我需要使用它们来自动修改一堆C头中的函数原型.有没有人知道一个不错的正则表达式来查找C头中的任何和所有函数原型,同时排除其他所有内容?

编辑:最初不清楚的三件事:

    关心C++,只关心C.这意味着没有模板等担心.

    该解决方案必须使用typedef和structs,不仅限于基本的C类型.

    这是一种一次性的事情.它不需要漂亮.只要它有效,我不在乎它有多大,但我不想要一个复杂,难以实施的解决方案.

Quassnoi.. 17

您可以使用ANSI C yacc/lex语法实现解析器.



1> Quassnoi..:

您可以使用ANSI C yacc/lex语法实现解析器.


我不能重复它.正则表达式不能替代解析器.+1.

2> Paul Becking..:

要正确执行此操作,您需要根据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 可以转换为正则表达式.它将是一个庞大而复杂的正则表达式,但它是可行的.


真实 - 仁慈地说,他们处理C而不是C++.

3> Jonathan Lef..:

对于一次性练习,您可能最好从简单开始并查看您必须扫描的代码.选择三个最差的标题,生成一个正则表达式或一系列正则表达式来完成这项工作.您必须决定是否以及如何处理包含函数声明的注释(实际上,包含注释的函数声明).处理:

extern void (*function(int, void (*)(int)))(int);

(这可能是标准C函数signal())因为嵌套括号而在正则表达式中很难.如果你没有任何这样的函数原型,那么花时间研究如何处理它们就浪费了时间.类似的注释适用于指向多维数组的指针.您可能会有简约的风格习惯来简化您的生活.您不能使用C99(C++)注释; 你不需要围绕它们编码.你可能不会在一行中放置多个声明,无论是否有共同类型 - 所以你不必处理它.

extern int func1(int), func2(double); double func3(int);  // Nasty!



4> 9999years..:

假设您的代码格式化为

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 “!@#$+%^”

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有