lex可以辅助生成词法分析程序,我们要做的仅仅是写好相应的正则表达式。
简介:http://www.ibm.com/developerworks/cn/linux/sdk/lex/
实例:找出一个文件中的函数并打印出来
文件tt.lex如下:
%{
#include <stdio.h>
int cnt=0,line=0;
void FindFunc(char *str);
void DoNothing();
%}
chars [a-zA-Z\_\'\"\.]
words {chars}+
identifier [a-zA-Z\_]+[a-zA-Z0-9_]*
ret_type [a-zA-Z\_]+[a-zA-Z0-9_]*
blanks [ \t]+
blanks_opt [ \t]*
func_name [a-zA-Z\_]+[a-zA-Z0-9_]*
left_bracket {blanks_opt}\(
params (({blanks_opt}[a-zA-Z0-9_]+[ \t]+[a-zA-Z \t\_\*&\[\],]*)|({blanks_opt}))
right_bracket {blanks_opt}\)
semicolon [;]?
%%
{ret_type}{blanks}{func_name}{left_bracket}{params}{right_bracket}{semicolon} FindFunc(yytext);cnt++;
. DoNothing();
\n DoNothing();line++;
%%
void main(int argc, char *argv[])
{
yyin = fopen(argv[1], "r");
if (yyin < 0)
{
printf("Open file %s failed\n", argv[1]);
return ;
}
yylex();
printf("%d functions found.\n", cnt);
}
void FindFunc(char *str)
{
printf("%3d %s\n", line+1, str);
}
void DoNothing()
{
}
一个lex source file 由三部分组成。
%{
C变量、函数声明
%}
lex标记声明
%%
lex的模式匹配规则
%%
C代码
表达式分析
ret_type [a-zA-Z\_]+[a-zA-Z0-9_]*
blanks [ \t]+
blanks_opt [ \t]*
func_name [a-zA-Z\_]+[a-zA-Z0-9_]*
left_bracket {blanks_opt}\(
param_list (({blanks_opt}[a-zA-Z0-9_]+[ \t]+[a-zA-Z \t\_\*&\[\],]*)|({blanks_opt}))
right_bracket {blanks_opt}\)
semicolon [;]?
/* return type */
ret_type [a-zA-Z\_]+[a-zA-Z0-9_]*
/*one or some blank or tab */
blanks [ \t]+
/* zero or some blank or tab */
blanks_opt [ \t]*
/* function name */
func_name [a-zA-Z\_]+[a-zA-Z0-9_]*
/* left bracket: may have blanks between function name and left bracket */
left_bracket {blanks_opt}\(
/* parameters: NULL or one identifier is need
params (({blanks_opt}[a-zA-Z0-9_]+[ \t]+[a-zA-Z \t\_\*&\[\],]*)|({blanks_opt}))
执行lex tt.lex会生成lex.yy.c文件
gcc -o temp lex.yy.c 生成程序temp
出现错误 undefined reference to `yywrap' 解决方法:gcc -o temp lex.yy.c -lfl
./temp inputfile.c
打印出inputfile.c中的函数。
把输入文件中的小写字母转换成大写字母:
%{
#include <stdio.h>
int cnt=0;
%}
chars [a-zA-Z/_/'/"/.]
lowcase [a-z]
words {chars}+
%%
{lowcase} {yytext[0] = toupper(yytext[0]);cnt++; fprintf(yyout,"%c",yytext[0]);}
. fprintf(yyout, "%c",yytext[0]);
/n fprintf(yyout, "%c",yytext[0]);
%%
void main(int argc, char *argv[])
{
yyin = fopen(argv[1], "r");
if (yyin < 0)
{
printf("Open file %s failed/n", argv[1]);
return ;
}
yyout = fopen(argv[2], "w");
if (yyout < 0)
{
printf("Open file %s failed/n", argv[2]);
fclose(yyin);
return;
}
yylex();
printf("%d lowcases found./n", cnt);
fclose(yyin);
fclose(yyout);
}
Note: 以上程序中 "\" 都被转成了 “/” 。直接从windows粘贴过来的缘故。