flex
是用来生成程序的工具(最初用来生成编译器),它所生成的程序能够处理结构化输入
。
基础:了解正则表达式
和编译原理
相关知识(词法分析器、语法分析器、自动机等)。
一个简单的Flex程序:
这个程序实现字数统计
功能,这个程序可以读入一个文件,然后报告这个文件的行数
、单词数
和字符数
。
$ vim WordCount.l
用vim创建文件拓展名为l
或lt
的文件,输入以下内容:
%{
int chars = 0;
int words = 0;
int lines = 0;
%}
%%
[a-zA-Z]+ { words++; chars += strlen(yytext); }
\n { chars++; lines++; }
. { chars++; }
%%
main(int argc, char **argv)
{
yylex();
printf("%8d%8d%8d\n", lines, words, chars);
}
flex程序包含三个部分,各部分之间通过仅有%%的行来分割,三个部分介绍如下:
(1)声明部分
%{
和%}
之间的代码会被原样照抄到生成的C文件的开头部分。
在这个例子中,它只是用来设定行数、单词数和字符数的变量。
(2)规则部分
模式处在一行的开头
处,接着是模式匹配
时所需要执行的C代码
(这儿的C代码是用{}
括住的一或多行语句。)
模式必须在行首
出现。(flex认为空白开始的行都是代码)
(3)C代码部分
末尾的C代码是我们的主程序,它负责调用flex提供的词法分析例程yylex(),并输出结果。
接下来将它编译:
$ flex -o WordCount.yy.c WordCount.lt
$ cc -o WordCount WordCount.yy.c -lfl
$ ls -l /usr/bin/cc
lrwxrwxrwx 1 root root 3 11月 29 19:48 /usr/bin/cc -> gcc
执行的方式有许多(第一种直接输入,后两种将文件作为标准输入):
$ ./WordCount
Hello World~
Yeah
2 3 18
# 或者
$ ./WordCount < file
1 1 10
# 或者
$ cat file | ./WordCount
1 1 10
真正的wc(字符统计)程序与上述定义有所不同:没有空白字符的字符串。
所以需略作修改:
[^\t\n\r\f\v ]+ { words++; chars += strlen(yytext); }