仿照上一篇的方法写了个识别函数的程序,可以识别出函数名和起始终止行数。
状态表:
e是error,代码能编译过的话这种情况是不会出现的,程序中用0代替了。
7状态在函数体内,计数{和},当计数到0时,说明遇到了函数的最后半个},即函数结束,进入0状态。
源代码:
#include "stdio.h"
#include "string"
#include <list>
char fsm_RemoveComment[9][128];
char fsm_FindFunction[11][128];
void initfsm()
{
const int line_len=sizeof(char)*128;
memset(fsm_RemoveComment[0],0,line_len);
memset(fsm_RemoveComment[1],0,line_len);
memset(fsm_RemoveComment[2],2,line_len);
memset(fsm_RemoveComment[3],3,line_len);
memset(fsm_RemoveComment[4],3,line_len);
memset(fsm_RemoveComment[5],5,line_len);
memset(fsm_RemoveComment[6],5,line_len);
memset(fsm_RemoveComment[7],0,line_len);
memset(fsm_RemoveComment[8],0,line_len);
fsm_RemoveComment[0]['/']=1;
fsm_RemoveComment[0]['"']=5;
fsm_RemoveComment[1]['/']=2;
fsm_RemoveComment[1]['*']=3;
fsm_RemoveComment[1]['"']=5;
fsm_RemoveComment[2]['\n']=7;
fsm_RemoveComment[3]['*']=4;
fsm_RemoveComment[4]['/']=7;
fsm_RemoveComment[4]['*']=4;
fsm_RemoveComment[5]['"']=0;
fsm_RemoveComment[5]['\\']=6;
fsm_RemoveComment[7]['/']=1;
fsm_RemoveComment[7]['"']=5;
fsm_RemoveComment[0]['\\']=8;
memset(fsm_FindFunction[0],0,line_len);
memset(fsm_FindFunction[1],2,line_len);
memset(fsm_FindFunction[2],2,line_len);
memset(fsm_FindFunction[3],3,line_len);
memset(fsm_FindFunction[4],4,line_len);
memset(fsm_FindFunction[5],5,line_len);
memset(fsm_FindFunction[6],1,line_len);
memset(fsm_FindFunction[7],7,line_len);
memset(fsm_FindFunction[8],5,line_len);
memset(fsm_FindFunction[9],9,line_len);
memset(fsm_FindFunction[10],9,line_len);
fsm_FindFunction[0]['\n']=1;
fsm_FindFunction[0][' ']=1;
fsm_FindFunction[0]['\t']=1; //原作者没有添加对制表符的识别导致以制表符开头的函数无法识别
fsm_FindFunction[0]['}']=1;
fsm_FindFunction[0][';']=1;
fsm_FindFunction[1]['(']=4;
fsm_FindFunction[1][' ']=1;
fsm_FindFunction[1]['\t']=1; //同上
fsm_FindFunction[1]['\n']=1;
fsm_FindFunction[2][';']=0;
fsm_FindFunction[2][')']=0;
fsm_FindFunction[2]['(']=4;
fsm_FindFunction[2][',']=0;
fsm_FindFunction[2]['{']=0;
fsm_FindFunction[2]['}']=0;
fsm_FindFunction[2][' ']=1;
fsm_FindFunction[2]['\t]=1; //同上
fsm_FindFunction[2]['\n']=1;
fsm_FindFunction[3][';']=0;
fsm_FindFunction[3]['{']=7;
fsm_FindFunction[3]['}']=0;
fsm_FindFunction[4][';']=0;
fsm_FindFunction[4][')']=6;
fsm_FindFunction[4]['(']=0;
fsm_FindFunction[4]['{']=0;
fsm_FindFunction[4]['}']=0;
fsm_FindFunction[5]['"']=7;
fsm_FindFunction[5]['\\']=8;
fsm_FindFunction[6]['\n']=6;
fsm_FindFunction[6]['{']=7;
fsm_FindFunction[6][' ']=6;
fsm_FindFunction[6]['\t']=6; //同上
fsm_FindFunction[6][':']=3;
fsm_FindFunction[7]['\'']=9;
fsm_FindFunction[7]['"']=5;
fsm_FindFunction[9]['\'']=7;
fsm_FindFunction[9]['\\']=10;
}
bool RemoveComment(const std::string& Filename,char* &co,int &nLength)
{
FILE *myfile=fopen(Filename.c_str(),"r");
if (!myfile)
{
printf("can't open file.\n");
return false;
}
fseek(myfile, 0, SEEK_END);
nLength=ftell(myfile);
fseek(myfile,0,SEEK_SET);
co=new char[nLength];
char c;
std::string s;
int state=0;
int i=0;
while (fscanf(myfile,"%c",&c)!=EOF)
{
state=fsm_RemoveComment[state][c];
s+=c;
switch(state)
{
case 0:
memcpy(co+i,s.c_str(),s.length());
i+=s.length();
s="";
break;
case 7:
s="";
if(c=='\n'){
co[i]=c;
i++;
}
break;
case 1:
case 2:
case 3:
case 4:
case 6:
case 8:
if ('\n'==c)
{
co[i]=c;
i++;
}
break;
}
}
fclose(myfile);
nLength=i+1;
return true;
}
struct FuncList_t
{
std::string name;
int nStartLine;
int nEndLine;
};
bool FindFunc(const std::string& Filename, std::list<FuncList_t>& listFunc)
{
//remove comment
char *co=NULL;
int nLength=0;
if (!RemoveComment(Filename,co,nLength)){
return false;
}
//find functions
FuncList_t st;
int nLine=0;
int state=0;
int nLastState=0;
int nBracket=0;
int i=0;
std::string s;
for (;i<nLength;i++){
char c=co[i];
state=fsm_FindFunction[state][c];
if (c=='\n'){
nLine++;
}
switch(state){
case 2:
if (nLastState==1){
s="";
}
s+=c;
break;
case 7:
if (6==nLastState||3==nLastState){
st.name=s;
st.nStartLine=nLine;
s="";
}
if (c=='{'){
nBracket++;
}
if ('}'==c){
nBracket--;
}
if (0==nBracket){
st.nEndLine=nLine+1;
listFunc.push_back(st);
state=0;
}
break;
}
nLastState=state;
}
delete []co;
return true;
}
int main()
{
initfsm();
std::list<FuncList_t> listFunc;
FindFunc("G:\\projects\\vc\\removeCppComment\\removeCppComment.cpp",listFunc);
FILE *file=fopen("C:\\1.txt","w");
std::list<FuncList_t>::iterator itFunc=listFunc.begin();
for (;itFunc!=listFunc.end();itFunc++){
fprintf(file,"%s: %d-%d\n",itFunc->name.c_str(),itFunc->nStartLine,itFunc->nEndLine);
}
fclose(file);
system("C:\\1.txt");
return 0;
}
用它自己这个cpp试验的运行结果:
initfsm: 6-86
RemoveComment: 88-141
FindFunc: 148-202
main: 204-217