C语言中使用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); }