求c语言词法分析程序
发布网友
发布时间:2022-04-30 05:11
我来回答
共2个回答
热心网友
时间:2023-10-15 14:56
以前学c语言的时候写的,但是没有经过很好的设计,程序结构比较乱。运行没有问题。也可以处理包含的头文件。
/*************************************************
c语言分析程序
*************************************************/
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
char *key[]={"auto","bool","break","case","char","complex","const","continue","default","restrict","do","double","else","enum","extern","float","for","goto","if","imaginary","inline","int","long","register","return","stort","signed","sizeof","static","struct","switch","tyepdef","union","unsigned","void","volatile","while"};
char *limit[]={"#","(",")","[","]","'","\"",";",":","{","}","\\",","};
char *ysf[]={"!","%","^","&","*","-","+","=","~","|",".","<",">","/","?",":","+=","-=","*=","/","%=","<<=",">>=","&=","^=","|=","->","++","--","<<",">>","<=",">=","==","!=","&&","||"};
char b[30];
char fn[20]={'\0'},text1[1000]={'\0'},string[30]={'\0'},text2[1000]={'\0'},kuoru[30];
char hm[10][30],hz[10][30];
char * tempp;
int z=1,y;
int i=0,j=0,k=1,n=1,p=1,q=1,o=1,m=1,x=0,temp,k1=0,k2=0,keyy,key1=0,key2=0,key3=0,key4=0,key5=0,key6=0;
FILE * sfhead;
FILE * ofhead;
FILE * bsfhead;
FILE * zsclbhead;
FILE * fdsclbhead;
FILE * zfclbhead;
FILE * zfcclbhead;
FILE * fgfhead;
FILE * ysfhead;
FILE * blzhead;
FILE * krhead;
bool find1(char * p){
int i=0;
for(i=0;i<36;i++){
if(strcmp(key[i],p)==0)
return true;
}
return false;
} /*判断提取的字符串是否属于保留字*/
int bianma1(char * p){
int i=0;
for(i=0;i<36;i++){
if(strcmp(key[i],p)==0)
return i+1;
}
return -1; /*确定保留字的序号*/
}
bool find2(char p){
int i=0;
for(i=0;i<13;i++){
if(*limit[i]==p)
return true;
}
return false;
} /*判断提取的符号是否为分隔符*/
int bianma2(char p){
int i=0;
for(i=0;i<13;i++){
if(*limit[i]==p)
return i+1;
}
return -1;
} /*确定分割符的序号*/
bool find3(char p){
int i=0;
for(i=0;i<37;i++){
if(*ysf[i]==p)
return true;
}
return false;
} /*判断提取的符号是否为运算符*/
int bianma3(char * p){
int i=0;
for(i=0;i<37;i++){
if(strcmp(ysf[i],p)==0)
return i+1;
}
return -1;
} /*确定运算符的序号*/
int bianma4(char * p){
int i=0;
for(i=0;i<10;i++){
if(strcmp(hm[i],p)==0)
return i;
}
return -1;
}
bool search(FILE * fp,char * p){
char a[30],c[30];
rewind(fp); /*将fp指向文件头部*/
while(!feof(fp)){
fscanf(fp,"%s",a);
if(strcmp(a,p)==0){ /*保存编码*/
fgets(b,30,fp);
return true;
}else
fgets(c,30,fp);
}
return false;
}
void clnmb(char * text){ /*处理以数字开头的函数*/
bool l=true;
string[j]=text[i];
i++;j++;
while(((text[i]>='0')&&(text[i]<='9'))||text[i]=='.'||text[i]=='e'||text[i]=='E'||text[i]=='-'){
string[j]=text[i];
if(text[i]=='.')
l=false;
i++;j++; /*判断数字字符串中有无小数点,如果有则证明位浮点数*/
}
if(l){
if(search(zsclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(zsclbhead,"\n\r%s\t",string);
fprintf(zsclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(zsclbhead,"\n\r%s\t",string);
fprintf(zsclbhead,"4\t");
fprintf(zsclbhead,"0\t");
fprintf(zsclbhead,"%d\t\n\r",m);
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"4\t");
fprintf(ofhead,"0\t");
fprintf(ofhead,"%d\t\n\r",m);
m++; /*用m标记出现整数常量的地址*/
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}else{
if(search(fdsclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(fdsclbhead,"\n\r%s\t",string);
fprintf(fdsclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(fdsclbhead,"\n\r%s\t",string);
fprintf(fdsclbhead,"4\t");
fprintf(fdsclbhead,"1\t");
fprintf(fdsclbhead,"%d\t\n\r",o);
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"4\t");
fprintf(ofhead,"1\t");
fprintf(ofhead,"%d\t\n\r",o); /*用o标记出现的浮点数常量地址*/
o++;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
l=true;
}
}
void dayin(FILE * fp){
int i;
char temp[40];
rewind(fp);
while(!feof(fp)){
fgets(temp,40,fp);
printf("%s",temp);
}
for(i=0;i<40;i++)
temp[i]='\0';
}
/****************************************
扫描分析程序段
*****************************************/
void saomiao(char * text){
i=0;
while(text[i]!='\0'){
if((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')){ /*分析以字母开头的情况*/
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')||text[i]=='_'||(text[i]>='0'&&text[i]<='9')){
string[j]=text[i];
i++;j++;
}
if(find1(string)){ /*判断是否为保留字*/
fprintf(blzhead,"\n\r%s\t",string);
fprintf(blzhead,"0\t");
fprintf(blzhead,"%d\t\n\r",bianma1(string));
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"0\t");
fprintf(ofhead,"%d\t\n\r",bianma1(string)); /*将字符串直接写入相应的文件和输出文件*/
for(j=0;j<30;j++) /*将string数组清空,防止出现错误*/
string[j]='\0';
j=0;
}
else {
if((keyy=bianma4(string))!=-1){
temp=i;
tempp=text;
i=0;
for(j=0;j<30;j++) /*将string数组清空,防止出现错误*/
string[j]='\0';
j=0;
clnmb(hz[keyy]);
text=tempp;
i=temp;
}else
if(search(bsfhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(bsfhead,"\n\r%s\t",string);
fprintf(bsfhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(bsfhead,"\n\r%s\t",string);
fprintf(bsfhead,"3\t");
fprintf(bsfhead,"%d\t\n\r",k);
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"3\t");
fprintf(ofhead,"%d\t\n\r",k);
k++; /*用k标记出现标识符的地址*/
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}
}
else if((text[i]>='0')&&(text[i]<='9')) /*分析以数字开头的情况*/
clnmb(text);
else if(find2(text[i])){ /*分析以分隔符开头的情况*/
if(text[i]=='{') key1++;
if(text[i]=='}') key2++;
if(text[i]=='[') key3++;
if(text[i]==']') key4++;
if(text[i]=='(') key5++;
if(text[i]==')') key6++;
string[0]=text[i];
if(text[i]=='\"'){ /*考虑其中可能出现的一"开头的字符串类型常量*/
do{
string[j]=text[i];
j++;i++;
}while(text[i]!='\"');
string[j]=text[i];
i++;j++;
if(search(zfcclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(zfcclbhead,"\n\r%s\t",string);
fprintf(zfcclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(zfcclbhead,"\n\r%s\t",string);
fprintf(zfcclbhead,"4\t");
fprintf(zfcclbhead,"3\t");
fprintf(zfcclbhead,"%d\t\n\r",q); /*用q标记出现字符串常量的地址*/
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"4\t");
fprintf(ofhead,"3\t");
fprintf(ofhead,"%d\t\n\r",q);
q++;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}
if(text[i]=='\''){ /*考虑可能出现的一'开头的字符类型常量*/
string[0]=text[i];
while(text[i]!='\''){
string[j]=text[i];
i++;j++;
}
string[j]=text[i];
if(search(zfclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(zfclbhead,"\n\r%c\t",text[i]);
fprintf(zfclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
else{
fprintf(zfclbhead,"\n\r%c\t",text[i]);
fprintf(zfclbhead,"4\t");
fprintf(zfclbhead,"4\t");
fprintf(zfclbhead,"%d\t\n\r",p);
fprintf(ofhead,"\n\r%c\t",text[i]);
fprintf(ofhead,"4\t");
fprintf(ofhead,"4\t");
fprintf(ofhead,"%d\t\n\r",p);
p++;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}
if(text[i]=='#'){
i++;
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')){
string[j]=text[i];
j++;i++;
}
if(strcmp(string,"include")==0){ /*括入文件处理程序段*/
if(text[i]=='\"'||text[i]=='<')i++;
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z'||text[i]=='.')){
kuoru[x]=text[i];
i++;x++;
}
if((krhead=fopen(kuoru,"r"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
while(!(feof(krhead)))
text2[y++]=fgetc(krhead);
text2[y]='\0';
y=0;
temp=i;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
saomiao(text2);
i=temp;
for(x=0;x<30;x++)
kuoru[x]='\0';
x=0;
i++;
}
if(strcmp(string,"define")==0){
for(j=0;j<30;j++)
string[j]='\0';
j=0;
while(!(text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z'))i++;
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')||text[i]=='_'||(text[i]>='0'&&text[i]<='9')){
hm[k1][k2]=text[i];
i++;k2++;
}
k2=0;
while(!(text[i]>='0')&&(text[i]<='9'))i++;
while((text[i]>='0')&&(text[i]<='9')||text[i]=='.'||text[i]=='e'||text[i]=='E'||text[i]=='-'){
hz[k1][k2]=text[i];
i++;k2++;
}
k1++;
k2=0;
}
}else{
if(search(fgfhead,string));
else{
fprintf(fgfhead,"\n\r%c\t",text[i]);
fprintf(fgfhead,"1\t");
fprintf(fgfhead,"%d\t\n\r",bianma2(text[i]));
}
fprintf(ofhead,"\n\r%c\t",text[i]);
fprintf(ofhead,"1\t");
fprintf(ofhead,"%d\t\n\r",bianma2(text[i]));
i++;
}
}else if(find3(text[i])){ /*分析一运算符开头的情况*/
while(find3(text[i])){
string[j]=text[i];
i++;j++; /*考虑到有多个字符组成的运算符,运算符的判断使用字符串*/
}
if(strcmp(string,"/*")==0){
while(!(text[i-1]=='*'&&text[i]=='/'))i++; /*去掉注释*/
if(text[i]=='/')i++;
}
if(strcmp(string,"//")==0)
while(!(text[i]=='\n'))
i++; /*去掉注释*/
if((bianma3(string)==-1)&&text[i-1]=='-'){
i=i-1;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
clnmb(text); /*处理负数的情况*/
}
if(search(ysfhead,string));
else{
if(bianma3(string)!=-1){
fprintf(ysfhead,"\n\r%s\t",string);
fprintf(ysfhead,"2\t");
fprintf(ysfhead,"%d\t\n\r",bianma3(string));
}
}
if(bianma3(string)!=-1){
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"2\t");
fprintf(ofhead,"%d\t\n\r",bianma3(string));
}
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else i++;
}
}
int main(){
printf("********************\nc语言分析程序\n********************\n");
printf("\n请输入文件名:");
scanf("%s",fn);
if((sfhead=fopen(fn,"r"))==NULL){
printf("不能打开源文件!\n");
exit(0);
}
if((ofhead=fopen("分解源文件所得文件.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((bsfhead=fopen("标识符表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((zsclbhead=fopen("整数常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((fdsclbhead=fopen("浮点数常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((zfclbhead=fopen("字符常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((zfcclbhead=fopen("字符串常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((fgfhead=fopen("分隔符表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((ysfhead=fopen("运算符表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((blzhead=fopen("保留字表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
fprintf(ofhead,"单词\t");
fprintf(ofhead,"类\t");
fprintf(ofhead,"编号\t地址\t\n\r");
fprintf(bsfhead,"单词\t");
fprintf(bsfhead,"类\t");
fprintf(bsfhead,"编号\t地址\t\n\r");
fprintf(zsclbhead,"单词\t");
fprintf(zsclbhead,"类\t");
fprintf(zsclbhead,"编号\t地址\t\n\r");
fprintf(zfclbhead,"单词\t");
fprintf(zfclbhead,"类\t");
fprintf(zfclbhead,"编号\t地址\t\n\r");
fprintf(zfcclbhead,"单词\t");
fprintf(zfcclbhead,"类\t");
fprintf(zfcclbhead,"编号\t地址\t\n\r");
fprintf(fdsclbhead,"单词\t");
fprintf(fdsclbhead,"类\t");
fprintf(fdsclbhead,"编号\t地址\t\n\r");
fprintf(fgfhead,"单词\t");
fprintf(fgfhead,"类\t");
fprintf(fgfhead,"编号\t地址\t\n\r");
fprintf(ysfhead,"单词\t");
fprintf(ysfhead,"类\t");
fprintf(ysfhead,"编号\t地址\t\n\r");
fprintf(blzhead,"单词\t");
fprintf(blzhead,"类\t");
fprintf(blzhead,"编号\t地址\t\n\r"); /*初始化所需要的文件*/
while(!feof(sfhead)) /*将原程序读入字符数组便于后面分析*/
text1[i++]=fgetc(sfhead);
text1[i++]='\0';
i=0;
saomiao(text1);
if(key1!=key2)
printf("ERROR:前后大括号个数不相等。\n");
if(key3!=key4)
printf("ERROR:前后中括号个数不相等。\n");
if(key5!=key6)
printf("ERROR:前后小括号个数不相等。\n");
while(z!=0){
printf("打印:\n1分析源文件所得文件\n2保留字表\n3分隔符表\n4运算符表\n5标识符表\n6整数类型常量表\n7浮点数类型常量表\n8字符类型常量表\n9字符串类型常量表\n\n0退出程序");
printf("\n\n请输入:");
scanf("%d",&z);
switch(z){
case 1 :{printf("**********分析源文件所得文件**********\n");dayin(ofhead);break;}
case 2 :{printf("***************保留字表***************\n");dayin(blzhead);break;}
case 3 :{printf("***************分隔符表***************\n");dayin(fgfhead);break;}
case 4 :{printf("***************运算符表***************\n");dayin(ysfhead);break;}
case 5 :{printf("***************标识符表***************\n");dayin(bsfhead);break;}
case 6 :{printf("************整数类型常量表************\n");dayin(zsclbhead);break;}
case 7 :{printf("***********浮点数类型常量表***********\n");dayin(fdsclbhead);break;}
case 8 :{printf("************字符类型常量表************\n");dayin(zfclbhead);break;}
case 9 :{printf("***********字符串类型常量表***********\n");dayin(zfcclbhead);break;}
case 10 :exit(0);
}
}
fclose(ofhead);
fclose(sfhead);
fclose(bsfhead);
fclose(fgfhead);
fclose(ysfhead);
fclose(blzhead);
fclose(fdsclbhead);
fclose(zfclbhead);
fclose(zfcclbhead);
fclose(zsclbhead);
}
热心网友
时间:2023-10-15 14:56
很好写的,看着编译书上的步骤,在参考下资料,自己写就行了。
热心网友
时间:2023-10-15 14:56
以前学c语言的时候写的,但是没有经过很好的设计,程序结构比较乱。运行没有问题。也可以处理包含的头文件。
/*************************************************
c语言分析程序
*************************************************/
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
char *key[]={"auto","bool","break","case","char","complex","const","continue","default","restrict","do","double","else","enum","extern","float","for","goto","if","imaginary","inline","int","long","register","return","stort","signed","sizeof","static","struct","switch","tyepdef","union","unsigned","void","volatile","while"};
char *limit[]={"#","(",")","[","]","'","\"",";",":","{","}","\\",","};
char *ysf[]={"!","%","^","&","*","-","+","=","~","|",".","<",">","/","?",":","+=","-=","*=","/","%=","<<=",">>=","&=","^=","|=","->","++","--","<<",">>","<=",">=","==","!=","&&","||"};
char b[30];
char fn[20]={'\0'},text1[1000]={'\0'},string[30]={'\0'},text2[1000]={'\0'},kuoru[30];
char hm[10][30],hz[10][30];
char * tempp;
int z=1,y;
int i=0,j=0,k=1,n=1,p=1,q=1,o=1,m=1,x=0,temp,k1=0,k2=0,keyy,key1=0,key2=0,key3=0,key4=0,key5=0,key6=0;
FILE * sfhead;
FILE * ofhead;
FILE * bsfhead;
FILE * zsclbhead;
FILE * fdsclbhead;
FILE * zfclbhead;
FILE * zfcclbhead;
FILE * fgfhead;
FILE * ysfhead;
FILE * blzhead;
FILE * krhead;
bool find1(char * p){
int i=0;
for(i=0;i<36;i++){
if(strcmp(key[i],p)==0)
return true;
}
return false;
} /*判断提取的字符串是否属于保留字*/
int bianma1(char * p){
int i=0;
for(i=0;i<36;i++){
if(strcmp(key[i],p)==0)
return i+1;
}
return -1; /*确定保留字的序号*/
}
bool find2(char p){
int i=0;
for(i=0;i<13;i++){
if(*limit[i]==p)
return true;
}
return false;
} /*判断提取的符号是否为分隔符*/
int bianma2(char p){
int i=0;
for(i=0;i<13;i++){
if(*limit[i]==p)
return i+1;
}
return -1;
} /*确定分割符的序号*/
bool find3(char p){
int i=0;
for(i=0;i<37;i++){
if(*ysf[i]==p)
return true;
}
return false;
} /*判断提取的符号是否为运算符*/
int bianma3(char * p){
int i=0;
for(i=0;i<37;i++){
if(strcmp(ysf[i],p)==0)
return i+1;
}
return -1;
} /*确定运算符的序号*/
int bianma4(char * p){
int i=0;
for(i=0;i<10;i++){
if(strcmp(hm[i],p)==0)
return i;
}
return -1;
}
bool search(FILE * fp,char * p){
char a[30],c[30];
rewind(fp); /*将fp指向文件头部*/
while(!feof(fp)){
fscanf(fp,"%s",a);
if(strcmp(a,p)==0){ /*保存编码*/
fgets(b,30,fp);
return true;
}else
fgets(c,30,fp);
}
return false;
}
void clnmb(char * text){ /*处理以数字开头的函数*/
bool l=true;
string[j]=text[i];
i++;j++;
while(((text[i]>='0')&&(text[i]<='9'))||text[i]=='.'||text[i]=='e'||text[i]=='E'||text[i]=='-'){
string[j]=text[i];
if(text[i]=='.')
l=false;
i++;j++; /*判断数字字符串中有无小数点,如果有则证明位浮点数*/
}
if(l){
if(search(zsclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(zsclbhead,"\n\r%s\t",string);
fprintf(zsclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(zsclbhead,"\n\r%s\t",string);
fprintf(zsclbhead,"4\t");
fprintf(zsclbhead,"0\t");
fprintf(zsclbhead,"%d\t\n\r",m);
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"4\t");
fprintf(ofhead,"0\t");
fprintf(ofhead,"%d\t\n\r",m);
m++; /*用m标记出现整数常量的地址*/
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}else{
if(search(fdsclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(fdsclbhead,"\n\r%s\t",string);
fprintf(fdsclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(fdsclbhead,"\n\r%s\t",string);
fprintf(fdsclbhead,"4\t");
fprintf(fdsclbhead,"1\t");
fprintf(fdsclbhead,"%d\t\n\r",o);
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"4\t");
fprintf(ofhead,"1\t");
fprintf(ofhead,"%d\t\n\r",o); /*用o标记出现的浮点数常量地址*/
o++;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
l=true;
}
}
void dayin(FILE * fp){
int i;
char temp[40];
rewind(fp);
while(!feof(fp)){
fgets(temp,40,fp);
printf("%s",temp);
}
for(i=0;i<40;i++)
temp[i]='\0';
}
/****************************************
扫描分析程序段
*****************************************/
void saomiao(char * text){
i=0;
while(text[i]!='\0'){
if((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')){ /*分析以字母开头的情况*/
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')||text[i]=='_'||(text[i]>='0'&&text[i]<='9')){
string[j]=text[i];
i++;j++;
}
if(find1(string)){ /*判断是否为保留字*/
fprintf(blzhead,"\n\r%s\t",string);
fprintf(blzhead,"0\t");
fprintf(blzhead,"%d\t\n\r",bianma1(string));
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"0\t");
fprintf(ofhead,"%d\t\n\r",bianma1(string)); /*将字符串直接写入相应的文件和输出文件*/
for(j=0;j<30;j++) /*将string数组清空,防止出现错误*/
string[j]='\0';
j=0;
}
else {
if((keyy=bianma4(string))!=-1){
temp=i;
tempp=text;
i=0;
for(j=0;j<30;j++) /*将string数组清空,防止出现错误*/
string[j]='\0';
j=0;
clnmb(hz[keyy]);
text=tempp;
i=temp;
}else
if(search(bsfhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(bsfhead,"\n\r%s\t",string);
fprintf(bsfhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(bsfhead,"\n\r%s\t",string);
fprintf(bsfhead,"3\t");
fprintf(bsfhead,"%d\t\n\r",k);
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"3\t");
fprintf(ofhead,"%d\t\n\r",k);
k++; /*用k标记出现标识符的地址*/
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}
}
else if((text[i]>='0')&&(text[i]<='9')) /*分析以数字开头的情况*/
clnmb(text);
else if(find2(text[i])){ /*分析以分隔符开头的情况*/
if(text[i]=='{') key1++;
if(text[i]=='}') key2++;
if(text[i]=='[') key3++;
if(text[i]==']') key4++;
if(text[i]=='(') key5++;
if(text[i]==')') key6++;
string[0]=text[i];
if(text[i]=='\"'){ /*考虑其中可能出现的一"开头的字符串类型常量*/
do{
string[j]=text[i];
j++;i++;
}while(text[i]!='\"');
string[j]=text[i];
i++;j++;
if(search(zfcclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(zfcclbhead,"\n\r%s\t",string);
fprintf(zfcclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else{
fprintf(zfcclbhead,"\n\r%s\t",string);
fprintf(zfcclbhead,"4\t");
fprintf(zfcclbhead,"3\t");
fprintf(zfcclbhead,"%d\t\n\r",q); /*用q标记出现字符串常量的地址*/
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"4\t");
fprintf(ofhead,"3\t");
fprintf(ofhead,"%d\t\n\r",q);
q++;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}
if(text[i]=='\''){ /*考虑可能出现的一'开头的字符类型常量*/
string[0]=text[i];
while(text[i]!='\''){
string[j]=text[i];
i++;j++;
}
string[j]=text[i];
if(search(zfclbhead,string)){ /*返回原表查询,防止重复出现*/
fprintf(zfclbhead,"\n\r%c\t",text[i]);
fprintf(zfclbhead,"%s",b);
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
else{
fprintf(zfclbhead,"\n\r%c\t",text[i]);
fprintf(zfclbhead,"4\t");
fprintf(zfclbhead,"4\t");
fprintf(zfclbhead,"%d\t\n\r",p);
fprintf(ofhead,"\n\r%c\t",text[i]);
fprintf(ofhead,"4\t");
fprintf(ofhead,"4\t");
fprintf(ofhead,"%d\t\n\r",p);
p++;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}
}
if(text[i]=='#'){
i++;
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')){
string[j]=text[i];
j++;i++;
}
if(strcmp(string,"include")==0){ /*括入文件处理程序段*/
if(text[i]=='\"'||text[i]=='<')i++;
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z'||text[i]=='.')){
kuoru[x]=text[i];
i++;x++;
}
if((krhead=fopen(kuoru,"r"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
while(!(feof(krhead)))
text2[y++]=fgetc(krhead);
text2[y]='\0';
y=0;
temp=i;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
saomiao(text2);
i=temp;
for(x=0;x<30;x++)
kuoru[x]='\0';
x=0;
i++;
}
if(strcmp(string,"define")==0){
for(j=0;j<30;j++)
string[j]='\0';
j=0;
while(!(text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z'))i++;
while((text[i]>='a'&&text[i]<='z')||(text[i]>='A'&&text[i]<='Z')||text[i]=='_'||(text[i]>='0'&&text[i]<='9')){
hm[k1][k2]=text[i];
i++;k2++;
}
k2=0;
while(!(text[i]>='0')&&(text[i]<='9'))i++;
while((text[i]>='0')&&(text[i]<='9')||text[i]=='.'||text[i]=='e'||text[i]=='E'||text[i]=='-'){
hz[k1][k2]=text[i];
i++;k2++;
}
k1++;
k2=0;
}
}else{
if(search(fgfhead,string));
else{
fprintf(fgfhead,"\n\r%c\t",text[i]);
fprintf(fgfhead,"1\t");
fprintf(fgfhead,"%d\t\n\r",bianma2(text[i]));
}
fprintf(ofhead,"\n\r%c\t",text[i]);
fprintf(ofhead,"1\t");
fprintf(ofhead,"%d\t\n\r",bianma2(text[i]));
i++;
}
}else if(find3(text[i])){ /*分析一运算符开头的情况*/
while(find3(text[i])){
string[j]=text[i];
i++;j++; /*考虑到有多个字符组成的运算符,运算符的判断使用字符串*/
}
if(strcmp(string,"/*")==0){
while(!(text[i-1]=='*'&&text[i]=='/'))i++; /*去掉注释*/
if(text[i]=='/')i++;
}
if(strcmp(string,"//")==0)
while(!(text[i]=='\n'))
i++; /*去掉注释*/
if((bianma3(string)==-1)&&text[i-1]=='-'){
i=i-1;
for(j=0;j<30;j++)
string[j]='\0';
j=0;
clnmb(text); /*处理负数的情况*/
}
if(search(ysfhead,string));
else{
if(bianma3(string)!=-1){
fprintf(ysfhead,"\n\r%s\t",string);
fprintf(ysfhead,"2\t");
fprintf(ysfhead,"%d\t\n\r",bianma3(string));
}
}
if(bianma3(string)!=-1){
fprintf(ofhead,"\n\r%s\t",string);
fprintf(ofhead,"2\t");
fprintf(ofhead,"%d\t\n\r",bianma3(string));
}
for(j=0;j<30;j++)
string[j]='\0';
j=0;
}else i++;
}
}
int main(){
printf("********************\nc语言分析程序\n********************\n");
printf("\n请输入文件名:");
scanf("%s",fn);
if((sfhead=fopen(fn,"r"))==NULL){
printf("不能打开源文件!\n");
exit(0);
}
if((ofhead=fopen("分解源文件所得文件.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((bsfhead=fopen("标识符表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((zsclbhead=fopen("整数常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((fdsclbhead=fopen("浮点数常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((zfclbhead=fopen("字符常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((zfcclbhead=fopen("字符串常量表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((fgfhead=fopen("分隔符表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((ysfhead=fopen("运算符表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
if((blzhead=fopen("保留字表.txt","wb+"))==NULL){
printf("不能建立目标文件!");
exit(0);
}
fprintf(ofhead,"单词\t");
fprintf(ofhead,"类\t");
fprintf(ofhead,"编号\t地址\t\n\r");
fprintf(bsfhead,"单词\t");
fprintf(bsfhead,"类\t");
fprintf(bsfhead,"编号\t地址\t\n\r");
fprintf(zsclbhead,"单词\t");
fprintf(zsclbhead,"类\t");
fprintf(zsclbhead,"编号\t地址\t\n\r");
fprintf(zfclbhead,"单词\t");
fprintf(zfclbhead,"类\t");
fprintf(zfclbhead,"编号\t地址\t\n\r");
fprintf(zfcclbhead,"单词\t");
fprintf(zfcclbhead,"类\t");
fprintf(zfcclbhead,"编号\t地址\t\n\r");
fprintf(fdsclbhead,"单词\t");
fprintf(fdsclbhead,"类\t");
fprintf(fdsclbhead,"编号\t地址\t\n\r");
fprintf(fgfhead,"单词\t");
fprintf(fgfhead,"类\t");
fprintf(fgfhead,"编号\t地址\t\n\r");
fprintf(ysfhead,"单词\t");
fprintf(ysfhead,"类\t");
fprintf(ysfhead,"编号\t地址\t\n\r");
fprintf(blzhead,"单词\t");
fprintf(blzhead,"类\t");
fprintf(blzhead,"编号\t地址\t\n\r"); /*初始化所需要的文件*/
while(!feof(sfhead)) /*将原程序读入字符数组便于后面分析*/
text1[i++]=fgetc(sfhead);
text1[i++]='\0';
i=0;
saomiao(text1);
if(key1!=key2)
printf("ERROR:前后大括号个数不相等。\n");
if(key3!=key4)
printf("ERROR:前后中括号个数不相等。\n");
if(key5!=key6)
printf("ERROR:前后小括号个数不相等。\n");
while(z!=0){
printf("打印:\n1分析源文件所得文件\n2保留字表\n3分隔符表\n4运算符表\n5标识符表\n6整数类型常量表\n7浮点数类型常量表\n8字符类型常量表\n9字符串类型常量表\n\n0退出程序");
printf("\n\n请输入:");
scanf("%d",&z);
switch(z){
case 1 :{printf("**********分析源文件所得文件**********\n");dayin(ofhead);break;}
case 2 :{printf("***************保留字表***************\n");dayin(blzhead);break;}
case 3 :{printf("***************分隔符表***************\n");dayin(fgfhead);break;}
case 4 :{printf("***************运算符表***************\n");dayin(ysfhead);break;}
case 5 :{printf("***************标识符表***************\n");dayin(bsfhead);break;}
case 6 :{printf("************整数类型常量表************\n");dayin(zsclbhead);break;}
case 7 :{printf("***********浮点数类型常量表***********\n");dayin(fdsclbhead);break;}
case 8 :{printf("************字符类型常量表************\n");dayin(zfclbhead);break;}
case 9 :{printf("***********字符串类型常量表***********\n");dayin(zfcclbhead);break;}
case 10 :exit(0);
}
}
fclose(ofhead);
fclose(sfhead);
fclose(bsfhead);
fclose(fgfhead);
fclose(ysfhead);
fclose(blzhead);
fclose(fdsclbhead);
fclose(zfclbhead);
fclose(zfcclbhead);
fclose(zsclbhead);
}
热心网友
时间:2023-10-15 14:56
很好写的,看着编译书上的步骤,在参考下资料,自己写就行了。