简单C语言编译器编译原理.docx
- 文档编号:6991872
- 上传时间:2023-01-15
- 格式:DOCX
- 页数:34
- 大小:25.01KB
简单C语言编译器编译原理.docx
《简单C语言编译器编译原理.docx》由会员分享,可在线阅读,更多相关《简单C语言编译器编译原理.docx(34页珍藏版)》请在冰豆网上搜索。
简单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;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; }//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<<"第"< "< 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<<"第"< "< 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<<"第"< "< } } 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 if((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<<"错误! 第"< "< if(ip->name! ='$')cout<<"错误! 第"< "< cout<<"\n============================================================\n"< } //================================================================
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 简单 语言 编译器 编译 原理