读书人

词法分析程序关键字main后的int没法

发布时间: 2013-04-07 12:50:11 作者: rapoo

词法分析程序,关键字main后的int无法配对!也就是输出的编码不对,请指导指导
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

FILE *fp1,*fp2;
char prog[255],token[8],ch;
int decode,p,m,n,i;
char *KEY_WORDS[7]={"main","int","char","if","else","for","while"};

void Scaner(void);
void PrintError(void);

int main()
{
char Sourfile[10],Wfile[10];
char lbracket,rbracket,comma;
lbracket = '(';
rbracket = ')';
comma = ',';
printf("请输入存放源程序的文件名:");
scanf("%s",Sourfile);
printf("\n");

if((fp1 = fopen(Sourfile,"r")) == NULL)
{
printf("无法打开此文件!\n");
exit(0);
}

printf("请输入输出数据文件的名字:");
scanf("%s",&Wfile);
printf("\n");

if((fp2 = fopen(Wfile,"w")) == NULL)
{
printf("无法打开此文件!\n");
exit(0);
}

p=0;

while(!feof(fp1))
{
ch = fgetc(fp1);
prog[p++] = ch;
};
prog[p] = '\0';

p = 0;

do{
Scaner();
switch(decode)
{
case -1:
//PrintError();
return 0;
case 0:
break;
//case -2:
//continue;

default:
fputc(lbracket,fp2);
fprintf(fp2,"%d",decode);
fputc(comma,fp2);
fputs(token,fp2);
fputc(rbracket,fp2);
fputc(' ',fp2);
break;
}
}while(decode != 0);
fclose(fp1);
fclose(fp2);
return 0;
}

void Scaner(void)
{
for(m = 0;m < 8;m++)
token[m++] = NULL;

ch = prog[p++];
m=0;

while((ch == ' ')||(ch == '\n')||(ch == '\t'))
ch = prog[p++];

if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch >= 'A')))
{
while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9')))
{


token[m++] = ch;
ch = prog[p++];
}

p--;
decode = 10;

for(n = 0;n < 7;n++) //检测标识符里是否有关键字
if(strcmp(token,KEY_WORDS[n]) == 0)
{
decode = n+1;
break;
}

}
else if((ch>='0')&&(ch<='9'))
{
while((ch>='0')&&(ch<='9'))
{
token[m++] = ch;
ch=prog[p++];
}
p--;
decode=20;
}
else
{
switch(ch)
{
case '<':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
decode=38;
token[m++]=ch;
}
else
{
decode=35;
p--;
}
break;

case '>':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
decode=37;
token[m++]=ch;
}
else


{
decode=36;
p--;
}
break;

case '=':
token[m++] = ch;
ch = prog[p++];
if(ch == '=')
{
decode = 39;
token[m++]=ch;
}
else
{
decode = 21;
p--;
}
break;

case '+':
decode = 22;
token[m++] = ch;
break;

case '-':
decode = 23;
token[m++]=ch;
break;

case '!':
token[m++] = ch;
ch=prog[p++];
if(ch == '=')
{
decode = 40;
token[m++]=ch;
}
else
{

p--;
}
break;

case '&':
token[m++] = ch;
ch = prog[p++];
if(ch == '&')
{
decode = 42;
token[m++] = ch;
}
else
{
decode = 41;
p--;
}
break;

case '*':
decode = 24;
token[m++] = ch;
break;

case '/':
decode = 25;
token[m++]=ch;
break;

case '(':
decode = 26;
token[m++]=ch;
break;

case ')':
decode = 27;
token[m++]=ch;
break;

case '[':


decode = 28;
token[m++]=ch;
break;

case ']':
decode = 29;
token[m++]=ch;
break;

case '{':
decode = 30;
token[m++]=ch;
break;

case '}':
decode = 31;
token[m++]=ch;
break;

case ',':
decode = 32;
token[m++]=ch;
break;

case ':':
decode = 33;
token[m++]=ch;
break;

case ';':
decode = 34;
token[m++] = ch;
break;
case '\0':
decode = 0;
break;
default:
decode = -1;
break;
}
}
token[m++]='\0';
}

输入的数据:main main main int int int int for for
输出的数据:(1,main) (1,main) (1,main) (10,int) (2,int) (2,int) (2,int) (6,for) (6,for)
其中紧跟main后的第一个int输出的编码不对 哪里出了问题?

token fp null file
[解决办法]
main长度是4。收到第一个int的时候,你只更新了token的实际字符,没有更新'\0',导致在执行完while的时候,token实际内容是intn,其中最后一个n是main留下来的n。所以执行strcmp的那个时候,你实际在用intn去比较keyword,当然是没找到。
在最后输出以前你token最后的确加了'\0'所以显示是正常的。
[解决办法]


void Scaner(void)
{
//for(m = 0;m < 8;m++)
//token[m++] = NULL;//这个效率不高,被编译器优化到变量定义的初始化中去了
memset(token,0,sizeof(token));//改为memset方法就不会被优化掉了或都干脆不初始化,下面及时添加结束符也可

ch = prog[p++];
m=0;

while((ch == ' ')
[解决办法]
(ch == '\n')
[解决办法]
(ch == '\t'))
ch = prog[p++];

if(((ch<='z')&&(ch>='a'))


[解决办法]
((ch<='Z')&&(ch >= 'A')))
{
while(((ch<='z')&&(ch>='a'))
[解决办法]
((ch<='Z')&&(ch>='A'))
[解决办法]
((ch>='0')&&(ch<='9')))
{
token[m++] = ch;
ch = prog[p++];
}
//token[m]='\0';//<<<调用strcmp()之前必需添加结束符,如果有memset处理就不必了
p--;
decode = 10;
for(n = 0;n < 7;n++)//检测标识符里是否有关键字
if(strcmp(token,KEY_WORDS[n]) == 0)
{
decode = n+1;
break;
}
}
else if((ch>='0')&&(ch<='9'))
{
while((ch>='0')&&(ch<='9'))
{
token[m++] = ch;
ch=prog[p++];
}
//token[m]='\0';//<<<结束符
p--;
decode=20;
}
else
{
switch(ch)
{
case '<':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
decode=38;
token[m++]=ch;
}
else
{
decode=35;
p--;
}
break;
case '>':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
decode=37;
token[m++]=ch;
}
else
{
decode=36;
p--;
}
break;
case '=':
token[m++] = ch;
ch = prog[p++];
if(ch == '=')
{
decode = 39;
token[m++]=ch;
}
else
{
decode = 21;
p--;
}
break;
case '+':
decode = 22;
token[m++] = ch;
break;
case '-':
decode = 23;
token[m++]=ch;
break;
case '!':
token[m++] = ch;
ch=prog[p++];
if(ch == '=')
{
decode = 40;
token[m++]=ch;
}
else
{
p--;
}
break;
case '&':
token[m++] = ch;
ch = prog[p++];
if(ch == '&')
{
decode = 42;
token[m++] = ch;
}
else
{
decode = 41;
p--;
}
break;
case '*':
decode = 24;
token[m++] = ch;
break;
case '/':
decode = 25;
token[m++]=ch;
break;
case '(':
decode = 26;
token[m++]=ch;
break;
case ')':
decode = 27;
token[m++]=ch;
break;
case '[':
decode = 28;
token[m++]=ch;
break;
case ']':
decode = 29;
token[m++]=ch;
break;
case '{':
decode = 30;
token[m++]=ch;
break;
case '}':
decode = 31;
token[m++]=ch;
break;
case ',':
decode = 32;
token[m++]=ch;
break;
case ':':
decode = 33;
token[m++]=ch;
break;
case ';':
decode = 34;
token[m++] = ch;
break;
case '\0':
decode = 0;
break;
default:
decode = -1;
break;
}
//token[m]='\0';//<<<结束符


}
//token[m++]='\0';//<<<这里才加结束符晚啦,前边已经提前用到结束符, 而且此时的++也多余了
}


读书人网 >C语言

热点推荐