简单C语言编译器编译原理.docx
- 文档编号:5080992
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:30
- 大小:48.55KB
简单C语言编译器编译原理.docx
《简单C语言编译器编译原理.docx》由会员分享,可在线阅读,更多相关《简单C语言编译器编译原理.docx(30页珍藏版)》请在冰豆网上搜索。
简单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;//illegalcharacterreturn(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;i one=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; 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<<"第"< "< 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<<"第"< 号连接错误! "< )&& (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<<"第"< ‘"< "< } } 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<<"第"< 误! "< find=find->next; } intj=0; for(i=0;i s_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<<"错误! 第"< "< } q=ip=(structStack*)malloc(sizeof(structStack)); ip->name='$'; for(i=0;i else \n" if((ip->name=='('&&word_fu[i]->mark_name==')')||(ip->name=='{'&&word_fu[i]->mark_name= ='}'))MarkPop(ip); else cout<<"错 误! 第"< 行, "< ”存在符号 匹配错误 ! "< if(ip->name! ='$')cout<<"错误 ! 第 "< 行, "< ”存在符号 匹配错误 ! "< cout<<"\n< } //=====================================================================//初始化分析表函数: Relation*FirstRelation() //数据传递: r_head返回分析表的头指针 Relation*FirstRelation(){ Relation*r_head,*r_find,*r_new; r_head=NULL; //状态 intsr[][13]={{2,1},{100},{3},{4},{5},{6},{12,15,16,17,18,10,11,7,9,13,14,8},{19}, {12,4,15,16,17,18,10,11,20,9,13,14,8},{21},{22},{23},{24},{6},{26,25}, {8},{9},{10},{11},{1},{3},{12,15,16,17,18,10,11,28,14,27},{33,34,32,29,30,31}, {33,34,32,35,30,31},{42,41,43,36,37,38,39,40},{44,7},{13,13},{2,2,2,2,2,2,2,2},{5}, {47,46},{18,48,18},{20,20,20},{33,34,32,49,30,31},{27,27,51,52,54,53,27},{50},{47,59},{60,83},{29,61,29,29},{31,31,62,31,31},{33,33,63,33,33,33,},{35,35,35,35,35,35},{42,41,43,64,37,38,39,40},{37,37,37,37,37,37},{38,38,38,38,38,38},{45},{12,12},{65},{33,34,32,66,31},{33,34,32,67},{47,82},{26,26,26},{55},{56},{57},{58},{22,22,22},{23,23,23},{24,24,24}, {25,25,25},{68},{42,41,43,69,38,39,40},{42,41,43,70,3
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 简单 语言 编译器 编译 原理
![提示](https://static.bdocx.com/images/bang_tan.gif)