原题: 编写一个删除C语言程序中所有的注释语句。要正确处理带引号的字符串与字符常量。再C语言中,注释不允许嵌套。
题目的目的是要做一个简单的语法分析器,所使用的工具为状态机。
状态 0 : start
输入 / 进入状态1
输入 " 进入状态4
输入 ' 进入状态8
输入其他字符进入状态0
状态 1 : 第一个 /
输入 * 进入状态2
输入 / 进入状态6 【c99 tc3 已经支持c++ style 的注释了 】
输入其他字符进入错误状态
状态 2 : /* 【注释部分开始】
输入 * 进入状态 5
输入其他字符进入状态2
状态 5 : /*...* 【注释内容(包含注释符号)】
输入 / 进入状态7
输入其他字符进入状态2
状态 7 : 注释部分结束
输入其他字符进入状态0
状态 6 : // 【注释部分开始】
输入 回车[\n] 进入状态0
输入 \ 进入状态9
输入其他字符进入状态6
状态 9 : // ... \
输入其他状态进入状态6
状态 4 : "
输入 " 进入状态0
输入 \ 进入状态3 【转义字符】
输入其他字符进入状态4
状态 3 : "....\
输入其他字符进入状态4
状态 8 : '
输入 \ 进入状态11
输入其他字符进入状态10
状态 10 : '?
输入 ' 进入状态 0
输入其他字符进入错误状态
状态 11 : '\
输入其他字符进入状态12
状态 12 : '\?
输入 ' 进入状态0;
输入其他字符进入错误状态
#include ”stdio.h“
#include “string.h”
#define NUMBER_OF_STATE 13
static char fsm[NUMBER_OF_STATE][128];
void init_fsm()
{
const size_t len_of_line = sizeof(fsm)/NUMBER_OF_STATE;
memset( fsm[0], 0, len_of_line );
fsm[0]['/'] = 1;
fsm[0]['"'] = 4;
fsm[0]['\''] = 8;
memset( fsm[1], -1, len_of_line );
fsm[1]['*'] = 2;
fsm[1]['/'] = 6;
memset( fsm[2], 2, len_of_line );
fsm[2]['*'] = 5;
memset( fsm[3], 4, len_of_line );
memset( fsm[4], 4, len_of_line );
fsm[4]['"'] = 0;
fsm[4]['\\'] = 3;
memset( fsm[5], 2, len_of_line );
fsm[5]['/'] = 7;
memset( fsm[6], 6, len_of_line );
fsm[6]['\n'] = 0;
fsm[6]['\\'] = 9;
memset( fsm[7], 0, len_of_line );
memset( fsm[8], 10, len_of_line );
fsm[8]['\\'] = 11;
memset( fsm[9], 6, len_of_line );
memset( fsm[10], -1, len_of_line);
fsm[10]['\''] = 0;
memset( fsm[11], 12, len_of_line );
memset( fsm[12], -1, len_of_line );
fsm[12]['\''] = 0;
}
int main(void)
{
char state = 0;
char c;
FILE* fin = fopen( "in.c", "r" );
FILE* fout = fopen( "out.c", "w" );
init_fsm();
while( fscanf( fin, "%c", &c )!= EOF ){
if ( (state = fsm[ state ][ c ] ) == -1 )
break;
switch(state)
{
case 0:
case 3:
case 4:
case 8:
case 10:
case 11:
case 12:
fprintf( fout, "%c", c);
break;
default:
break;
}
}
if( state == 6 && c == EOF ) // c ++ style is at the end of file.
state = 0;
if( state != 0 && state != 7 )
{
printf( "there is an syntactic error" );
}
fclose(fin);
fclose(fout);
return 0;
}
应付这道题还OK了,但是还是留下来了两个问题:
1. 状态机还有什么别的实现方法么?
2. 为什么使用状态机?