(1)保留字
(reserved word)
:
指在高级语言中已经定义过的字,使用者不能再将这些字作为变量名或过程名使用。例如c语言中的auto、double、float、int、break、if、else 等等。
(2)标示符(ID
entifier
):是指用来标识某个实体的一个符号。在不同的应用环境下有不同的含义。其实这里可以理解为自己定义的变量名。
(3)本题中比较难克服的问题在于怎么识别注释中的字段以及怎么校验源码中的保留字。特画具体DFA如下:
(4)根据上面的DFA,只需要用嵌套的switch语句来标定属于哪个阶段,并对读到的字母转换成大写即可。具体代码如下,因为是先写的代码,写文时才想起来画图,所以图中阶段号和代码中阶段号不一致,但是具体的思路是一致的。
char reservesWord[][19]={"int","double","long","float","bool","char",
"if","else","while","switch","case","continue",
"break","void","unsighed","extern","global","default","return"};
int main(){
char token[32];
int i,j;
int check=0; //用来存储和保留字校验的结果
int sz=0;
int state=0; //存储当前属于的阶段号
int ch; //存储当前读到的字符
FILE *fp;
if((fp=fopen("exercise1.txt","r"))==NULL){
printf("无法打开源文件!\n");
exit(0);
}
while((ch=getc(fp))!=EOF){
i=0;j=0;
sz=0;
check=0;
switch(state){
case 0:
if(ch=='/'){
state=1;
break;
}
case 1:
{
switch(ch){
case '*':
state=2;
break;
case '/':
state=4;
break;
default:
state=0;
break;
}
break;
}
case 2:
if(ch=='*'){
state=3;
break;
}
case 3:
if(ch=='/'){
state=0;
}else{
state=2;
}
case 4:
if(ch=='\n')
state=0;
}
//isalpha函数非字母返回0,大写字母返回1,小写字母返回2
if((!isalpha(ch))||state==2||state==4){ //若当前字符是非字母或者是第二/四阶段,打印该字符
if(!isalpha(ch) || isupper(ch)){
putc(ch,stdout);
}
else if(islower(ch)){
ch = toupper(ch);
putc(ch,stdout);
}
else
;
}else{
for(i=0;i<19;i++)
token[i]='\0';
i=0;
do{
token[i++]=ch;
ch=getc(fp);
}while(isalpha(ch)&&ch!=EOF);
//将读入的token和保留字数组做对比,如果是保留字,check置1
for(i=0;i<19;i++){
if(strcmp(token,reservesWord[i])==0){
check=1;
break;
}
}
//对token数组组成的字符串做处理
for(j=0;token[j]!='\0';j++){
if(check==1) //如果确定为保留字,改为大写字母
{
if(islower(token[j])){
token[j]=toupper(token[j]);
putc(token[j],stdout);
}
}
else //如果是标识符,改为小写字母
{
token[j]=tolower(token[j]);
putc(token[j],stdout);
}
}
putc(ch,stdout);
}
}
fclose(fp);
return 0;
}