作者在 2011-08-31 23:47:18 发布以下内容
// 去除汇编代码中的注释符号
/*****************************************************************************
用状态机做会不会很方便,输入集中比较特殊的就这几个:#,/,*,",\,关键是在它的构造,
在本子上画个表,纵向是表示状态,横向表示特殊的输入,表中的值就是状态的变化,
再在旁边记录各个状态的含义,它大概是这样:
\输入 # / * " \ 回车 其它
状态
0 7 1 0 5 0 0 0
1
2
...
0: 正在分析
1:读到第一个/
2:读完第二个/,"//...
3:读到 "/*...
4:读到 "/*...*
5:读到第一个"
6:读到字符串里的转义符 "...\
7:读到 #
8:找到注释
0和8是等价的状态,但是可以用8状态做些特别的事情,比如这个时候删除刚找到的注释等。
最后的程序如下,输入输出还是用C的文件比较方便:
*****************************************************************************/
#include "stdio.h"
#include "string"
using namespace std;
#define ALPHABET_NUM 256
char fsm[9][ALPHABET_NUM];
void initfsm()
{
memset(fsm[0],0,ALPHABET_NUM); // 初始状态
memset(fsm[1],0,ALPHABET_NUM);
memset(fsm[2],2,ALPHABET_NUM);
memset(fsm[3],3,ALPHABET_NUM);
memset(fsm[4],3,ALPHABET_NUM);
memset(fsm[5],5,ALPHABET_NUM);
memset(fsm[6],5,ALPHABET_NUM);
memset(fsm[7],2,ALPHABET_NUM);
memset(fsm[8],0,ALPHABET_NUM);
fsm[0]['/']=1; // 读到第一个/
fsm[0]['"']=5;
fsm[0]['#']=2;
fsm[1]['/']=2;
fsm[1]['*']=3;
fsm[1]['"']=5;
fsm[1]['#']=7;
fsm[2]['\n']=8;
fsm[3]['*']=4; // /* ... *
fsm[4]['/']=8;
fsm[4]['*']=4;
fsm[5]['"']=0;
fsm[5]['\\']=6;
fsm[8]['/']=1;
fsm[8]['"']=5;
fsm[8]['#']=2;
}
int main()
{
int state=0;
char c;
std::string s;
FILE *fin=fopen("in.txt","r");
FILE *fout=fopen("out.txt","w");
initfsm();
while(fscanf(fin,"%c",&c)!=EOF)
{
state=fsm[state][c];
//printf("\t(%d,%s,%c)\n",state, s.c_str(), c);
switch(state)
{
case 0:
s+=c;
fprintf(fout,"%s",s.c_str());
s="";
break;
case 7:
fprintf(fout,"%s",s.c_str()); // fprintf(fout,"/");
s="";
break;
case 8:
if(c=='\n')
{
fputc(c,fout);
}
s="";
break;
default:
s+=c;
break;
}
}
fclose(fin);
fclose(fout);
return 0;
}
/*****************************************************************************
用状态机做会不会很方便,输入集中比较特殊的就这几个:#,/,*,",\,关键是在它的构造,
在本子上画个表,纵向是表示状态,横向表示特殊的输入,表中的值就是状态的变化,
再在旁边记录各个状态的含义,它大概是这样:
\输入 # / * " \ 回车 其它
状态
0 7 1 0 5 0 0 0
1
2
...
0: 正在分析
1:读到第一个/
2:读完第二个/,"//...
3:读到 "/*...
4:读到 "/*...*
5:读到第一个"
6:读到字符串里的转义符 "...\
7:读到 #
8:找到注释
0和8是等价的状态,但是可以用8状态做些特别的事情,比如这个时候删除刚找到的注释等。
最后的程序如下,输入输出还是用C的文件比较方便:
*****************************************************************************/
#include "stdio.h"
#include "string"
using namespace std;
#define ALPHABET_NUM 256
char fsm[9][ALPHABET_NUM];
void initfsm()
{
memset(fsm[0],0,ALPHABET_NUM); // 初始状态
memset(fsm[1],0,ALPHABET_NUM);
memset(fsm[2],2,ALPHABET_NUM);
memset(fsm[3],3,ALPHABET_NUM);
memset(fsm[4],3,ALPHABET_NUM);
memset(fsm[5],5,ALPHABET_NUM);
memset(fsm[6],5,ALPHABET_NUM);
memset(fsm[7],2,ALPHABET_NUM);
memset(fsm[8],0,ALPHABET_NUM);
fsm[0]['/']=1; // 读到第一个/
fsm[0]['"']=5;
fsm[0]['#']=2;
fsm[1]['/']=2;
fsm[1]['*']=3;
fsm[1]['"']=5;
fsm[1]['#']=7;
fsm[2]['\n']=8;
fsm[3]['*']=4; // /* ... *
fsm[4]['/']=8;
fsm[4]['*']=4;
fsm[5]['"']=0;
fsm[5]['\\']=6;
fsm[8]['/']=1;
fsm[8]['"']=5;
fsm[8]['#']=2;
}
int main()
{
int state=0;
char c;
std::string s;
FILE *fin=fopen("in.txt","r");
FILE *fout=fopen("out.txt","w");
initfsm();
while(fscanf(fin,"%c",&c)!=EOF)
{
state=fsm[state][c];
//printf("\t(%d,%s,%c)\n",state, s.c_str(), c);
switch(state)
{
case 0:
s+=c;
fprintf(fout,"%s",s.c_str());
s="";
break;
case 7:
fprintf(fout,"%s",s.c_str()); // fprintf(fout,"/");
s="";
break;
case 8:
if(c=='\n')
{
fputc(c,fout);
}
s="";
break;
default:
s+=c;
break;
}
}
fclose(fin);
fclose(fout);
return 0;
}