通过词法分析实现的指出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

可见已经达到了目的。

时间: 2024-10-25 22:48:35

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

前端技术:HTML---Head标签中包含的头文件标签,body标签包含的内部标签

1.Head标签中包含的 头文件标签的作用: (1)title标签:定义网页的标题. (2)meta标签:一般用于定义页面的特殊信息,例如页面的关键字.页面描述等 (3)link标签:用于引入外部样式文件(CSS 文件). (4)style标签:用于定义元素的CSS样式. (5)script标签:用于定义页面的JavaScript代码,或者引入外部JavaScript文件. meta标签包含的属性 (1)charset属性:字符集编码方式: ASCII:数字.英文字母.字符进行编码 GB2312

Makefile中自动生成头文件依赖

为什么需要自动生成头文件依赖? 编译单个源文件时,需要获取文件中包含的头文件的信息,但是一般的Makefile不会在规则中明确写明文件依赖的头文件,所以单独修改头文件后,不会导致包含头文件的源文件重新编译.如果每次手动的添加头文件依赖,又会非常的繁琐,所以需要一种自动生成依赖的方法. 编译器中神奇的选项 使用$(CC)中的-M命令就可以完美的解决问题,因为-M选项可以将源文件依赖的所有头文件,自动解析出来. 例子:在当前路径下,编辑test.c和test.h文件,test.c如下所示,test.

搜索文件或目录中包含字符串的文件 java小程序

package com.ruishenh.spring.test; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Enumeration; import java.

Spring MVC程序中得到静态资源文件css,js,图片文件的路径问题总结

上一篇 | 下一篇 Spring MVC程序中得到静态资源文件css,js,图片 文件的路径 用 Spring MVC 开发应用程序,对于初学者有一个很头疼的问题,那就是程序数据都已经查询出来了,但界面样式仍然十分丑陋,加载不了 css,js,图片等资源文件.当你在浏览器上直接输入某个css文件的路径时,直接得到404错误,而路径肯定没有错,其原因就在于在web.xml 中配置了类似如下的 spring servlet: 程序代码 <servlet>    <servlet-name&g

苹果开发者应当在应用程序中包含隐私策略(附隐私策略模板)

前几日苹果在其开发者中心重申开发者应当在应用程序中包含隐私策略.为了确保用户理解应用如何使用他们的数据,开发者在以下两种情况中必须在iTunes的Privacy Policy URL字段提供一个链接: 1.开发者所在国家法律要求提供. 2.满足以下前提之一: 使用用户或者设备数据 提供账户注册程 访问用户现有的账号 使用HomeKit或者HealthKit框架 集成Apple Pay 包含键盘扩展 包含自动更新订阅和免费订阅 应用属于儿童类别 附隐私政策模板: 隐私政策  Poposoft尊重并

vscode中c/c++头文件引用找不到飘红

正在进行 GTK 学习, 但是在 vscode GTK 的头文件找不到(头文件引用底下飘红, 逼死强迫症), 影响敲字键入速度. 解决一下该问题-- vscode中c/c++头文件引用找不到(#include errors detected) 花了我几十分钟, 可以说相当智障了... 在 c_cpp_properties.json(就是c/c++的配置文件)里面添加 "includePath": 开始提示 glib.h 找不到, 我加上了 "/usr/include/glib

利用vs2010制作C语言 dll文件,并在其它程序中调用该dll文件

一.为什么需要dll 代码复用是提高软件开发 效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架, 如ATL.MFC等,它们都以源代码的形式发布.由于这种复用是“源码级别”的,源代码完全暴露给了程序员,因而称之为“白盒复用”.“白盒复用”的缺点 比较多,总结起来有4点. 暴露了源代码: 容易与程序员的“普通”代码发生命名冲突: 多份拷贝,造成存储浪费: 更新功能模块比较困难. 实际上,以上4点概括起来就是

C/C++中如何写头文件

在C语言的学习过程中,我们一般把所有的代码写在一个文件中.随着自身水平的提高,我们发现代码越写越长,代码行数越来越多,把一个工程的所有代码写在一个文件中让人看起开非常吃力.于是我们开始想把代码中的函数归类,同一类放在同一个文件中当中,那么如何实现将一个工程中的代码放到不同文件中呢?这就需要写头文件了.下面的简单列子将让你学会如何写头文件.你也可以点击这里下载源代码自己研究. 假设我们需要定义一些与栈有关的函数,主程序需要调用这些函数. 首先,我们在同一文件夹中新建3个文件(要包含不同的自定义头文

C++中 &lt;iso646.h&gt;头文件

1 #include<iostream> 2 #include<iso646.h> 3 using namespace std; 4 int main(){ 5 int i = 5,j = 6,k=7; 6 if(i<j and j<k)cout<<"i<j and j<k"<<endl; 7 if(i<j or j<k)cout<<"i<j or j<k"&