编译原理语法分析算法实现.docx

上传人:b****6 文档编号:3972115 上传时间:2022-11-26 格式:DOCX 页数:23 大小:60.28KB
下载 相关 举报
编译原理语法分析算法实现.docx_第1页
第1页 / 共23页
编译原理语法分析算法实现.docx_第2页
第2页 / 共23页
编译原理语法分析算法实现.docx_第3页
第3页 / 共23页
编译原理语法分析算法实现.docx_第4页
第4页 / 共23页
编译原理语法分析算法实现.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

编译原理语法分析算法实现.docx

《编译原理语法分析算法实现.docx》由会员分享,可在线阅读,更多相关《编译原理语法分析算法实现.docx(23页珍藏版)》请在冰豆网上搜索。

编译原理语法分析算法实现.docx

编译原理语法分析算法实现

实验二语法分析程序

一、实验目的

通过设计调试算符优先分析程序,加深对课堂教学的理解,深刻理解自底向上语法分析方法的归约过程,提高语法分析方法的实践能力。

二、实验内容及要求

(1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符

优先关系表输出到屏幕或者输出到文件);

(2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要

求输出归约过程)

(3)给定表达式文法为:

G(E’):

E’→#E#

E→E+T|T

T→T*F|F

F→(E)|i

(4)分析的句子为:

(i+i)*i和i+i)*i

三、程序源代码:

#include"iostream.h"

#include"stdio.h"

#include"malloc.h"

#include"stdlib.h"

#include"string.h"

#defineMAX_VALUE100

#defineSTACK_INIT_SIZE100

charVN[MAX_VALUE];//非终结符数组

charVT[MAX_VALUE];//终结符数组

staticintcurrent=1;//当前输入符

structCSS

{

chars[MAX_VALUE];

structCSS*next;

};

structARRAY

{

charVN;

charVT;

intvalue;

}F[MAX_VALUE],L[MAX_VALUE];//布尔数组F[A,a],L[A,a]

structARRAY1

{

charVT1;

charVT2;

charrelation;

}PT[MAX_VALUE];//定义优先关系结构体数组

structARRAY2

{

charVN;

charVT[MAX_VALUE];

}FIRSTVT[MAX_VALUE],LASTVT[MAX_VALUE];//FIRSTVT集合和LASTVT集合

structSElemType

{

charVN;

charVT;

};

typedefstruct

{

SElemType*base;

SElemType*top;

intstacksize;

}SqStack;

voidInitStack(SqStack&S)//对栈进行初始化

{

S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));

if(!

S.base)

{

cout<<"存储分配失败!

"<

exit(0);

}

S.top=S.base;

S.stacksize=STACK_INIT_SIZE;

}

intStackEmpty(SqStack&S)//判断栈是否为空

{

if(S.top==S.base)

return0;

else

return1;

}

voidPush(SqStack&S,SElemTypee)//入栈

{

*S.top++=e;

}

voidPop(SqStack&S,SElemType&e)//出栈,并用e返回值

{

if(S.top==S.base)

{

cout<<"栈空!

"<

exit(0);

}

e=*--S.top;

}

structCSS*ReadFromFile()

{

structCSS*head;

structCSS*p1,*p2;

p1=p2=(structCSS*)malloc(sizeof(structCSS));

head=NULL;

intn=0;

FILE*fp;

charS[MAX_VALUE];

cout<<"请输入文件名:

";

cin>>S;

if((fp=fopen(S,"r"))==NULL)

{

cout<<"Cannotopenthefile!

"<

exit(0);

}

else

{//从文件中读取文法

charch=fgetc(fp);

while(!

feof(fp))

{

inti=0;

while(ch!

=10)//为回车键时,作为一个产生式的结束

{

while(ch==32)//过滤掉空格

ch=fgetc(fp);

p1->s[i++]=ch;

ch=fgetc(fp);

}

p1->s[i]='\0';

n=n+1;

if(n==1)

head=p1;

else

p2->next=p1;

p2=p1;

p1=(structCSS*)malloc(sizeof(structCSS));

ch=fgetc(fp);

}

p2->next=NULL;

return(head);

}

}

structCSS*creat()//创建结构体链表来存储输入的文法

{

structCSS*head;

structCSS*p1,*p2;

intn=0;

cout<<"请输入文法:

"<

p1=p2=(structCSS*)malloc(sizeof(structCSS));

cin>>p1->s;

head=NULL;

while(strcmp(p1->s,"exit"))

{

n=n+1;

if(n==1)

head=p1;

else

p2->next=p1;

p2=p1;

p1=(structCSS*)malloc(sizeof(structCSS));

cin>>p1->s;

}

p2->next=NULL;

return(head);

}

structCSS*Select()

{

structCSS*p;

cout<<"读取方式:

1.从文件读取;2.从键盘读取"<

cout<<"请选择:

";

charsLetter;

cin>>sLetter;

if(sLetter=='1')

p=ReadFromFile();

else

p=creat();

return(p);

}

voidSearch(structCSS*head)//搜索产生式中的终结符和非终结符,并分别存放到数组VT和VN中

{

inti;

intj=0;

intk=0;

structCSS*p;

p=head;

if(head!

=NULL)

{

do//对每个产生式进行扫描

{

for(i=0;p->s[i]!

='\0';i++)

{

if(p->s[i]>='A'&&p->s[i]<='Z'&&i==0)

{//在每个产生式开头搜索非终结符

for(intn=0;n<=j;n++)//扫描VN数组,看是否已经存在该非终结符

if(p->s[i]!

=VN[n])

continue;

elsebreak;

if(p->s[i]!

=VN[n])//如果不存在,就添加该非终结符

VN[j++]=p->s[i];

}

if(!

(p->s[i]>='A'&&p->s[i]<='Z')&&i>=3)

{//从->后面开始搜索终结符

for(intn=0;n<=k;n++)//扫描VT数组,看是否已经存在该终结符

if(p->s[i]!

=VT[n])

continue;

elsebreak;

if(p->s[i]!

=VT[n])//如果不存在,就添加该终结符

VT[k++]=p->s[i];

}

}

p=p->next;

}while(p!

=NULL);

}

VN[j]='\0';

VT[k]='\0';

}

voidInsert(SqStack&S,structARRAYF[],inti,intFlag)

{

if(Flag==0)

{

if(!

F[i].value)

{

F[i].value=1;

SElemTypee;

e.VN=F[i].VN;

e.VT=F[i].VT;

Push(S,e);

}

}

else

{

if(!

L[i].value)

{

L[i].value=1;

SElemTypee;

e.VN=L[i].VN;

e.VT=L[i].VT;

Push(S,e);

}

}

}

 

voidDO_FIRSTVT(structCSS*head)//求FIRSTVT集合

{

intk;

inti=0,j=0,m=0,n=0;

SqStackS;

InitStack(S);

for(;VN[i]!

='\0';i++)//初始化布尔数组F[A,a]

{

for(;VT[j]!

='\0';j++)

{

F[n].VN=VN[i];

F[n].VT=VT[j];

F[n].value=0;

n++;//计数器,统计布尔数组F[A,a]中元素的个数

}

j=0;

}

structCSS*p;

p=head;

if(head!

=NULL)

{

do

{

if(!

(p->s[3]>='A'&&p->s[3]<='Z'))//处理每个形如A->a...的产生式

{

for(i=0;i

if(F[i].VN==p->s[0]&&F[i].VT==p->s[3])

break;

Insert(S,F,i,0);

}

if((p->s[3]>='A'&&p->s[3]<='Z')&&!

(p->s[4]>='A'&&p->s[4]<='Z'))

{//处理每个形如A->Ba...的产生式

for(i=0;i

if(F[i].VN==p->s[0]&&F[i].VT==p->s[4])

break;

Insert(S,F,i,0);

}

p=p->next;

}while(p!

=NULL);

}

while(StackEmpty(S))

{

p=head;

SElemTypee;

Pop(S,e);

if(head!

=NULL)

{

do

{

if(p->s[3]==e.VN&&p->s[4]=='\0')

{

for(i=0;i

if(F[i].VN==p->s[0]&&F[i].VT==e.VT)

break;

Insert(S,F,i,0);

}

p=p->next;

}while(p!

=NULL);

}

}

FIRSTVT[0].VN=F[0].VN;

for(i=0,j=0,k=0;i

{

if((F[i].VN==FIRSTVT[j].VN)&&(F[i].value==1))

FIRSTVT[j].VT[k++]=F[i].VT;

if((F[i].VN!

=FIRSTVT[j].VN)&&(F[i].value==1))

{

j++;

k=0;

FIRSTVT[j].VN=F[i].VN;

FIRSTVT[j].VT[k++]=F[i].VT;

}

}

cout<<"所求每个非终结符的FIRSTVT集合如下:

"<

for(i=0;i<(signed)strlen(VN);i++)

cout<<"FIRSTVT("<

}

voidDO_LASTVT(structCSS*head)//求LASTVT集合

{

inti=0,j=0,n=0;

intk;

SqStackS;

InitStack(S);

for(;VN[i]!

='\0';i++)//初始化布尔数组L[A,a]

{

for(;VT[j]!

='\0';j++)

{

L[n].VN=VN[i];

L[n].VT=VT[j];

L[n].value=0;

n++;//计数器,统计布尔数组L[A,a]中元素的个数

}

j=0;

}

structCSS*p;

p=head;

if(head!

=NULL)

{

do

{

if(!

(p->s[strlen(p->s)-1]>='A'&&p->s[strlen(p->s)-1]<='Z'))

{//处理每个形如A->...a的产生式

for(i=0;i

if(L[i].VN==p->s[0]&&L[i].VT==p->s[strlen(p->s)-1])

break;

Insert(S,L,i,1);

}

if((p->s[strlen(p->s)-1]>='A'&&p->s[strlen(p->s)-1]<='Z')&&!

(p->s[strlen(p->s)-2]>='A'&&p->s[strlen(p->s)-2]<='Z'))

{//处理每个形如A->...aC的产生式

for(i=0;i

if(L[i].VN==p->s[0]&&L[i].VT==p->s[strlen(p->s)-2])

break;

Insert(S,L,i,1);

}

p=p->next;

}while(p!

=NULL);

}

while(StackEmpty(S))

{

p=head;

SElemTypee;

Pop(S,e);

if(head!

=NULL)

{

do

{

if(p->s[3]==e.VN&&p->s[4]=='\0')

{

for(i=0;i

if(L[i].VN==p->s[0]&&L[i].VT==e.VT)

break;

Insert(S,L,i,1);

}

p=p->next;

}while(p!

=NULL);

}

}

LASTVT[0].VN=L[0].VN;

for(i=0,j=0,k=0;i

{

if((L[i].VN==LASTVT[j].VN)&&(L[i].value==1))

LASTVT[j].VT[k++]=L[i].VT;

if((L[i].VN!

=LASTVT[j].VN)&&(L[i].value==1))

{

j++;

k=0;

LASTVT[j].VN=L[i].VN;

LASTVT[j].VT[k++]=L[i].VT;

}

}

cout<<"所求每个非终结符的LASTVT集合如下:

"<

for(i=0;i<(signed)strlen(VN);i++)

cout<<"LASTVT("<

}

voidDO_PRIORITY_TABLE(structCSS*head)//求优先关系表

{

structCSS*p;

p=head;

if(head!

=NULL)

{

for(intl=0;p->next!

=NULL;p=p->next)

for(inti=3,j=0;j<(signed)strlen(p->s)-3-1;i++,j++)

{

if((!

(p->s[i]>='A'&&p->s[i]<='Z'))&&(!

(p->s[i+1]>='A'&&p->s[i+1]<='Z')))

{//p->s[i]和p->s[i+1]都为终结符,置'='

PT[l].VT1=p->s[i];

PT[l].VT2=p->s[i+1];

PT[l].relation='=';

l++;

}

if((j<=(signed)strlen(p->s)-3-3)&&(!

(p->s[i]>='A'&&p->s[i]<='Z')&&!

(p->s[i+2]>='A'&&p->s[i+2]<='Z'))&&(p->s[i+1]>='A'&&p->s[i+1]<='Z'))

{//p->s[i]和p->s[i+2]都为终结符,p->s[i+1]都为非终结符置'='

PT[l].VT1=p->s[i];

PT[l].VT2=p->s[i+2];

PT[l].relation='=';

l++;

}

if(!

(p->s[i]>='A'&&p->s[i]<='Z')&&(p->s[i+1]>='A'&&p->s[i+1]<='Z'))

{//p->s[i]为终结符,p->s[i+1]都为非终结符置'<'

for(intk=0;;k++)

if(FIRSTVT[k].VN==p->s[i+1])

break;

elsecontinue;

for(intm=3,x=0;FIRSTVT[k].VT[x]!

='\0';m++,l++)

{

PT[l].VT1=p->s[i];

PT[l].VT2=FIRSTVT[k].VT[x++];

PT[l].relation='<';

}

}

if((p->s[i]>='A'&&p->s[i]<='Z')&&!

(p->s[i+1]>='A'&&p->s[i+1]<='Z'))

{//p->s[i]为非终结符,p->s[i+1]都为终结符置'>'

for(intk=0;;k++)

if(LASTVT[k].VN==p->s[i])

break;

elsecontinue;

for(intm=3,x=0;LASTVT[k].VT[x]!

='\0';m++,l++)

{

PT[l].VT1=LASTVT[k].VT[x++];

PT[l].VT2=p->s[i+1];

PT[l].relation='>';

}

}

}

}

cout<<"算符优先关系矩阵表"<

cout<<"------------------------------------------------------------"<

for(inti=strlen(VT)-1;i>=0;i--)

cout<<"\t"<

cout<

cout<<"------------------------------------------------------------"<

for(i=strlen(VT)-1;i>=0;i--)

{

cout<

for(intm=strlen(VT)-1;m>=0;m--)

{

for(intk=0;k<(signed)(strlen(VT)*strlen(VT));k++)

if((PT[k].VT1==VT[i])&&(PT[k].VT2==VT[m]))

{

cout<

break;

}

elsecontinue;

if(k==(signed)(strlen(VT)*strlen(VT)))

cout<<"\t";

}

cout<

}

cout<<"------------------------------------------------------------"<

}

intk=0;

intj;

intN=1;//归约步骤序号

staticintCurrentWith(charzf[],charzfc[]);

char*SYSRC(charzf[],charzfc[])//返回剩余的字符串的首地址

{

char*str;

str=zfc;

str=str+current+1;

returnstr;

}

voiddo_current(charzf[],charzfc[])

{

charQ=zf[j];

if(!

(zf[j-1]>='A'&&zf[j-1]<='Z'))

j=j-1;

elsej=j-2;

for(inti=0;i<(signed)(strlen(VT)*strlen(VT));i++)

if((PT[i].VT1==zf[j])&&(PT[i].VT2==Q))

break;

elsecontinue;

if(PT[i].relation=='<')//将zf[j+1]...zf[k]归约为N

{

k=j+1;

zf[k]='N';

zf[k+1]='\0';

N

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 小升初

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1