简单C语言编译器(编译原理)

简单C语言编译器(编译原理)
简单C语言编译器(编译原理)

#include

#include

#include

#include

#include

#include

#include

#include

#define NULL 0

struct Stack // 栈结构体: 序号、内容、连接下一结点指针

{

int num;

char name;

struct Stack *next;

};

struct Guiyue// 规则集结构体:序号、规则长度、符号、连接下一结点指针

{

int num;

int count;

char name;

struct Guiyue *next;

};

struct Relation // 分析表结构体:状态序号、对应符号列、操作类型的对应序号、操作类型、连接下一结点指针

{

int line_States ;

char rank_Letter;

int relationship;

char name;

struct Relation *next;

};

struct Sign // 符号表结构体: 自变量名、标识类型、连接下一结点指针

{

char name[20];

char kind;

struct Sign *next;

};

struct Word // 单词表结构体: 单词名字、标识类型、状态、序号、行号、连接符号表指针、连接下一结点指针

{

char name[20];

char mark_name;

int state;

int num;

int line;

struct Sign *link;

struct Word *next;

};

FILE *fp1;//文件指针

int row=1,line[10000],Lin[300],w_num;//字符行变量、字符行、单词所在行、字符数char buffer[10000];//字符串缓冲区

Stack *MarkPush(Stack *ip,char mark,int I_i)//压栈

{

Stack *s;

s=(Stack *)malloc(sizeof(Stack));

s->name=mark;

s->num=I_i;

s->next=ip;

ip=s;

return ip;

}

void MarkPop(Stack *ip)//出栈

{

Stack *q;

char name;

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);

}

}

int judge(char ch)// 接收ch判断字符,变量flag返回字符类别

{

int flag;

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;

else if('0'<=ch&&ch<='9')

flag=2;

else if(('a'<=ch&&ch<='z')||('A'<=ch&&ch<='Z'))

flag=3;

else if(ch==' ')

flag=4;

else if(ch=='\n')

flag=5;

else if(ch=='?')

flag=6;

else if(feof(fp1))

flag=7;//结束

else

flag=0; //illegal character

return(flag);

}

//===================================================================== =================================

// 词法分析函数: void scan()

// 数据传递: 形参fp接收指向文本文件头的文件指针;

// 全局变量buffer与line对应保存源文件字符及其行号,char_num保存字符总数。

void scan()

{

char ch;

int flag,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;}

else if(flag==4) {i++;buffer[i]='?';line[i]=row;}

else if(flag==5) {i++;buffer[i]='~';row++;}

else if(flag==7) continue;

else cout<<"\n请注意,第"<

}

w_num=i;

/*****************确定单词所在的行*****************/

int one,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++;

}

}

}

//===================================================================== =================================

// 初始化单词表函数: struct Word *InitWord()

// 数据传递: head返回单词表的头指针

// 备注: 初始化单词表函数包括分割单词、标识单词、生成变量符号表、完善单词属性表四个功能

struct Word *InitWord(){

struct Word *head,*ft,*news,*p;

struct Sign *s_first,*s_look;

s_first=s_look=(struct Sign *)malloc(sizeof(struct Sign));

s_first->kind='\0';

s_first->name[0]='\0';

news=head=ft=(struct Word *)malloc(sizeof(struct Word));

ft->link=s_first;

ft->next=NULL;

//====================================分割单词功能========================================================== int i=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=(struct Word *)malloc(sizeof(struct Word));

ft->next=news;

news->next=NULL;

}

if(flag==1){//3~

if(buffer[k]=='/'&&buffer[k+1]=='/') jud=1;

else if(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=(struct Word *)malloc(sizeof(struct Word));

ft->next=news;

news->next=NULL;

}//4~

}//3~

}//2~

}//1~

else if(jud==1)

if(buffer[k]=='~') jud=0;

else ;

else if(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';}

else if(strcmp(ft->name,"void")==0){ft->mark_name='v';}

else if(strcmp(ft->name,"while")==0){ft->mark_name='w';}

else if(strcmp(ft->name,"if")==0){ft->mark_name='f';}

else if(strcmp(ft->name,"else")==0){ft->mark_name='e';}

else if(strcmp(ft->name,"int")==0){ft->mark_name='a';}

else if(strcmp(ft->name,"float")==0){ft->mark_name='b';}

else if(strcmp(ft->name,"double")==0){ft->mark_name='d';}

else if(strcmp(ft->name,"char")==0){ft->mark_name='c';}

else if(ft->name[0]>='0'&&ft->name[0]<='9'){ft->mark_name='n';}

else if(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];} else if(strcmp(ft->name,"&&")==0){ft->mark_name='&';}

else if(strcmp(ft->name,"||")==0){ft->mark_name='|';}

else if(strcmp(ft->name,"!=")==0){ft->mark_name='@';}

else if(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;

char word_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=(struct Sign *)malloc(sizeof(struct Sign));

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:单词表的头指针.

// 备注: 查找保留字是否被声名和符号是否对称.

void FindWordDeclare(Word *head){

struct Sign *s_first;

struct Word *find,*w_name[1000],*word_fu[100];

struct Stack *ip,*q;

int i,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<<" ’存在字符重复错误!"<

else

if((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;

}

int j=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;

else s_first=s_first->next;

}

if(end==1&&i!=cal-1) cout<<"错误! 第"<line<<" 行,变量"<name<<" 没有被声明!"<

}

q=ip=(struct Stack *)malloc(sizeof(struct Stack));

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);

else

if((ip->name=='('&&word_fu[i]->mark_name==')')||(ip->name=='{'&&word_fu[i]->mark_name= ='}')) MarkPop(ip);

else cout<<"错误! 第"<line<<" 行,“"<name<<" ”存在符号匹配错误! "<

if(ip->name!='$') cout<<"错误! 第"<line<<" 行,“"<name<<" ”存在符号匹配错误!"<

cout<<"\n============================================================\n" <

}

//===================================================================== =================================

//初始化分析表函数: Relation *FirstRelation()

// 数据传递: r_head返回分析表的头指针

Relation *FirstRelation(){

Relation *r_head,*r_find,*r_new;

r_head=NULL;

//状态

int sr[][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,39,40},{42,41,43,71,40},

{42,41,43,72},{60,73},{12,15,16,17,18,10,11,74,9,13,14,8},{17,48,17}, {19,19,19},{12,15,16,17,18,10,11,75,9,13,14,8},{28,61,28,28},{30,30,62,30,30},

{32,32,63,32,32,32},{34,34,34,34,34,34},{36,36,36,36,36,36},{77},{76},

{15,15,15,15,15,15,15,15},{78},{79},{12,15,16,17,18,10,11,80,9,13,14,8},

{81},{14,14,14,14,14,14,14,14},{21,21,21},{16,16,16,16,16,16,16,16}};

//以上状态对应的操作类别

char SS[][14]={"ss","o","s","s","s","s","ssssssssssss","s","srsssssssssss","s","s","s","s"

,"r","ss","r","r","r","r","r","r","ssssssssss","ssssss","ssssss","ssssssss","sr"

,"rr","rrrrrrrr","r","ss","rsr","rrr","ssssss","rrssssr","s","ss","ss","rsrr","rrsrr"

,"rrsrrr","rrrrrr","ssssssss","rrrrrr","rrrrrr","s","rr","s","sssss","ssss"

,"ss","rrr","s","s","s","s","rrr","rrr","rrr","rrr","s","sssssss","ssssss"

,"sssss","ssss","ss","ssssssssssss","rsr","rrr","ssssssssssss","rsrr","rrsrr"

,"rrsrrr","rrrrrr","rrrrrr","s","s","rrrrrrrr","s","s","ssssssssssss","s"

,"rrrrrrrr","rrr","rrrrrrrr"};

//状态的个数

int cal[84]={2,1,1,1,1,1,12,1,13,1,1,1,1,1,2,1,1,1,1,1,1,10,6,6,8,2,2,8,1,2,3,3,6,7,1,2,2,4,5,6,

6,8,6,6,1,2,1,5,4,2,3,1,1,1,1,3,3,3,3,1,7,6,5,4,2,12,3,3,12,4,5,6,6,6,1,1,8,1,1,12,1,8,3,8};

//以上状态在action和goto中对应的列

char Let[][14]={{'v','Q'},{'$'},{'m'},{'('},{')'},{'{'},{'i','a','b','c','d','f','w','A',

'C','X','Y','S'},{'}'},{'i','}','a','b','c','d','f','w','A','C','X','Y','S'},{';'},

{'('},{'('},{'='},{';'},{'i','Z'},{'i'},{'i'},{'i'},{'i'},{'$'},{'}'},{'i','a',

'b','c','d','f','w','X','Y','S'},{'i','!','(','E','H','G'},{'i','!','(','E','H','G'

},{'i','(','n','L','I','K','T','F'},{',',';'},{',',';'},{'i','}','a','b','c','d','f','w'},{';'},{'&',')'},

{'&','|',')'},{'&','|',')'},{'i','!','(','E','H','G'},{'&','|','<','>','@','#',

')'},{'i'},{'&',')'},{'+',';'},{'+','-',';',')'},{'+','-','/',';',')'},{'+','-',

'*','/',';',')'},{'+','-','*','/',';',')'},{'i','(','n','L','I','K','T','F'},

{'+','-','*','/',';',')'},{'+','-','*','/',';',')'},{'i'},{',',';'},{'{'},{'i',

'!','(','H','G'},{'i','!','(','G'},{'&',')'},{'&','|',')'},{'i'},{'i'},{'i'},

{'i'},{'&','|',')'},{'&','|',')'},{'&','|',')'},{'&','|',')'},{'{'},{'i','(',

'n','I','K','T','F'},{'i','(','n','K','T','F'},{'i','(','n','T','F'},{'i','(',

'n','F'},{'+',')'},{'i','a','b','c','d','f','w','A','C','X','Y','S'},{'&','|',

')'},{'&','|',')'},{'i','a','b','c','d','f','w','A','C','X','Y','S'},{'+','-',

';',')'},{'+','-','/',';',')'},{'+','-','*','/',';',')'},{'+','-','*','/',';',

')'},{'+','-','*','/',';',')'},{'}'},{'}'},{'i','}','a','b','c','d','f','w'},

{'e'},{'{'},{'i','a','b','c','d','f','w','A','C','X','Y','S'},{'}'},{'i','}',

'a','b','c','d','f','w'},{'&','|',')'},{'i','}','a','b','c','d','f','w','}'}};

//初始化关系表

for(int i=0;i<84;i++){

for(int j=0;j

r_new=(Relation *)malloc(sizeof(Relation));

if(r_head==NULL){

r_find=r_head=r_new;

}

r_new->line_States=i;

r_new->rank_Letter=Let[i][j];

r_new->relationship=sr[i][j];

r_new->name=SS[i][j];

r_find->next=r_new;

r_find=r_new;

r_new->next=NULL;

}

}

return r_head;

}

//===================================================================== =================================

//初始化规则表函数: Guiyue *guiyue()

// 数据传递: g_head返回规则表的头指针

Guiyue *FirstGuiyue(){

Guiyue *g_head,*g_find,*g_new;

g_head=NULL;

//规约

char root[]={'B','Q','S','A','A','C','C','X','Y','Y','Y','Y','Z','Z','S','S','S','E','E','H',

'H','G','G','G','G','G','G','G','L','L','I','I','K','K','T','T','F','F','F'};

int LR[]={1,7,3,2,1,3,1,2,1,1,1,1,3,1,11,7,4,3,1,3,1,3,3,3,3,3,2,1,3,1,3,1,3,1,3,1,3,1,1};

//初始化规则表

for(int i=0;i<39;i++){

g_new=(Guiyue *)malloc(sizeof(Guiyue));

if(g_head==NULL){

g_find=g_head=g_new;

}

g_new->num=i;

g_new->count=LR[i];

g_new->name=root[i];

g_find->next=g_new;

g_find=g_new;

g_new->next=NULL;

}

return g_head;

}

//=====================================================================

=================================

//语法分析函数: int ResultAnely(Relation *r_head,Stack *s_head,char str[],Guiyue *g_head,int cal)

// 数据传递: 1 *r_head:分析表头指针.

// 2 *s_head:符号栈头指针.

// 3 str[] :转义字符流.

// 4 *g_head:规则表头指针.

// 5 cal :转义字符流的长度.

int ResultAnely(Relation *r_head,Stack *s_head,char str[],Guiyue *g_head,int cal){ Relation *r_find;

Guiyue *g_find;

Stack *s_find,*s_look;

s_find=s_head;

int j,v,admition=1,goon=1,in,out=1,hang=-1,count;

char stack[200],name;

// cout<<"\n===================显--示--语--法--分--析--过--程--及--结--果==================="<

// cout<<" LineNum StackData inputSentence\n"<

while(goon){//:1

int admit=1;

r_find=r_head;

g_find=g_head;

hang++;

while(r_find&&admit){//:2

if(r_find->line_States==s_find->num&&r_find->rank_Letter==str[0]&&r_find->name=='s') {//:入栈

s_find=MarkPush(s_find,str[0],r_find->relationship);

admit=0;

for(in=0;in

str[in]='\0';

cal--;

r_find=r_find->next;

}//:入栈~

if(r_find->line_States==s_find->num&&r_find->rank_Letter==str[0]&&r_find->name=='r'){ //:规约

g_find=g_head;

int g=r_find->relationship;

while(g) {g_find=g_find->next;g--; }

name=g_find->name;

count=g_find->count;

admit=0;

for(int k=0;k

MarkPop(s_find);

}

r_find=r_head;

int a=1;

while(r_find&&a){

if(r_find->line_States==s_find->num && r_find->rank_Letter==name){

s_find=MarkPush(s_find,name,r_find->relationship);

a=0;

}

r_find=r_find->next;

}

}//:规约~

if(r_find->line_States==s_find->num&&r_find->rank_Letter==str[0]&&r_find->name=='o') {//:2判断运算结束

admit=0;

goon=0;

out=0;

cout<<"\nSuccession !"<

return(1);

}

r_find=r_find->next;

}//:2~

/* if(out==1)//显示语法分析结果

{

s_look=s_find;

v=0;

while(s_look)

{

stack[v]=s_look->name;

s_look=s_look->next;

v++;

}

cout<

for(j=v-1;j>=0;j--)

{

cout<

if(stack[j]=='i'){v++;}

}

for(j=0;j<10-v;j++){cout<<" ";}

cout<<" "<

cout<

}*/

if(admit==1){ //判断输入流是否正确,如在分析表中找不到关系,则输入流错误goon=0;

cout<<"\nInput Flow Error !"<

return(0);

}

}//1:~

cout<<"\n****************************************\n"<

}

//===================================================================== =================================

// 算术表达式四元式函数: void ProduceStyle(char str[],int order_num)

// 数据传递:1.str[] :转义字符流.

// 2 order_num :表达式所在行.

void ProduceStyle(char str[],int order_num){

struct FourStyle{

char Word,Opr1,Opr2,Result;

int num;

struct FourStyle *next;

};

struct Stack *stack_a,*stack_b;

char temp;

struct FourStyle *f_head,*f_find,*f_new;

stack_a=(struct Stack *)malloc(sizeof(struct Stack));

stack_a->name='$';

stack_a->next=NULL;

stack_b=(struct Stack *)malloc(sizeof(struct Stack));

stack_b->name='#';

stack_b->next=NULL;

f_head=NULL;

int admit,cal,four;

four=1;// 四元式序号

cal=0;

admit=1;

while(admit){

if(str[cal]=='='){

stack_a=MarkPush(stack_a,str[cal],cal);

cal++;

}

else

if(stack_b->name=='#'||stack_b->name=='+'||stack_b->name=='-'||stack_b->name=='*'||stack_b->n ame=='/')

{

if((str[cal]>='a')&&(str[cal]<='z')||(str[cal]>='0')&&(str[cal]<='9')){

stack_a=MarkPush(stack_a,str[cal],cal);

cal++;

}

else if(str[cal]=='('){

stack_b=MarkPush(stack_b,'#',cal);

cal++;

}

else

if((stack_b->name=='#')&&(str[cal]=='+'||str[cal]=='-'||str[cal]=='*'||str[cal]=='/')){

stack_b=MarkPush(stack_b,str[cal],cal);

cal++;

}

else if((stack_b->name=='#')&&(str[cal]==')')){

MarkPop(stack_b);

cal++;

}

else if((stack_b->name=='#')&&(str[cal]==';')){

admit=0;

}

else

if(stack_b->name=='+'||stack_b->name=='-'||stack_b->name=='*'||stack_b->name=='/'){

if((stack_b->name=='+'||stack_b->name=='-')&&(str[cal]=='*'||str[cal]=='/')){

stack_b=MarkPush(stack_b,str[cal],cal);

cal++;

}

else{

if(f_head==NULL){

f_new=(struct FourStyle *)malloc(sizeof(struct FourStyle));

f_find=f_new;

f_head=f_find;

}

else{

f_new=(struct FourStyle *)malloc(sizeof(struct FourStyle));

f_find->next=f_new;

f_find=f_new;

f_new->next=NULL;

}

f_new->num=order_num;

f_new->Word=stack_b->name;

MarkPop(stack_b);

f_new->Opr2=stack_a->name;

MarkPop(stack_a);

f_new->Opr1=stack_a->name;

MarkPop(stack_a);

temp=four+65;

f_new->Result=temp;

stack_a=MarkPush(stack_a,f_new->Result,cal);

four++;

}

}

}

if(cal!=3&&admit==0&&str[cal]==';'){

f_new=(struct FourStyle *)malloc(sizeof(struct FourStyle));

f_new->num=order_num;

f_new->Opr1=stack_a->name;

MarkPop(stack_a);

f_new->Word=stack_a->name;

MarkPop(stack_a);

f_new->Opr2='_';

f_new->Result=stack_a->name;

MarkPop(stack_a);

f_find->next=f_new;

f_find=f_new;

f_new->next=NULL;

four++;

}

else if(cal==3&&admit==0&&str[cal]==';'){

f_new=(struct FourStyle *)malloc(sizeof(struct FourStyle));

f_new->num=order_num;

f_new->Opr1=stack_a->name;

MarkPop(stack_a);

f_new->Word=stack_a->name;

MarkPop(stack_a);

f_new->Opr2='_';

f_new->Result=stack_a->name;

f_head=f_new;

f_new->next=NULL;

four++;

}

}

f_find=f_head;

while(f_find){

/*cout.width(20);*/cout<num<<" "<Word<<" "<Opr1<<" "<Opr2<<" "<Result<

f_find=f_find->next;

}

}

//===================================================================== =================================

// 布尔表达式四元式函数: void BoolStyle(char str[],int order_num)

// 数据传递:1.str[] :转义字符流.

// 2 order_num :表达式所在行.

void BoolStyle(char str[],int order_num){

struct FourStyle{

char Word,Opr1,Opr2;

int Order,num;

struct FourStyle *next;

};

struct FourStyle *b_head,*b_find,*b_new,*p[100];

b_head=NULL;

int cal,admit,i=0;

admit=1;

cal=0;

while(admit){

if(str[cal]!='|'&&str[cal]!='&'){

if(b_head==NULL){

b_find=b_new=(struct FourStyle *)malloc(sizeof(struct FourStyle));

b_head=b_find;

p[i]=b_find;

i++;

}

else{

b_new=(struct FourStyle *)malloc(sizeof(struct FourStyle));

p[i]=b_new;i++;

b_find->next=b_new;

b_find=b_new;

b_new->next=NULL;

}

b_new->Opr1=str[cal];cal++;

b_new->Word=str[cal];cal++;

b_new->Opr2=str[cal];cal++;

b_new->num=order_num;

b_new->Order=0;

b_new=(struct FourStyle *)malloc(sizeof(struct FourStyle));

p[i]=b_new;i++;

b_new->Opr1='_';

b_new->Word='j';

b_new->Opr2='_';

b_new->num=order_num;

b_new->Order=0;

b_find->next=b_new;

b_find=b_new;

b_new->next=NULL;

}

else if(str[cal]=='|'){

p[i-1]->Order=p[i-1]->num+1;

cal++;

}

else if(str[cal]=='&'){

p[i-2]->Order=p[i-2]->num+2;

cal++;

}

if(str[cal]=='$'){

admit=0;

p[0]->Order=order_num;

p[i-2]->Order=p[i-2]->num+2;

if(str[cal-4]=='&'){

p[i-1]->Order=p[i-3]->num;

}

}

}

b_find=b_head;

while(b_find){

cout<num<<" "<Word<<" "<Opr1<<" "<Opr2<<" "<Order<

b_find=b_find->next;

}

}

//===================================================================== =================================

// 显示四元式函数: FourStyle(int goon,Word *head)

// 数据传递:1.goon :语法分析成功标志

// 2 head :单词表头指针.

void FourStyle(int goon,Word *head){

Word *find;

find=head;

int jishu=0,order_num=1;

char str1[20];

cout<

while(goon){

if(find->next->mark_name=='='){

order_num=find->line;

jishu=0;

while(find->mark_name!=';'){

str1[jishu]=find->name[0];

jishu++;

find=find->next;

}

str1[jishu]=';';

str1[jishu+1]='\0';

ProduceStyle(str1,order_num);

}

else if(find->mark_name=='f'||find->mark_name=='w'){ jishu=0;

find=find->next->next;

order_num=find->line;

while(find->next->mark_name!='{'){

str1[jishu]=find->name[0];

jishu++;

find=find->next;

}

str1[jishu]='$';

str1[jishu+1]='\0';

BoolStyle(str1,order_num);

}

else if(find->mark_name=='e'){

find=find->next->next;

order_num=find->line;

if(find->next->mark_name=='='){

jishu=0;

while(find->mark_name!=';'){

str1[jishu]=find->name[0];

jishu++;

find=find->next;

}

str1[jishu]=';';

str1[jishu+1]='\0';

ProduceStyle(str1,order_num);

}

else if(find->mark_name=='f'||find->mark_name=='w'){ order_num=find->line;

jishu=0;

find=find->next->next;

while(find->next->mark_name!='{'){

str1[jishu]=find->name[0];

jishu++;

find=find->next;

}

str1[jishu]='$';

str1[jishu+1]='\0';

BoolStyle(str1,order_num);

}

}

find=find->next;

if(find->next==NULL){goon=0;}

}

cout<

}

//===================================================================== =================================

// 打印表格函数: Print(int t,Word *head,FILE *fp,Relation *r_head)

// 数据传递:1.t :打印表格类别标志

// 2 head :单词表头指针.

// 3 fp :规则表文件指针.

// 4 r_head:分析表头指针.

void Print(int t,Word *head,FILE *fp,Relation *r_head){

struct Word *w_look;

struct Sign *s_look;

struct Relation *r_new;

int i=0;

switch(t){

case 1:

{ cout<

w_look=head;

while(w_look){

if(i==30) {cout<<" "<mark_name<

else {cout<<" "<mark_name;i++;}

w_look=w_look->next;

}

break;

}

case 2:

{

cout<

w_look=head;

cout<<"WordNumber WordLine WordName

一个简单的C语言编译器

个简单的C语言编译器 源代码: // // #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include #include #include #include #include #include using namespace std; class Symbol { public: int line; string word; char group; Symbol(); Symbol(const Symbol &b); virtual ~Symbol(); operator =(const Symbol &b); string code; };

class Label { public: Label(); virtual ~Label(); string text; private: int n; static int next(); static int _label; }; class Action { public: static int lookUp(char v,int s); private: Action(); ~Action(); static int Table[54][19]; static string vs; }; class Goto { public: static int lookUp(char v,int s); private: Goto(); ~Goto(); static int Table[54][9]; static string vs; }; class Compiler {

一个简单编译器的实现

基于flex与bison的一个简单编译器的研究与实践 [摘要]编译是程序执行过程中一个重要的步骤,分为词法分析、语法分析、语义分析、中间代码生成、中间代码优化、机器代码生成、机器代码优化几个步骤。本文使用flex与bison 工具,编写了简洁的代码,实现了对一个简单语言的简单程序的词法分析、语法分析,最后生成了相应的抽象语法树。得出了flex与bison是编写词法分析器和语法分析器的有效工具的结论。 [关键词] 编译抽象语法树词法语法程序 目录 摘要 第一章绪论 1.1 为什么要用编译器 1.2 编译步骤 第二章简单编译器的研究与实现 2.1 简单编译器的结构 2.2 词法分析 2.3 语法分析 2.4 语义分析 第三章实验结果 全文总结 第一章绪论 1.1 为什么要用编译器 在计算机中,程序可以用不同的语言来编写,比如C,C++,汇编语言,机器代码等。计算机能够直接识别的只有机器代码,因此需要编译器来将其他语言编译成机器代码,或者将一种语言编译成另一种语言[1]。 编译器是一个计算机程序(或一系列程序),它能将用程序语言写的源代码编译成计算机能够识别的目标代码,后者往往是二进制代码[2]。 近年来基本的编译器设计都没多大的改变,而且它们正迅速地成为计算机科学课程中的中心一环。[5] 1.2 编译步骤 1.2.1 预处理 一个较为复杂的程序可能被分割为多个模块,并存放于对应的源文件中。预处理器是一个程序,它把源程序拼接在一起,并把宏转化为源语言的语句[3]。 1.2.2 词法分析 经过预处理的源程序会作为输入传递给编译器,词法分析是编译的第一个步骤。词法分析器以字符流的形式读入源程序,将它们组织成有意义的单词(token)[3]。flex是一种词法分析工具,它基于lex做了改进,能够更快地生成C语言词法分析程序。 1.2.3 语法分析 语法分析是编译的第二个步骤。在这个步骤中,根据语言的语法识别词法分析后得到的字符流,生成语法树。为了能够为应用程序提供清晰简洁的接口,隐藏复杂的底层信息,抽象语法树仅仅设计了有实际意义的节点。Bison是一种语法分析工具,它基于YACC做了改进,能够自动生成C语言语法分析程序。

C++课程设计报告(简易文本编辑器)

面向对象程序设计课程设计报告 (2011/2012学年第二学期) 题目名称简单文本编辑器的设计 系部 专业计算机科学与技术 班级 学生 完成时间 2012年 6 月 指导老师

在文本编辑器出现前,人们用打孔机把计算机文字打到穿孔卡片上。文字存放于一个装着这样的薄卡片的盒子里,可以用读卡器来阅读它。 第一个文本编辑器是一种行编辑器,它运行在打字机型的终端上,这种编辑器并不具备在窗口和屏幕中显示的功能。它包含了一些非常短的命令(为了减少打字量)。其中一个命令能够把文件的指定部分通过打字机打印出来。编辑光标是想象中的一个插入点,通过特殊命令,可以把它移动到特定内容字符串所在的行。随后,内容字符串又被扩展成正则表达式。如果想看到文件的变化,你需要把它打印出来。相对于穿孔机来说,人们认为这种基于行的文本编辑器具有革命性的进步。如果没有它,用户就需要把那些处理文本的命令打成专用的卡片,并在编辑文件时使用这些卡片。 当带有显示屏的计算机终端出现后,基于显示屏的文本编辑器开始流行起来。最早的全屏编辑器中,有一种叫做O26,它是于1967年为CDC 6000系列机器的操作控制台而作的。另外一个早期的全屏编辑器是vi。vi诞生于20世纪70年代,至今,它仍是Unix和Linux的标准编辑器。全屏编辑器对视频终端的销售起到了促进的作用。 文本编辑器在Windows的应用中是一个非常重要的项目,在过去十数年中,微软对windows文本编辑器有多个版本的升级改进,而基于其他的编程环境的文本编辑器也是多如牛毛,今天我们用MFC可视化编译环境做一个简易的文本编辑器。

引言 (2) 1.课程设计目的和意义 (4) 2.详细设计 (4) 2.1需求描述 (4) 2.1.1文件 (4) 2.1.2编辑 (4) 2.1.3应用 (5) 2.1.4帮助 (5) 2.1.5高级 (5) 2.2功能描述 (5) 2.2.1文本编辑区 (5) 2.2.2文件 (7) 2.2.3编辑 (15) 2.2.4应用 (16) 2.2.5帮助 (21) 2.2.6高级 (22) 2.2.7菜单栏 (25) 2.2.7图标 (26) 2.3程序运行说明 (27) 3.课程设计总结 (30) 3.1编程日志 (30) 3.3测试报告 (31) 4.心得体会 (31) 5.参考文献 (31)

编译原理课程设计报告-简单文法的编译器的设计与实现

提供全套毕业论文,各专业都有 课程设计报告 设计题目:简单文法的编译器的设计和实现 班级:计算机1206 组长学号: 组长姓名: 指导教师: 设计时间:2014年12月 摘要 编译原理是计算机科学和技术专业一门重要的专业课, 它具有很强的理论性和实践性,目的是系统地向学生介绍编译系统的结构、工作原理以及编译程序各组成部分的设计原理和实现技术,在计算机本科教学中占有十分重要的地位。计算机语言之所以能由单一的机器语言发展到现今的数千种高级语言,就是因为有了编译技术。编译技术是计算机科学中发展得最迅速、最成熟的一个分支,它集中体现了计算机发展的成果和精华。 本课设是词法分析、语法分析、语义分析的综合,外加上扩展任务中间代码的优化和目标代码的生成,主要是锻炼学生的逻辑思维能力,进一步理解编译原理的方法和步骤。 关键词:编译原理,前端,目标代码,后端

目录 摘要 (3) 1. 概述 (6) 2. 课程设计任务及要求 (8) 2.1 设计任务 (8) 2.2 设计要求 (9) 3. 算法及数据结构 (10) 3.1算法的总体思想 (10) 3.2 词法分析器模块 (11) 3.2.1 功能 (11) 3.2.2 数据结构 (11) 3.2.3 算法 (12) 3.3 语法分析器模块 (13) 3.3.1功能 (13) 3.3.2 数据结构 (13) 3.3.3算法 (14) 3.4 中间代码产生器模块 (24) 3.4.1 功能 (24) 3.4.2 数据结构 (24) 3.4.3 算法 (25) 3.5 优化器模块 (27) 3.5.1 功能 (27) 3.5.2 数据结构 (27) 3.5.3 算法 (28) 3.6 目标代码生成器模块 (30) 3.6.1功能 (30) 3.6.2 数据结构 (30) 3.6.3 算法 (31)

实验报告简单Simple语言编译器的实现

《编译原理》课程设计报告 简单Simple语言编译器的实现 学院(系):计算机科学与技术学院 班级:0404102 学生姓名:李超学号24 指导教师:张华 时间:从2007年3月6日到2007年3月16日

《编译原理》课程设计 目录 1、课程设计的目的 (2) 2、课程设计的内容及要求 (2) 2.1、设计符号表 (2) 2.2、语法分析与中间代码产生器 (2) 3、实现原理 (3) 3.1、词法分析原理 (3) 3.2、语法分析原理 (3) 3.3、语义分析原理 (4) 4、算法实现流程图 (4) 4.1、词法分析算法实现流程图 (4) 4.2、语法分析算法实现流程图 (5) 4.3、语义分析算法实现流程图 (6) 5、测试数据 (6) 6、结果输出及分析 (7) 7、软件运行环境及限制 (11) 8、心得体会 (11) 9、参考文献 (11)

1、课程设计的目的 1.锻炼编写程序的能力,提高自己利用某种编程语言编写应用程序的能力, 从而提高自己的综合能力。 2.熟悉编译原理词法分析、语法分析和语义分析的方法和原理,进一步掌 握《编译原理》课堂上老师所讲的知识点,了解和掌握编译程序的工作 原理,加深对基本方法的了解。 3.进一步的理解编译原理,更好的的学习它的一些思路,掌握编译原理的 理论基础。进一步理解高级语言在计算机中的执行过程,加深对编译原 理中重点算法和编译技术的理解,提高自己的编程能力,培养好的程序 设计风格。同时通过某种可视化编程语言(如vc++)的应用,具备初步的 Windows环境下的编程思想。 2、课程设计的内容及要求 2.1、设计符号表 确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。要考虑能够存储有关名字的信息,并可以高效地完成如下操作: a.查找:根据给定的名字,在符号表中查找其信息。如果该名字在符号表中不存在,则将其加入到符号表中,否则返回指向该名字的指针; b.删除:从符号表中删除给定名字的表项。 1、设计词法分析器 设计各单词的状态转换图,并为不同的单词设计种别码。将词法分析器设计成供语法分析器调用的子程序。功能包括: a.具备预处理功能。将不翻译的注释等符号先滤掉,只保留要翻译的符号 串,即要求设计一个供词法分析调用的预处理子程序; b.能够拼出语言中的各个单词; c.将拼出的标识符填入符号表; d.返回(种别码,属性值) 2.2、语法分析与中间代码产生器 要求用LL1 、递归下降、算符优先分析法、SLR分析法等方法之一或若干方法,实现对表达式、各种说明语句、控制语句进行语法分析。

编译原理课程设计一个简单编译器的设计与分析

摘要 使用过现代计算机的人都知道,多数用户是应用高级语言来实现他们所需要的计算的。现在计算机系统一般都含有不只一个的高级语言的编译程序,对有些高级语言甚至配置了几个不同性能的编译程序,供用户按不同需要进行选择。高级语言编译程序是计算机系统软件最主要的组成部分之一,也是用户最直接关系的工具之一。 计算机上执行一个高级语言程序一般分为两步:第一,用一个编译程序把高级语言翻译成机器语言程序;第二,运行所得的机器语言程序求得计算结果。 通常说的翻译程序是指能够把某一种语言程序转换成另一种语言程序(目标语言程序)。如果源语言诸如Fortran,Pascal,C,Ada或java这样的高级语言,而目标程序是诸如汇编语言或者机器语言这类的低级语言,这样的一个翻译程序就是称为编译程序。 一个编译程序的工作过程一般可以划分为五个阶段:词法分析、语法分析、语义分析与中间代码生成、优化、目标代码生成。每个阶段都是从上一个阶段得到结果,对他进行分析,并且根据一些外部环境(例如符号表等)得到最终的输出结果。要构造一个编译程序,可以按照这样的阶段来分别构造,最后来连调。 现在人们已经建立了多种编制部分编译程序或整个编译程序的有效工具。有些能用于自动生成扫描器(如LEX),有些可以用于自动产生语法分析器(如YACC),有些甚至可以用来自动产生整个的编译程序。这些构造编译程序的工具成为编译程序-编译程序、编译程序产生器或翻译程序书写系统,他们是按照编译程序和目标语言的形式描述而自动产生编译程序的。 编译程序是一极其庞大而又复杂的系统,掌握它比较苦难。但是一旦对其掌握,对以后的程序语言设计,系统软件分析,系统软件设计,形式语言研究等方面都是非常有好处的。 关键字:C语言、、编译、扫描器、语法分析

一种简单的编译器的设计

一种简单的编译器的设计 摘要:基于编译理论与虚拟机技术,经过词法分析、语法分析、语义分析等过程,设计一个简单的编译器,将某一种源程序编译成目标程序,以验证结果的正确性。 关键词:编译器;词法分析;语法分析;语义分析 中图分类号:TP311文献标识码:A文章编号: 1009-3044(2008)33-1508-03 The Design of a Simple Compiler CHENG Hua (Jiangsu Food Science College, Huaian 223003, China) Abstract: Based on compile theory and Virtual Machine technology,to transfer source program into destination program by Lexical analyse, Parse, Semantic analyse, and to test and verify the results. Key words: compiler; lexical analyse; parse; semantic analyse 1 设计背景 目前,计算机无纸化考试系统的应用越来越广,选择题、判断题的自动评分基本完善,但对程序修改题、编程题等考题来说,运用简单地看结果或指定行、段等办法评分,不能从根本上达到客观、公正地评阅考生答案。要想让计算机评

分具有智能化,就必须让计算机具备“思想”,即让评分系统能“看懂”考生答案,能“感受”设计成果的优越之处与不足所在,能给“过程分”及“设计创新分”,而绝不单纯依赖“运行结果”。本文以此为切入点,基于编译理论与虚拟机技术,自主设计有限元编译系统,分课程、分模块,能自行分析、编译考生答案(如程序代码),进而判断其正确性、合理性及优越性。 2 编译程序的一般结构 编译程序结构框图如图1。 3 编译器的设计 3.1 建立符号表及其管理程序 建立符号表,收录某种语言(C、PASCAL等)的所有字符集,允许在编译的各个阶段插入或查找名字的相关信息,并且能够反映出名字所在的位置,编制相应的程序来实现对字符表的各种操作,主要操作有:查找操作、插入操作、定位操作、重定位操作。 3.2 建立一个词法分析器 图1 核心技术是处理单词符号的种类及内部的编码(需要设计翻译表)、行计数器等,把词法分析器作为语法分析器调用的函数,词法分析器以二进制的形式输出单词符号的类别

编译原理课程设计 C语言编译器的实现

编译原理课程设计报告 设计题目编译代码生成器设计 学生姓名 班级 学号 指导老师 成绩

一、课程设计的目的 编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设计程序的能力,加深对编译理论知识的理解与应用。 二、课程设计的要求 1、明确课程设计任务,复习编译理论知识,查阅复印相关的编译资料。 2、按要求完成课程设计内容,课程设计报告要求文字和图表工整、思路清晰、算法正 确。 3、写出完整的算法框架。 4、编写完整的编译程序。 三、课程设计的内容 课程设计是一项综合性实践环节,是对平时实验的一个补充,课程设计内容包括课程的主要理论知识,但由于编译的知识量较复杂而且综合性较强,因而对一个完整的编译程序不适合平时实验。通过课程设计可以达到综合设计编译程序的目的。本课程的课程设计要求学生编写一个完整的编译程序,包括词法分析器、语法分析器以及实现对简单程序设计语言中的逻辑运算表达式、算术运算表达式、赋值语句、IF语句、While语句以及do…while语句进行编译,并生成中间代码和直接生汇编指令的代码生成器。 四、总体设计方案及详细设计 总体设计方案: 1.总体模块 主程序 词法分析程序语法分析 程序 中间代码 生成程序

2. 表2.1 各种单词符号对应的种别码 单词符号种别码单词符号种别码bgin 1 :17 If 2 := 18 Then 3 < 20 wile 4 <> 21 do 5 <= 22 end 6 > 23 lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ;26 —14 ( 27 * 15 ) 28 / 16 # 0 详细设计: 4.1界面导入设计 (1)一共三个选项: ①choice 1--------cifafenxi ②choice 2--------yufafenxi ③choice 3--------zhongjiandaima (2)界面演示 图一

一个简单文法的编译器前端的设计与实现

课程设计报告 设计题目:一个简单文法的编译器前端的设计与实现 班级:计算机1208班 组长学号:20124016 组长姓名:樊荣 指导教师:张俐 设计时间:2014年12月

设计分工 组长学号及姓名:20124016 樊荣 分工:四元式生成、语义分析(未定义、重定义等)、整体设计组员1学号及姓名:20124020 李鑫 分工:符号表建立及其输入输出设计 组员2学号及姓名:20124032 杨学良 分工:词法分析 组员3学号及姓名:20124018 焦通 分工:语法分析 组员4学号及姓名:201240 陈凤 分工:简单C语言文法设计及部分简单函数编写

摘要 编译器是程序员使用的关键工具,程序员每天都在使用编译器,并且非常依赖于其正确性和可靠性。编译器作为广大IT从业者必须接触的系统软件,它的设计本身又是一个极其庞大的工程。编译器相关的各项技术经过近几十年的发展,已经日臻成熟,然而编译器构造原理和技术依然是计算机科学中理论与实践相结合的最好典范。本文重点介绍了编译器前端的详细开发过程,分为四个部分分别阐述:文法设计,词法分析器的设计,语法分析器的设计,语义分析部分。每个部分又分别从功能,数据结构和算法三个方面进行详尽阐述,。由于C语言本身的复杂性,很难面面俱到实现所有标准定义,所以本次设计只象征性的选择部分具有代表性的功能。在本文的第四章详细给出了此次设计所实现的功能和语法规范,同时也给出了编译器的运行方式。 关键词:编译原理,编译器前端,C源程序……

目录 摘要 (1) 1 概述 (2) 2 课程设计任务及要求 (3) 2.1 设计任务 (3) 2.2 设计要求 (3) 3 算法与数据结构 (4) 3.1算法的总体思想(流程) (4) 3.2词法分析模块 (5) 3.2.1 功能 (7) 3.2.2 数据结构 (8) 3.2.3 算法 (9) 3.3 语法分析模块 (10) 3.3.1功能 (11) 3.3.2 数据结构 (12) 3.3.3算法 (13) 3.4 符号表模块 (13) 3.4.1功能 (13) 3.4.2 数据结构 (14) 4序设计与实现 (14) 4.1 程序流程图 (14) 4.2 程序说明 (15) 4.3 实验结果 (15) 5. 结论 (16) 6. 参考文献。 (17) 7. 收获、体会和建议。 (17)

编译原理-课程设计报告-简单编译器实现-精品

课程设计 题目:简单编译器实现 学院:信息工程学院计算机系专业:计算机科学与技术班级:计科1103班 组长: 小组成员: 指导教师: 2014 年12 月19 日

目录 1 概述 (3) 1.1源、目标语言简介 (3) 1.2实现平台与运行平台简介 (3) 1.3其它 (4) 2简单词法分析器的设计与实现 (4) 2.1 基础理论说明 (4) 2.2 需求分析 (4) 2.3 概要设计 (5) 2.4 详细设计 (5) 2.5 测试数据与结果 (7) 2.6 心得体会 (7) 3 简单语法分析器设计与实现 (8) 3.1 基础理论说明 (8) 3.2 需求分析 (8) 3.3 概要设计 (8) 3.4 详细设计 (8) 3.5 测试数据与结果 (9) 3.6 心得体会 (10) 4 中间代码产生器的设计与实现 (10) 4.1 基础理论说明 (10) 4.2 需求分析 (10) 4.3 概要设计 (10) 4.4 详细设计 (11) 4.5 测试数据与结果 (12) 4.6 心得体会 (12) 附录: (14) 附录A:主要源程序与系统截图 (14) 附录B:任务分配表及个人完成的程序模块 (33) 附录C:小组讨论与研发记录 (34)

编译程序的工作过程一般可以分为五个阶段:词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。每一个阶段在功能上是相对独立的,它一方面从上一个阶段获取分析的结果来进行分析,另一方面由将结果传递给下一个阶段。由编译程序的五个阶段就对应了编译系统的结构。 其中词法分析器利用超前搜索、状态转换等方法,将源程序转化成为一个一个的单词符号二元式。一般程序语言的单词符号包括关键字、运算符、常数、标识符和界符。语法分析器将这些单词符号作为输入,对它进行语法分析。语法分析分为两种方法:自上而下分析法和自下而上分析法。针对不同程序语言的语法规则可以采取不同的分析方法,当然两种方法也可以同时使用。语法分析器把语法单元作为输入供语义分析器使用。一般的语义分析器主要采用的是语法制导方法,即在语法分析的同时进行语法分析,并产生一定的语义动作,来生成中间代码。上面三个过程可以与硬件无关,而接下来的优化器和目标代码生成器是针对某一种处理器而言的。代码优化是将语义分析生成的中间代码进行优化,产生执行效率更高的代码。目标代码生成器最终生成可以在某种机器上运行的机器语言或者汇编语言。在整个编译过程中还包括对表格的操作和对错误的处理,这些也都是非常重要的环节。 1.1源、目标语言简介 使用C语言做简单语法分析器,C语言是一门高级计算机编程语言,设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言 1.2实现平台与运行平台简介 在win32环境下进行编译,Win32是指Microsoft Windows操作系统的32位环境,是目前使用最多的操作系统。 实验环境:需要TC、VC++ 6.0等开发工具作为本次试验的环境。

编译原理课程设计____C语言编译器的实现

南华大学 编译原理课程设计名:编译代生 成器设计 专业计算机科学与技术 学生姓名熊浩斌 班级计算机01班 学号 20109440114 指导老师陈星 实验地点 8栋 2-209 完成日期:2013.6.2

一、课程设计的目的 编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设计程序的能力,加深对编译理论知识的理解与应用。 二、课程设计的要求 1、明确课程设计任务,复习编译理论知识,查阅复印相关的编译资料。 2、按要求完成课程设计内容,课程设计报告要求文字和图表工整、思路清晰、算法正 确。 3、写出完整的算法框架。 4、编写完整的编译程序。 三、课程设计的内容 课程设计是一项综合性实践环节,是对平时实验的一个补充,课程设计内容包括课程的主要理论知识,但由于编译的知识量较复杂而且综合性较强,因而对一个完整的编译程序不适合平时实验。通过课程设计可以达到综合设计编译程序的目的。本课程的课程设计要求学生编写一个完整的编译程序,包括词法分析器、语法分析器以及实现对简单程序设计语言中的逻辑运算表达式、算术运算表达式、赋值语句、IF语句、While语句以及do…while语句进行编译,并生成中间代码和直接生汇编指令的代码生成器。 四、总体设计方案及详细设计 总体设计方案: 1.总体模块

简单编译器的设计与实现1

一、课程设计的目的 在学习《程序设计语言编译原理》课程过程中,结合各章节构造编译程序的基本理论分别完成词法分析器、语法分析器和语义分析器实验,在基本实验完成的基础上,逐步完成课程设计。针对自己的理解和学习,实现一个小编译器括符号表的构造,词法分析,语法分析,目标代码生成等重要子程序,其中词法分析、语法分析及语义分析功能必须完成),并对其进行分析解释和总结,同时将理论与实际应用结合起来,接受软件设计等开发过程的全面训练,从而提高软件开发的能力。 二、课程设计的任务 (1)设计符号表 确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。要考虑能够存储有关名字的信息,并可以高效地完成如下操作: a.查找:根据给定的名字,在符号表中查找其信息。如果该名字在符号表中不存在,则将其加入到符号表中,否则返回指向该名字的指针; b.删除:从符号表中删除给定名字的表项。 (2)设计词法分析器 设计各单词的状态转换图,并为不同的单词设计种别码。将词法分析器设计成供语法分析器调用的子程序。功能包括: a.具备预处理功能。将不翻译的注释等符号先滤掉,只保留要翻译的符号串, 即要求设计一个供词法分析调用的预处理子程序; b.能够拼出语言中的各个单词; c.将拼出的标识符填入符号表; d.返回(种别码,属性值)。 (3)语法分析器 要求用预测分析法、递归下降分析法、算符优先分析法、SLR分析法(几种方法任选),实现对表达式、各种说明语句、控制语句进行语法分析。 (4)目标代码生成器 能完成指定寄存器个数的情况下将一中间代码程序段翻译成汇编语言目标代码(汇编指令应包括加、减、乘、除),要求指令条数最少的情况下,尽量使

一个简单的C语言编译器

一个简单的C语言编译器 一.小组成员 朱嘉俊()计算机996 王筱()计算机996 朱杭()计算机996 朱林()计算机994 二.运行方式 在DOS环境下运行: Cminus.exe -h 三.概述 经过一段时间的学习,我们在初步掌握了编译器的基本原理以后,设计了一个具有基本编译功能的编译器。该编译器接受类C语言语法的源代码输入,输出结果是PC机的汇编源代码。在捆绑了宏汇编编译器Masm后,即可直接生成MSDOS下的二进制可执行文件。为方便起见,以下简称为C—语言编译器。 本编译器实现了基本高级语言所必须的语法要素,包括简单变量声明、函数的实现、整数和字符串运算、条件判断语句和循环语句及跳转语句、基本代数运算、赋值等,还支持汇编语言嵌入。本编译器是利用编译器生成器Parse Generator和VC6.0在Windows平台上实现的,并开发了一个基于Windows平台的32位编译集成开发环境CompilerMan,提供了关键字彩色提示、出错同屏提示、出错代码跳转等较为完善方便的功能。 由于编译程序本身涉及到词法分析、语法分析、代码生成、错误恢复和优化等诸多模块,要在实验中做到面面俱到不太可能,所以本编译器不可避免的会存在各种问题,但作为一个具有基本功能的、可扩充的系统,完全达到了巩固编译原理的理论知识,并将其运用于实践的目的。

四.背景 编译程序,就是一种具有编撰和翻译功能的程序。人们要用计算机来解决问题,首先面临的一个问题,就是要告诉计算机解决什么问题,或者告诉计算机如何解决这个问题。这就涉及到用什么样的语言来描述的问题,人所习惯的自然语言和计算机认识的机器语言有很大的差别,用机器语言来描述人想解决的问题十分不便,因而,计算机科学家设计一些人们比较习惯的语言来描述要解决的问题,称之为高级语言。用语言来描述的问题,统称为程序。然而,用高级语言写的程序,不能被计算机所直接认识和理解,必须经过等价的转换,变成机器能理解并执行的机器语言的程序。进行这种等价转换工作的工具,就是编译程序。 1.编译程序的结构 编译程序是很复杂的,但它可被分为相对独立的几个部分,每个部分承担专门的工作,各部分间互相共享传送数据。把编译程序分解成较小的部分,不仅便于开发、调试,而且便于编译程序的移植。一个典型的编译程序通常具有如图1的结构。 图1 编译器基本结构 1.1 词法分析 词法分析负责对源程序的字符串进行扫描和分解,根据构词法将字符流(Character Stream)转化成单词流(Token Stream)。

简单的C编译器(c语言实现)

#include #include #include #include #include #include using namespace std; #define NORW 16/*关键字个数为16*/ #define TXMAX 100 /*符号表长度最大为100*/ #define NMAX 10 /*数字最多为14位*/ #define AL 16 /*标识符最长为16*/ #define AMAX 2047 /*最大整数为2047*/ #define LEVMAX 3 /*过程调用最多为3层*/ #define CXMAX 200 /*生成的目标代码最多为200条*/ #define STACKSIZE 500 /*运行时数据栈元素最多为500个*/ char *symbol[36]={"nul","ident","number","plus","minus","times","slash","surplus","oddsym","xorsy m"//odd求奇slash除这里要添surplus 求余 "eql","neq","lss","leq","gtr","geq","lparen","rparen","comma", "semicolon","becomes","lbracketsym","rbracketsym","ifsym", "whilesym","switchsym","casesym","writesym","readsym", "repeatsym","untilsym","forsym","plusone","minusone", "constsym","intsym","voidsym"}; /*全部单词种类*/ char *word[NORW]={"break","call","case","const","for","if","int","odd","read","repeat","switch","unti l","void","while","write","xor"};/*关键字*/ //procedure 步骤这里要添case lbracket左括号rbracket右括号 /*关键字的类别标记*/ char *wsym[NORW]={"breaksym","callsym","casesym","constsym","forsym","ifsym","intsym","oddsy m","readsym","repeatsym","switchsym","untilsym","void","whilesym","writesym","xorsym"}; /*8条目标代码*/ char *mnemonic[8]={"lit","opr","lod","sto","cal","ini","jmp","jpc"}; char ch; /*当前读入的字符*/ char id[AL]; /*当前读入的单词*/

简单行编辑器 数据结构 课程设计

中国矿业大学徐海学院计算机系《软件认知实践》报告 姓名:学号: 专业: 设计题目:简单行编辑器 指导教师: 2012年12月25

目录 第1章题目概述 (1) 第1.1节题目要求 (1) 第1.2节主要难点 (2) 第2章系统流程图 (3) 第3章数据结构和算法 (4) 第4章核心代码分析 (6) 第5章复杂度分析 (10) 第6章总结 (11) 参考文献 (13)

第1章题目概述 在这次课程设计中我选的题目是文本编辑,文本编辑几乎是每个使用电脑 的人都会遇到的问题,特别是网络小说作家们。在文本的编辑中,我们会时常 遇到文本信息的统计问题、小型子串的查找问题、子串的查找和删除问题等。 如果靠人自己去观察和执行相关操作的话,不仅累人,而且很容易出错。而使 用计算机程序去实现的话,则会省力不少,而且相对来说非常精确。本程序使 用了较快速的查找算法,可以大大提高检索的效率,相信这可一极大的方便用 户用电脑编辑文本文件。 第1.1节题目要求 文章编辑 功能:输入一页文字,程序可以统计出文字、数字、空格的个数。 静态存储一页文章,每行最多不超过80个字符,共N行; 要求 (1)分别统计出其中英文字母数和空格数及整篇文章总字数; (2)统计某一字符串在文章中出现的次数,并输出该次数; (3)删除某一子串,并将后面的字符前移。 存储结构使用线性表,分别用几个子函数实现相应的功能; 输入数据的形式和范围:可以输入大写、小写的英文字母、任何数字及标 点符号。 输出形式: (1)分行输出用户输入的各行字符; (2)分4行输出"全部字母数"、"数字个数"、"空格个数"、"文章总字数" (3)输出删除某一字符串后的文章; 实现功能 (1)文章内容的输入:包括字母、标点符号、数字等; (2)文章内容的统计:包括文章中大写字母、小写字母、数字、标点符

简单编译器的设计

华北电力大学 报告 | | 论文名称简单编译器的实现原理 课程名称编译原理 | | 专业班级:软件1202 学生姓名:朱晓琳 学号:201209020234 成绩: 指导教师:鲁斌日期: 2014.12

一、前言 经过将近八周的学习,我逐渐了解了关于编译的各种知识,虽然掌握的不是很牢固,也没有完全学完全部知识。尤其印象深刻的是在第一堂课时,老师说学完本门课,希望同学们都能跃跃欲试自己设计出一个小编译器出来。于是我对设计编译器这方面的知识进行了查询和学习,希望能把自己所学的知识总结和连接起来。 二、面向对象语言 1、先来分析一直以来学习的面向对象的语言C++和JAVA。其特点有: 1) 抽象 简单的说,抽象就是根据程序设计的需要,确定对象的特征和行为,并排除不相关的冗余细节的思维过程。通常,对于一个具有大量物特征和行为的客观对象,只抽取其中有助于解决问题的行为和特征,从而得到该问题的抽象结果。 2) 封装 封装就是将对象的属性和实现细节进行隐藏,只提供对外的公共接口,将抽象得到的数据和行为相结合,形成一个有机的整体,在实际操作中,可以将类的定义过程理解为封装。其中数据和方法都是类的成员。 3) 继承 继承性是面向对象程序设计的一个独有特征,它与自然界和生物界的遗传或继承类似。在传统的程序设计中,数据类型之间是没有父子的层次关系的,而在面向对象程序设计中,一个类可以继承另一个类的中所有数据成员和成员方法,而且这个类还可以定义自己的数据成员和成员方法,继承是从一个现有类产生新类的过程,它带来的最大好处就是实现了代码的可重用性,极大的提高了编程的效率。微软的.NET框架类库就是在充分利用继承的基础上形成的一个树形层次结构。 4) 多态 多态性是指对象运行时类型呈现不同的行为能力。在面向对象程序设计中,对象间的通信是通过发送和接收消息进行的,消息发送者不需要知道接收者是那一类对象,只需要知道接收者可以执行某种特定行为,对行为的细节也不必关心。利用多态性,用户可以发送统一消息,由各个接收者来完成不同的实现细节。 2、面向对象语言具有的上述特点决定了它的编译系统必须好好考虑这些特点及其对应的解决方法。比如其继承类,多重继承类,相互依赖的多重继承类等等等。 三、设计思路 1、语言的设计 2、目标机器建模 3、编译器的实现 四、具体实现 1、语言的设计 在这里可以选择我们从大一就开始学习的C++或java语言。 2、目标机器建模 需要设计好其处理器、存储器、指令系统。 1)处理器 数据结构如下:

编译原理-课程设计报告-简单编译器实现

编译原理-课程设计报告-简单编译器实现

课程设计 题目:简单编译器实现 学院:信息工程学院计算机系专业:计算机科学与技术班级:计科1103班 组长: 小组成员: 指导教师:

1 概述 编译程序的工作过程一般可以分为五个阶段:词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。每一个阶段在功能上是相对独立的,它一方面从上一个阶段获取分析的结果来进行分析,另一方面由将结果传递给下一个阶段。由编译程序的五个阶段就对应了编译系统的结构。 其中词法分析器利用超前搜索、状态转换等方法,将源程序转化成为一个一个的单词符号二元式。一般程序语言的单词符号包括关键字、运算符、常数、标识符和界符。语法分析器将这些单词符号作为输入,对它进行语法分析。语法分析分为两种方法:自上而下分析法和自下而上分析法。针对不同程序语言的语法规则可以采取不同的分析方法,当然两种方法也可以同时使用。语法分析器把语法单元作为输入供语义分析器使用。一般的语义分析器主要采用的是语法制导方法,即在语法分析的同时进行语法分析,并产生一定的语义动作,来生成中间代码。上面三个过程可以与硬件无关,

而接下来的优化器和目标代码生成器是针对某一种处理器而言的。代码优化是将语义分析生成的中间代码进行优化,产生执行效率更高的代码。目标代码生成器最终生成可以在某种机器上运行的机器语言或者汇编语言。在整个编译过程中还包括对表格的操作和对错误的处理,这些也都是非常重要的环节。 1.1源、目标语言简介 使用C语言做简单语法分析器,C语言是一门高级计算机编程语言,设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言 1.2实现平台与运行平台简介 在win32环境下进行编译,Win32是指Microsoft Windows操作系统的32位环境,是目前使用最多的操作系统。 实验环境:需要TC、VC++ 6.0等开发工具作为本次试验的环境。 1.3其它 通过实现一个可以把类似c语言的源代码转变为中间代码的编译器,更好地理解编译的过程,锻炼我们组的编程能力。 2简单词法分析器的设计与实现 2.1 基础理论说明 词法分析负责对源程序的字符串进行扫描和分解,根据构词法将字符流(Character Stream)转化成单词流(Token Stream)。

简单C语言编译器(编译原理)

#include #include #include #include #include #include #include #include #define NULL 0 struct Stack // 栈结构体: 序号、内容、连接下一结点指针 { int num; char name; struct Stack *next; }; struct Guiyue// 规则集结构体:序号、规则长度、符号、连接下一结点指针 { int num; int count; char name; struct Guiyue *next; }; struct Relation // 分析表结构体:状态序号、对应符号列、操作类型的对应序号、操作类型、连接下一结点指针 { int line_States ; char rank_Letter; int relationship; char name; struct Relation *next; }; struct Sign // 符号表结构体: 自变量名、标识类型、连接下一结点指针 { char name[20]; char kind; struct Sign *next; }; struct Word // 单词表结构体: 单词名字、标识类型、状态、序号、行号、连接符号表指针、连接下一结点指针 { char name[20];

char mark_name; int state; int num; int line; struct Sign *link; struct Word *next; }; FILE *fp1;//文件指针 int row=1,line[10000],Lin[300],w_num;//字符行变量、字符行、单词所在行、字符数char buffer[10000];//字符串缓冲区 Stack *MarkPush(Stack *ip,char mark,int I_i)//压栈 { Stack *s; s=(Stack *)malloc(sizeof(Stack)); s->name=mark; s->num=I_i; s->next=ip; ip=s; return ip; } void MarkPop(Stack *ip)//出栈 { Stack *q; char name; 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); } } int judge(char ch)// 接收ch判断字符,变量flag返回字符类别 { int flag; 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; else if('0'<=ch&&ch<='9')

相关文档
最新文档