编译原理语法分析算法实现.docx
《编译原理语法分析算法实现.docx》由会员分享,可在线阅读,更多相关《编译原理语法分析算法实现.docx(23页珍藏版)》请在冰豆网上搜索。
编译原理语法分析算法实现
实验二语法分析程序
一、实验目的
通过设计调试算符优先分析程序,加深对课堂教学的理解,深刻理解自底向上语法分析方法的归约过程,提高语法分析方法的实践能力。
二、实验内容及要求
(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;iif(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;iif(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;iif(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;iif(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;iif(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;iif(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