flex工具学习二

参考书:flex与bsion

目标:读入文本并打印文本信息及行号,遇到文本中包含#include "file" 则读入嵌套文本并打印

创建text.l写入以下代码:

 1 %option noyywrap 
 2 %x IFILE
 3 
 4 %{
 5     struct bufstack {
 6         struct bufstack *prev;
 7         YY_BUFFER_STATE bs;
 8         int lineno;
 9         char *filename;
10         FILE *f;
11     } *curbs = 0;
12     char *curfilename;
13     int newfile(char *fn);
14     int popfile(void);
15 %}
16 
17 %%
18 [ \t]*#include[ \t]*[\"|<]     { 
19     BEGIN IFILE; 
20 }
21 
22 <IFILE>[^ \t\n\">]+ {
23     {
24         int c;
25         while((c = input()) && c != '\n');
26     }
27     yylineno++;
28     if(!newfile(yytext)) yyterminate();
29     BEGIN INITIAL;
30 }
31                         
32 <IFILE>.|\n {
33     fprintf(stderr, "%4d bad include line\n", yylineno);
34 }
35 
36 <<EOF>> { if(!popfile()) yyterminate(); }
37 
38 ^. { fprintf(yyout, "%4d %s", yylineno, yytext); }
39 
40 \n { ECHO; yylineno++; }
41 %%
42 
43 main(int argc, char **argv)
44 {
45     if(argc<2) {
46         fprintf(stderr, "need filename\n");
47         return 1;
48     }
49     if(newfile(argv[1])) yylex();
50 }
51 
52 int newfile(char *fn)
53 {
54     FILE *f = fopen(fn, "r");
55     struct bufstack *bs = malloc(sizeof(struct bufstack));
56     if(!f){
57         perror(fn); 
58         return 0;
59     }
60     if(!bs){
61         perror("malloc");
62         exit(1);
63     }
64     if(curbs) curbs->lineno = yylineno; 
65     bs->prev = curbs;
66     bs->bs = yy_create_buffer(f, YY_BUF_SIZE);
67     bs->f = f;
68     bs->filename = fn;
69     yy_switch_to_buffer(bs->bs);
70     curbs = bs;
71     yylineno = 1;
72     curfilename = fn;
73     return 1;
74 }
75 
76 int popfile(void)
77 {
78     struct bufstack *bs = curbs;
79     struct bufstack *prevbs;
80     if(!bs) return 0;
81     fclose(bs->f);
82     yy_delete_buffer(bs->bs);
83     prevbs = bs->prev;
84     free(bs);
85     if(!prevbs) return 0;
86     yy_switch_to_buffer(prevbs->bs);
87     curbs = prevbs;
88     yylineno = curbs->lineno;
89     curfilename = curbs->filename;
90     return 1;
91 }

 

 

编译代码:

flex text.l
gcc -o test lex.yy.c -lfl

创建test.txt、test2.txt,里面内容分别为:

#include "test2.txt"
local i = 1;
local x = 2

测试:

./test test.txt

输出:

   1 local x = 2
   2 local i = 1;

 源码分析:

第1行的%option 为flex选项,noyywrap表示不调用yywrap()函数。yywrap()函数可以用于扫描多个源文件。

其它选项有:

%option yylineno // 自动使用yylineno记录符号所在行号

%option case-insensitive // 匹配时自动忽略大小写,比如[a-z]也可以匹配A-Z字符,但不改变yytext里字符的大小写。

%option debug // 扫描器在debug模式下运行

第2行的%IFILE定义一个状态,用户可以定义多个状态。flex本身有一个默认状态INITIAL,规则区的正则表达式前加入<IFILE>表示该正则表达式只在IFILE状态时启用后面的处理例程。没有加状态的正则表达式则是在默认状态下匹配。

源代码第36行的<<EOF>>是指扫描任意源文件结束时调用后面例程:将当前文本出栈

bufstack是一个栈结构,当扫描器匹配到#include时,则进入IFILE状态,接下来读取紧跟的文件名,然后调用newfile记录当件文本当前扫描位置并入栈,读取新的文本,然后进入默认状态。在默认状态下匹配\n ^.等规则。ECHO为回车。

 

转载于:https://www.cnblogs.com/liumu1209/p/5664751.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值