简单C语言编译器编译原理.docx
《简单C语言编译器编译原理.docx》由会员分享,可在线阅读,更多相关《简单C语言编译器编译原理.docx(41页珍藏版)》请在冰点文库上搜索。
简单C语言编译器编译原理
#include
#include
#include
#include
#include
#include
#include
#include
#defineNULL0
structStack//栈结构体:
序号、内容、连接下一结点指针
{
intnum;
charname;
structStack*next;
};
structGuiyue//规则集结构体:
序号、规则长度、符号、连接下一结点指针
{
intnum;
intcount;
charname;
structGuiyue*next;
};
structRelation//分析表结构体:
状态序号、对应符号列、操作类型的对应序号、操作类型、连接下一结点指针
{
intline_States;
charrank_Letter;
intrelationship;
charname;
structRelation*next;
};
structSign//符号表结构体:
自变量名、标识类型、连接下一结点指针
{
charname[20];
charkind;
structSign*next;
};
structWord//单词表结构体:
单词名字、标识类型、状态、序号、行号、连接符号表指针、连接下一结点指针
{
charname[20];
charmark_name;
intstate;
intnum;
intline;
structSign*link;
structWord*next;
};
FILE*fp1;//文件指针
introw=1,line[10000],Lin[300],w_num;//字符行变量、字符行、单词所在行、字符数
charbuffer[10000];//字符串缓冲区
Stack*MarkPush(Stack*ip,charmark,intI_i)//压栈
{
Stack*s;
s=(Stack*)malloc(sizeof(Stack));
s->name=mark;
s->num=I_i;
s->next=ip;
ip=s;
returnip;
}
voidMarkPop(Stack*ip)//出栈
{
Stack*q;
charname;
name=ip->name;
q=ip->next;
if(ip->next!
=NULL)
{
ip->name=ip->next->name;
ip->num=ip->next->num;
ip->next=ip->next->next;
free(q);
}
}
intjudge(charch)//接收ch判断字符,变量flag返回字符类别
{
intflag;
if(ch=='!
'||ch=='$'||ch=='&'||ch=='*'||ch=='('||ch==')'||ch=='-'||ch=='_'||
ch=='+'||ch=='='||ch=='|'||ch=='{'||ch=='}'||ch=='['||ch==']'||ch==';'||
ch==':
'||ch=='"'||ch=='<'||ch==','||ch=='>'||ch=='.'||ch=='/'||ch=='\'')
flag=1;
elseif('0'<=ch&&ch<='9')
flag=2;
elseif(('a'<=ch&&ch<='z')||('A'<=ch&&ch<='Z'))
flag=3;
elseif(ch=='')
flag=4;
elseif(ch=='\n')
flag=5;
elseif(ch=='?
')
flag=6;
elseif(feof(fp1))
flag=7;//结束
else
flag=0;//illegalcharacter
return(flag);
}
//======================================================================================================
//词法分析函数:
voidscan()
//数据传递:
形参fp接收指向文本文件头的文件指针;
//全局变量buffer与line对应保存源文件字符及其行号,char_num保存字符总数。
voidscan()
{
charch;
intflag,j=0,i=-1;
while(!
feof(fp1))
{
ch=fgetc(fp1);
flag=judge(ch);
printf("%c",ch);//显示打开的文件
if(flag==1||flag==2||flag==3){i++;buffer[i]=ch;line[i]=row;}
elseif(flag==4){i++;buffer[i]='?
';line[i]=row;}
elseif(flag==5){i++;buffer[i]='~';row++;}
elseif(flag==7)continue;
elsecout<<"\n请注意,第"<"<}
w_num=i;
/*****************确定单词所在的行*****************/
intone,two,k=0;
for(i=0;ione=judge(buffer[i]);
two=judge(buffer[i+1]);
if((one!
=two&&buffer[i]!
='?
'&&buffer[i]!
='~')||one==1){
Lin[k]=line[i];
k++;
}
}
}
//======================================================================================================
//初始化单词表函数:
structWord*InitWord()
//数据传递:
head返回单词表的头指针
//备注:
初始化单词表函数包括分割单词、标识单词、生成变量符号表、完善单词属性表四个功能
structWord*InitWord(){
structWord*head,*ft,*news,*p;
structSign*s_first,*s_look;
s_first=s_look=(structSign*)malloc(sizeof(structSign));
s_first->kind='\0';
s_first->name[0]='\0';
news=head=ft=(structWord*)malloc(sizeof(structWord));
ft->link=s_first;
ft->next=NULL;
//====================================分割单词功能==========================================================
inti=0,k,flag,jud=0;
for(k=0;k{
flag=judge(buffer[k]);
if(jud==0){//1~
if(flag==2||flag==3){
news->name[i]=buffer[k];
news->name[++i]='\0';
}
else{//2~
i=0;
ft=news;
if(news->name[0]>=33&&news->name[0]<=125){
news=(structWord*)malloc(sizeof(structWord));
ft->next=news;
news->next=NULL;
}
if(flag==1){//3~
if(buffer[k]=='/'&&buffer[k+1]=='/')jud=1;
elseif(buffer[k]=='/'&&buffer[k+1]=='*')jud=2;
else{//4~
news->name[i]=buffer[k];
if((buffer[k]=='='&&buffer[k+1]=='=')||(buffer[k]=='&'&&buffer[k+1]=='&')||
(buffer[k]=='|'&&buffer[k+1]=='|')||(buffer[k]=='>'&&buffer[k+1]=='=')||
(buffer[k]=='<'&&buffer[k+1]=='=')||(buffer[k]=='!
'&&buffer[k+1]=='=')){
k=k+1;
i=i+1;
printf("%d",i);
news->name[i]=buffer[k];
}
news->name[1+i]='\0';
ft=news;
news=(structWord*)malloc(sizeof(structWord));
ft->next=news;
news->next=NULL;
}//4~
}//3~
}//2~
}//1~
elseif(jud==1)
if(buffer[k]=='~')jud=0;
else;
elseif(jud==2)
if(buffer[k]=='*'&&buffer[k+1]=='/'){jud=0;k=k+1;}
else;
}
if(news->name[0]<33||news->name[0]>125)ft->next=NULL;
/*******************单词转换成标识符*******************/
ft=head;
while(ft){
if(strcmp(ft->name,"main")==0){ft->mark_name='m';}
elseif(strcmp(ft->name,"void")==0){ft->mark_name='v';}
elseif(strcmp(ft->name,"while")==0){ft->mark_name='w';}
elseif(strcmp(ft->name,"if")==0){ft->mark_name='f';}
elseif(strcmp(ft->name,"else")==0){ft->mark_name='e';}
elseif(strcmp(ft->name,"int")==0){ft->mark_name='a';}
elseif(strcmp(ft->name,"float")==0){ft->mark_name='b';}
elseif(strcmp(ft->name,"double")==0){ft->mark_name='d';}
elseif(strcmp(ft->name,"char")==0){ft->mark_name='c';}
elseif(ft->name[0]>='0'&&ft->name[0]<='9'){ft->mark_name='n';}
elseif(ft->name[0]=='+'||ft->name[0]=='-'||ft->name[0]=='*'||ft->name[0]=='/'
||ft->name[0]=='='||ft->name[0]=='<'||ft->name[0]=='>'
||ft->name[0]==','||ft->name[0]==';'||ft->name[0]=='('||ft->name[0]==')'
||ft->name[0]=='{'||ft->name[0]=='}'){ft->mark_name=ft->name[0];}
elseif(strcmp(ft->name,"&&")==0){ft->mark_name='&';}
elseif(strcmp(ft->name,"||")==0){ft->mark_name='|';}
elseif(strcmp(ft->name,"!
=")==0){ft->mark_name='@';}
elseif(strcmp(ft->name,"==")==0){ft->mark_name='#';}
else{ft->mark_name='i';}
ft=ft->next;
}
/********************初始化单词表的序号和行号********************/
i=0;
ft=head;
while(ft){
ft->num=i;
ft->line=Lin[i];
i++;
ft=ft->next;
}
/*************************初始化符号表*************************/
ft=head;
charword_type;
while(ft){//1~
if(ft->mark_name=='a'||ft->mark_name=='b'||ft->mark_name=='c'||ft->mark_name=='d'){//2~
p=ft->next;
word_type=ft->mark_name;
while(p->mark_name!
=';'){
if(p->mark_name!
=','){
s_look=(structSign*)malloc(sizeof(structSign));
s_look->kind=word_type;
strcpy(s_look->name,p->name);
s_first->next=s_look;
s_first=s_look;
s_look->next=NULL;
}
p=p->next;
}
ft=p;
}//2~
ft=ft->next;
}//1~
return(head);
}
//=====================================================================================================
//正确性检测函数:
FindWordDeclare(Word*head)
//数据传递:
*head:
单词表的头指针.
//备注:
查找保留字是否被声名和符号是否对称.
voidFindWordDeclare(Word*head){
structSign*s_first;
structWord*find,*w_name[1000],*word_fu[100];
structStack*ip,*q;
inti,cal=0,ca=0,end;
find=head;
cout<while(find){
if(find->mark_name=='i'){
w_name[cal]=find;
cal++;
}
if(find->next!
=NULL){
if((find->mark_name==find->next->mark_name)&&(find->mark_name!
='{')&&
(find->mark_name!
='}')&&(find->mark_name!
='(')&&(find->mark_name!
=')'))
cout<<"第"<line<<"行,‘"<mark_name<<"’存在字符重复错误!
"<elseif((find->mark_name=='i'&&find->next->mark_name=='}')||(find->mark_name==','&&find->next->mark_name=='}')||
(find->mark_name==','&&find->next->mark_name==';')||(find->mark_name==';'&&find->next->mark_name==',')||
(find->mark_name=='('&&find->next->mark_name==',')||(find->mark_name==','&&find->next->mark_name=='(')||
(find->mark_name==')'&&find->next->mark_name==';')||(find->mark_name==')'&&find->next->mark_name==',')||
(find->mark_name==')'&&find->next->mark_name=='}')){
cout<<"第"<line<<"行,"<name<<"处存在符号连接错误!
"<if((find->mark_name=='a'||find->mark_name=='b'||find->mark_name=='c'||find->mark_name=='d')&&
(find->next->mark_name=='}'||find->next->mark_name=='{'||find->next->mark_name==','||
find->next->mark_name==';'||find->next->mark_name=='('||find->next->mark_name==')'||
find->next->mark_name=='+'||find->next->mark_name=='-'||find->next->mark_name=='*'||
find->next->mark_name=='/'||find->next->mark_name=='&'||find->next->mark_name=='>'||
find->next->mark_name=='<'||find->next->mark_name=='='||find->next->mark_name=='!
'||
find->next->mark_name=='@'||find->next->mark_name=='n'))
cout<<"第"<line<<"行,‘"<mark_name<<"’存在自变量声明搭配错误!
"<}
}
if(find->mark_name=='('||find->mark_name==')'||find->mark_name=='{'||find->mark_name=='}'){
word_fu[ca]=find;
ca++;
}
if(find->name[0]>='0'&&find->name[0]<='9'&&find->name[1]>='a'&&find->name[1]<='z')
cout<<"第"<line<<"行,"<name<<"存在变量声明错误!
"<find=find->next;
}
intj=0;
for(i=0;is_first=head->link;
end=1;
while(s_first&&end){
if(strcmp(s_first->name,w_name[i]->name)==0)end=0;
elses_first=s_first->next;
}
if(end==1&&i!
=cal-1)cout<<"错误!
第"<line<<"行,变量"<name<<"没有被声明!
"<}
q=ip=(structStack*)malloc(sizeof(structStack));
ip->name='$';
for(i=0;iif((word_fu[i]->mark_name=='(')||(word_fu[i]->mark_name=='{'))ip=MarkPush(ip,word_fu[i]->mark_name,i);
elseif((ip->name=='('&&word_fu[i]->mark_name==')')||(ip->name=='{'&&word_fu[i]->mark_name=='}'))MarkPop(ip);
elsecout<<"错误!
第"<line<<"行,“"<name<<"”存在符号匹配错误!
"<if(ip->name!
='$')cout<<"错误!
第"<line<<"行,“"<name<<"”存在符号匹配错误!
"<cout<<"\n============================================================\n"<}
//============================================================================
|