最近在研究c语言之父的c程序设计语言,里面有一个关于将c注释转换成c++注释的问题,要用到状态机的知识:这里总结一下,并附上源代码
有限状态机体现了两点:首先是离散的,然后是有限的。
State:
状态这个词有些难以定义,状态存储关于过去的信息,就是说它反映从系统开始到现在时刻的输入变化。 Actions & Transitions: 转换指示状态变更,并且用必须满足来确使转移发生的条件来描述它。动作是在给定时刻要进行的活动的描述。
Guards:
检测器出现的原因是为了检测是否满足从一个状态切换到另外一个状态的条件。 Event:
事件,又见事件,笼统说来,对系统重要的某件事情被称为事件。 恩,就这些了,有些迷惑么:),恩,我们来理清一下思路:先从事件说起,事件是有生命的,它经历:
1. 被产生(被接受,等待被处理,一般放入事件队列)
2. 被分发(从事件队列取出,分发到响应的状态机处理)
3. 死亡(当状态机处理了该事件,它随之死亡) 从一个状态切换到另外一个状态被称为状态转换,而引起它的事件称为触发事件.(可以看到,不是所有的事件都会引起状态的转换).
提到状态转换,不能不提及检测器(Guards),只有当检测器的值为TRUE时候,才能启动转换
所有可能出现的情况:
// 1.一般情况
/* int i = 0; */
// 2.换行问题
/* int i = 0; */int j = 0;
/* int i = 0; */
int j = 0;
// 3.匹配问题
/*int i = 0;/*xxxxx*/
// 4.多行注释问题
/*
int i=0;
int j = 0;
int k = 0;
*/int k = 0;
// 5.连续注释问题
/**//**/
// 6.连续的**/问题
/***/
// 7.C++注释问题
// /*xxxxxxxxxxxx*/
#include<stdio.h>
static enum STATE
{
NULL_STATE,
C_STATE,
CPP_STATE,
END_STATE
};
enum STATE state = NULL_STATE;
void Do_C_State(FILE *fRead, FILE *fWrite)
{
char first = 0;
char second = 0;
char third = 0;
first = fgetc(fRead);
switch (first)
{
case'*':
second = fgetc(fRead);
switch (second)
{
case'/':
third = fgetc(fRead);
if (third != '\n')
fputc('\n', fWrite);
if (third == '/')
{
ungetc(third, fRead);
state = NULL_STATE;
break;
}
fputc(third, fWrite);
state = NULL_STATE;
break;
case'*':
third = fgetc(fRead);
fputc(first, fWrite);
if (third == '/')
{
state = NULL_STATE;
fputc('\n', fWrite);
break;
}
ungetc(second, fRead);
ungetc(third, fRead);
break;
default:
fputc(first, fWrite);
fputc(second, fWrite);
break;
}
break;
case'\n':
fputc(first, fWrite);
fputc('/', fWrite);
fputc('/', fWrite);
break;
case EOF:
state = END_STATE;
break;
default:
fputc(first, fWrite);
break;
}
}
void Do_CPP_State(FILE *fRead, FILE *fWrite)
{
char first = 0;
first = fgetc(fRead);
switch (first)
{
case '\n':
fputc(first, fWrite);
state = NULL_STATE;
break;
case EOF:
state = END_STATE;
break;
default:
fputc(first, fWrite);
break;
}
}
void Do_Null_state(FILE *fRead, FILE *fWrite)
{
char first = 0;
char second = 0;
first = fgetc(fRead);
switch (first)
{
case'/':
second = fgetc(fRead);
if (second == '*')
{
fputc('/', fWrite);
fputc('/', fWrite);
state = C_STATE;
}
else if (second == '/')
{
fputc(first, fWrite);
fputc(second, fWrite);
state = CPP_STATE;
}
else
{
fputc(first, fWrite);
fputc(second, fWrite);
}
break;
case EOF:
state = END_STATE;
break;
default:
fputc(first, fWrite);
break;
}
}
void CommentConvert(FILE *fRead, FILE *fWrite)
{
while (state != END_STATE)
{
switch (state)
{
case NULL_STATE:
Do_Null_state(fRead, fWrite);
break;
case C_STATE:
Do_C_State(fRead, fWrite);
break;
case CPP_STATE:
Do_CPP_State(fRead, fWrite);
break;
default:
break;
}
}
}
int main()
{
FILE *fRead = NULL;
FILE *fWrite = NULL;
printf("注释转换开始啦~~");
fWrite = fopen("./2.txt","r+");
if (NULL == fWrite)
{
fclose(fRead);
perror("失败");
}
fRead = fopen("./1.txt","r");
if (NULL == fRead)
{
perror("失败了");
}
CommentConvert(fRead, fWrite);
printf("转换结束");
fclose(fRead);
fclose(fWrite);
system("pause");
return 0;
}