怎么样使用lex统计文本文件字符数?
我曾经在Linux上写的一个C程序,借助Lex做词法分析来同时统计N个文本文件的字符数,单词数和行数。让我觉得Lex确实挺有意思的。确实Lex的功能非常强大,用来做小巧的词法分析非常适合,也非常好用。这个程序参考了《Lex与Yacc》上的一个例子。
%{
unsignedintchar_count=0,word_count=0,line_count=0;
%}
%%
[^/t/n]+{word_count++;char_count+=yyleng;};
/n{char_count++;line_count++;};
.char_count++;
%%
char**file_list;
unsignedintcurrent_file=0;
unsignedinttotal_file=0;
unsignedinttotal_cc=0;
unsignedinttotal_wc=0;
unsignedinttotal_lc=0;
typedefstructfile_info{
unsignedintc;
unsignedintw;
unsignedintl;
char*name;
}INFO;
INFO**all;
intcreate_info(intnum)
{
INFO*tmp;
inti;
if(num<=0){
return-1;
}
all=(INFO**)malloc(sizeof(int*)*num);
for(i=0;i<num;i++){
tmp=(INFO*)malloc(sizeof(INFO));
tmp->c=0;
tmp->w=0;
tmp->l=0;
tmp->name=NULL;
all[i]=tmp;
}
return1;
}
intdelete_info(intnum)
{
inti;
if((all==(INFO**)0)||num<=0){
return-1;
}
for(i=0;i<num;i++){
free(all[i]);
}
free(all);
return1;
}
intset_info(intpos)
{
intlength=0;
if(pos<0){
return-1;
}
all[pos]->c=char_count;
all[pos]->w=word_count;
all[pos]->l=line_count;
all[pos]->name=file_list[pos];
return1;
}
intmain(intargc,char**argv)
{
FILE*file;
intposition=0;
inti;
file_list=argv+1;
total_file=argc-1;
current_file=0;
printf("--------------------------------------------------------------/n",
total_file);
if(argc>1){
if(create_info(total_file)==-1){
fprintf(stderr,"%s/n","Encounteraerrorwhenmallocmemory.");
exit(1);
}
}
if(argc==2){
file=fopen(argv[1],"r");
if(!file){
fprintf(stderr,"Couldnotopen%s./n",argv[1]);
delete_info(total_file);
exit(1);
}
yyin=file;
}
yywrap();
yylex();
if(argc>1){
total_cc+=char_count;
total_wc+=word_count;
total_lc+=line_count;
if(set_info(current_file-1)==-1){
fprintf(stderr,"%s/n","Encounteraerrorwhensetinformationto
INFO.");
delete_info(total_file);
exit(1);
}
for(i=0;i<total_file;i++){
printf("char:%-8luword:%-8luline:%-8lufilename:%s/n",all[i]->
c,all[i]->w,all[i]->l,file_list[i]);
}
printf("-----------------------total--------------------------------
/n");
printf("chars:%-8luwords:%-8lulines:%-8lufiles:%d/n",total_cc,tot
al_wc,total_lc,total_file);
}else{
printf("char:%-8luword:%-8luline:%-8lu/n",char_count,word_count,l
ine_count);
}
delete_info(total_file);
return0;
}
yywrap()
{
FILE*file=NULL;
if((current_file>0)&&(current_file<total_file)&&(total_file>1))
{
total_cc+=char_count;
total_wc+=word_count;
total_lc+=line_count;
if(set_info(current_file-1)==-1){
fprintf(stderr,"%s/n","Encounteraerrorwhensetinformationto
INFO.");
delete_info(total_file);
exit(1);
}
char_count=word_count=line_count=0;
fclose(yyin);
}
while((file_list[current_file]!=(char*)0)&&(current_file<total_fil
e)){
file=fopen(file_list[current_file++],"r");
if(!file){
fprintf(stderr,"couldnotopen%s.",file_list[current_file-1]
);
}else{
yyin=file;
break;
}
}
return(file?0:1);
}
本文地址:http://www.45fan.com/a/question/72058.html