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

100分请调试一个简单的程序!

2012-02-22 
100分请调试一个简单的程序!!!!高手请进一个小语法分析器,当调用Output(id,X)时想输出到output.txt,但没有

100分请调试一个简单的程序!!!!高手请进
一个小语法分析器,当调用Output(id,X)时想输出到output.txt,但没有数据输出。请帮忙查找出原因。将数据输出到文本文件即可。
#include   <stdio.h>
#include   <string.h>
#include   <stdlib.h>
charVN[10][5]={ "L ", "E ", "E ' ", "T ", "T ' ", "F "};   //非终结符表
intlength_vn=6;       //非终结符的个数

charVT[15][5]={ "id ", "num ", "+ ", "- ", "* ", "/ ", "% ", "( ", ") ", "; ", "$ "};     //终结符表
intlength_vt=11;   //终结符的个数  

charFa[15][10]={ "E;L ", " ", "TE ' ", "+TE ' ", "-TE ' ", " ", "FT ' ", "*FT ' ", "/FT ' ", "%FT ' ", " ", "(E) ", "id ", "num "};  
  //产生式表0:L-> E;L       1:l-> 空       2:E-> TE '       3:E '-> +TE '     4:E '-> -TE '     5:E '-> 空       6:T-> FT '     7:T '-> *FT '    
//   8:T '-> /FT '     9:T '-> %FT "       10:T '-> 空     11:F-> (E)     12:F-> id       13:F-> num

intanalysis_table[10][11]={0,0,-1,-1,-1,-1,-1,0,-1,-1,1,
2,2,-1,-1,-1,-1,-1,2,-2,-2,-1,
-1,-1,3,4,-1,-1,-1,-1,5,5,-1,
6,6,-2,-2,-1,-1,-1,6,-2,-2,-1,
-1,-1,10,10,7,8,9,-1,10,10,-1,
12,13,-2,-2,-2,-2,-2,11,-2,-2,-1};
//预测分析表,-1表示出错,-2表示该行终结符的follow集合,用于错误处理

FILE     *fp;   //二元式文件指针

int   X_id;

struct   link{
char   token[5];
char     value[10];
link     *next;
}   ;//链表结构
link     *S;       //栈结构


int   search_vn(char   c[]);
int   search_vt(char   c[]);
void   initstack();
int   nexttoken();
char   *gettop();       //取栈顶
void   pre_analy();         //预测分析函数
/**************************************************************************************/
void   main()
{
char     fname[10];

printf( "请输入二元式文件名: ");
scanf( "%s ",fname);
fp=fopen(fname, "r ");
if(fp==NULL)   {printf( "文件打不开.\n ");         exit(0);}     //exit函数在stdlib.h中
char   z;
z=fgetc(fp);
while(z!=EOF)//从文件头部依次输出所有字符
{
printf( "%c ",z);
z=fgetc(fp);
}
printf( "\n\n ");//换行
fseek(fp,0,SEEK_SET);//因读取完文件后,文件指针指向文件尾部,此函数功能为把文件指针再次移回文件头部
printf( "语法分析过程如下:\n\n ");
initstack();

pre_analy();


}     //end   of   main

/*************************************************************************************/
void   Output(int   id,char   w[5])//输出单词的二元式到目标文件   id为编号   w为单词                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        


{
FILE   *output;
output=fopen( "output.txt ", "wt ");
fprintf(output, "%s%d%s%s%s\n ", "( ",id, ", ",w, ") ");
printf( "%s%d%s%s%s\n ", "( ",id, ", ",w, ") ");
//printf( "输出%s\n ",w);
}

void   initstack()
{       //预测分析栈初始化函数,使用不带头结点的单链表作为栈的存储结构
link   *t;

S=new   link;
strcpy(S-> token,VN[0]);

t=new   link;
strcpy(t-> token, "$ ");
t-> next=NULL;

S-> next=t;

}//栈初始化函数结束

/***************************************************************************************/
int   nexttoken()
{   //读取下一个记号
char     c[5]= " ";
int     i;//终结符的位置
int       len=1;//当前终结符的长度
c[0]=fgetc(fp);
c[1]= '\0 ';
while((i=search_vt(c))==-1)     //没找到终结符,表示还没有形成完整的终结符,继续读入下一符号
{c[len]=fgetc(fp);
len++;
c[len]= '\0 ';
}
return   i;

}       //读取下一记号结束
/*************************************************************************************/
int   search_vt(char     c[])       //查找终结符,返回终结符在终结符表中的下标位置,-1表示查找失败
{
int     i;
for(i=length_vt-1;i> =0&&strcmp(VT[i],c)!=0;i--);
return   i;

}//终结符查找结束
/*************************************************************************************/
int   search_vn(char   c[])
{
int     i;
for(i=length_vn-1;i> =0&&strcmp(VN[i],c)!=0;i--);
return   i;

}
/************************************************************************************/

/**************************************************************************************/
char   *gettop()       //取栈顶
{

return     S-> token;
}
/***************************************************************************************/
void   pop()     //出栈函数
{
link   *     head;
head=S;
S=S-> next;
free(head);
}
/**************************************************************************************/
void   push(char   Yi[])     //入栈函数
{
link     *head=new   link;
strcpy(head-> token,Yi);
head-> next=S;
S=head;
}
/**************************************************************************************/
void   error(int   i,int     j,int   token)
{
switch(i)
{
case   1:       pop();     printf( "弹出栈顶符号.\n ");   break;       //终结符不匹配
case   2:       //栈顶为非终结符,
if(j==-2)
{
pop();
printf( "弹出栈顶符号.\n ");
}
else
{  
printf( "跳过%s\n ",VT[token]);

}       break;



}     //end   of   switch

}
/*************************************************************************************/
void   pre_analy()         //预测分析函数
{
int     token;//存放读取的单词记号在终结符表中的位置
char     X[5];         //存放栈顶符号
int   i,j,len;
char       Yi[5],temp_Y[5];
printf( "栈顶元素当前单词记号   动作\n ");
printf( "_________________________________________________________________\n ");



token=nexttoken();     //取下一记号,终结符的编号
do{
strcpy(X,gettop());
i=search_vt(X);       //终结符号表中查找X
if(i> =0)       //X是终结符
{if(strcmp(X,VT[token])==0)       //终结符相等,匹配终结符
{
pop();    
printf( "%s%s匹配终结符%s\n ",X,VT[token],X);
if(strcmp( "id ",X)==0||strcmp( "num ",X)==0)
{X_id=17;}
//printf( "hehe ");
Output(X_id,X);
token=nexttoken();
}
else  
{
printf( "%s%s出错, ",X,VT[token]);
error(1,0,0);
//token=nexttoken();
}
}
else       //栈顶为非终结符,展开
{
i=search_vn(X);
if((i=analysis_table[i][token])!=-1&&i!=-2)     //X是非终结符且查预测分析表不为空,-2表示follow(X)值
{
len=strlen(Fa[i]);
pop();     //从栈顶弹出X
if(len==0)     //空产生式
{

}
else
for(j=len-1;j> =0;j--)       //将产生式Fa[i]反向压入栈
{
Yi[0]=Fa[i][j];     Yi[1]= '\0 ';       //寻找产生式中的文法符号(终结符或非终结符),可能不止一个字符
while(search_vn(Yi)==-1&&search_vt(Yi)==-1)     //     没有形成文法符号
{
j--;
temp_Y[0]=Fa[i][j];temp_Y[1]= '\0 ';
strcat(temp_Y,Yi);
strcpy(Yi,temp_Y);
}
push(Yi);       //文法符号入栈
}
printf( "%s%s展开非终结符%s-> %s\n ",X,VT[token],X,Fa[i]);     //输出动作

}
else    
{
printf( "%s%s出错, ",X,VT[token]);
error(2,i,token);
if(i=-1)     token=nexttoken();
}
                       
}
}while(strcmp(gettop(), "$ ")!=0);   //栈不空,继续分析,栈空,则结束分析

printf( "$$结束\n ");

}    


读取的文本文件是:a.txt
id*id+id$
将上行复制存为a.txt即可


[解决办法]
/*************************************************************************************/
void Output(int id,char w[5])//输出单词的二元式到目标文件 id为编号 w为单词
{
FILE *output;
output=fopen( "output.txt ", "wt ");
fprintf(output, "%s%d%s%s%s\n ", "( ",id, ", ",w, ") ");
printf( "%s%d%s%s%s\n ", "( ",id, ", ",w, ") ");
// printf( "输出%s\n ",w);
fclose(output); //你的程序少这个
}

main函数中文件打开后也没有关闭。
[解决办法]
fp=fopen(fname, "r ");
if(fp==NULL) {printf( "文件打不开.\n "); exit(0);} //exit函数在stdlib.h中

以只读方式打开,如果不存在输入的文件名,程序就结束了
[解决办法]
fp=fopen(fname, "rw ");
fclose(output);
[解决办法]
没有
fclose()

热点排行