zoukankan      html  css  js  c++  java
  • 通过词法分析实现的指出C程序中包含的头文件

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

     1 /*源代码:ic.l*/
     2 
     3 /*定义文件预处理指令文件名起始状态*/
     4 %x IFILE
     5 
     6 %%
     7 ^"#"[ 	]*include[ 	]*["<]        {BEGIN IFILE;}   /*#include的多种表达方式的正则表达式*/
     8 <IFILE>[^	
    ">]+                    {/*进入文件名状态*/ 
     9                                         printf("%d:%s
    ",yylineno++,yytext);/*输出行号和文件名,yylineno是flex定义的全局变量,yytext是当前
    10                                                                              输入流*/
    11                                         {
    12                                             char c;
    13                                             /*去处行尾可能的换行符*/
    14                                             while((c=input()) && c!='
    ');
    15                                         }        
    16 /*回复至初始状态*/
    17                                         BEGIN INITIAL;
    18                                     }/*下面的RE用于处理行首换行(空行)和换行的情况,增加yylineno的值*/
    19 ^
                                        {++yylineno;}
    20 
                                        {++yylineno;}
    21 .                                    {/*直接忽略*/}
    22 %%
    23 
    24 int main(int argc,char *argv[])
    25 {
    26     /*命令行读取文件名参数*/
    27     if (argc<2)
    28     {
    29         fprintf(stderr,"Usage:%s filename
    ",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("	%s:
    ",argv[i]);
    47         yylex();/*开始词法分析*/
    48         printf("
    ");
    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

    可见已经达到了目的。

  • 相关阅读:
    【POJ3069】Saruman's Army
    【POJ2453】An Easy Problem
    【POJ2386】Lake Counting
    【POJ2251】Dungeon Master
    【POJ1664】放苹果
    【基础】枚举学习笔记
    算法时空复杂度【OI缩水版】
    【POJ2018】Best Cow Fences
    【POJ3889】Fractal Streets(分形图)
    【BZOJ2296】随机种子(构造)
  • 原文地址:https://www.cnblogs.com/Chaobs/p/4496144.html
Copyright © 2011-2022 走看看