通过词法分析实现的指出C程序中包含的头文件

  在阅读有些程序的源码时,很希望能够马上弄清楚源码中到底包含了哪些头文件,以确定是否需要为了特殊的函数而手动加入#include。借助flex的词法分析实现了这一功能,本质上就是对正则表达式的匹配。注意这个程序不能够处理包含嵌套的情形(也就是说不能指出包含文件包含了哪些文件),感兴趣的可以通过栈来实现。源码如下:

 1 /*源代码:ic.l*/
 2 
 3 /*定义文件预处理指令文件名起始状态*/
 4 %x IFILE
 5 
 6 %%
 7 ^"#"[ \t]*include[ \t]*[\"<]        {BEGIN IFILE;}   /*#include的多种表达方式的正则表达式*/
 8 <IFILE>[^\t\n\">]+                    {/*进入文件名状态*/ 
 9                                         printf("%d:%s\n",yylineno++,yytext);/*输出行号和文件名,yylineno是flex定义的全局变量,yytext是当前
10                                                                              输入流*/
11                                         {
12                                             char c;
13                                             /*去处行尾可能的换行符*/
14                                             while((c=input()) && c!='\n');
15                                         }        
16 /*回复至初始状态*/
17                                         BEGIN INITIAL;
18                                     }/*下面的RE用于处理行首换行(空行)和换行的情况,增加yylineno的值*/
19 ^\n                                    {++yylineno;}
20 \n                                    {++yylineno;}
21 .                                    {/*直接忽略*/}
22 %%
23 
24 int main(int argc,char *argv[])
25 {
26     /*命令行读取文件名参数*/
27     if (argc<2)
28     {
29         fprintf(stderr,"Usage:%s filename\n",argv[0]);    
30     }
31     FILE *f;
32     int i;
33     /*循环打开文件*/
34     for (i=1;i<argc;++i)
35     {
36         f=fopen(argv[i],"r");    
37         if (!f)
38         {
39             perror(argv[i]);
40             exit(EXIT_FAILURE);
41         }
42         /*重新开始输入*/
43         yyrestart(f);
44         yylineno=1;
45         /*开始新的文件,函数初始化为1*/
46         printf("\t%s:\n",argv[i]);
47         yylex();/*开始词法分析*/
48         printf("\n");
49         fclose(f);
50     }
51     return 0;
52 }

编译指令:

1 $flex -o ic.lex.c ic.l
2 $gcc -o ic ic.lex.c -lfl

示范运行结果:

 1 $ ./ic test_inc.c inc_count.lex.c 
 2     test_inc.c:
 3 1:stdio.h
 4 
 5     inc_count.lex.c:
 6 20:stdio.h
 7 21:string.h
 8 22:errno.h
 9 23:stdlib.h
10 43:inttypes.h
11 487:unistd.h

可见已经达到了目的。

posted @ 2015-05-12 00:09  Chaobs  阅读(354)  评论(0编辑  收藏