首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

词法分析程序,关键字main后的int没法配对!也就是输出的编码不对,请指导指导

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

词法分析程序,关键字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';//<<<这里才加结束符晚啦,前边已经提前用到结束符, 而且此时的++也多余了
}


热点排行