编译原理实验3算符优先分析.docx
《编译原理实验3算符优先分析.docx》由会员分享,可在线阅读,更多相关《编译原理实验3算符优先分析.docx(49页珍藏版)》请在冰豆网上搜索。
编译原理实验3算符优先分析
编译原理实验3算符优先分析
一、实验目的
通过设计编制调试构造FIRSTVT集、LASTVT集和构造算符优先表、对给定符号串进行分析的程序,了解构造算符优先分析表的步骤,对文法的要求,生成算符优先关系表的算法,对给定的符号串进行分析的方法。
二、实验内容
1.给定一文法G,输出G的每个非终结符的FIRSTVT集和LASTVT集。
2.构造算符优先表。
3.对给定的符号串进行分析,包含符号栈,符号栈栈顶符号和输入串当前符号的优先级,最左素短语和使用的产生式和采取的动作。
三、程序思路
在文法框内输入待判断文法产生式,格式E->a|S,注意左部和右部之间是“->”,每个
产生式一行,ENTER键换行。
文法结束再输入一行G->#E#
1.先做文法判断,即可判断文法情况。
2.若是算符优先文法,则在优先表栏显示优先表。
3.写入要分析的句子,按回车即可。
4.在分析过程栏,可以看到整个归约过程情况四、实验结果
FunctorFirst.h
#include
#include
#include
#include
usingnamespacestd;
#define
rightlength20
#define
product_num20
//
产生式最多个数
#define
num_noterminal
26
//
非终结符最多个数
#define
num_terminal
26
//
终结符最多个数
struct
Production
{
charLeft;
charRight[rightlength
];
int
num;
};
structVT
{
boolvt[num_noterminal][num_terminal];
};
structStack
{
charP;
chara;
};
class
CMyDlg
{
public
:
CMyDlg();
void
InputRule();
CString
showLastVT();
CString
showFirstVT();
CString
shownoTerminal(
charG[]);
CString
showTerminal(charg[]);
CString
showLeftS(
char
S[],
int
j,
int
k);
void
InitAll();
CString
showSentence(CString
sen,
int
start);
CString
showStack(
char
S[],
int
n);
void
Initarry(
char
arry[],
int
n);
CString
ProdtoCStr(
Production
prod);
int
selectProd(
int
i,
int
j,
char
S[]);
void
preFunctor(CStringsen);
void
insertFirstVT(
Stack
S[],
int
&sp,
charP,
chara);
void
insertLastVT(
StackS[],
int&sp,
charP,
chara);
void
ShowPreTable();
void
createPreTable();
charpretable[
num_terminal][
num_terminal];
bool
like_Q(Productionprod,
charQ);
void
createLastVT();
bool
likeQ_(Productionprod,
charQ);
bool
likeQa_(Productionprod);
bool
like_aQ(Productionprod);
bool
like_a(Productionprod);
bool
likea_(Productionprod);
bool
Dignose(charc);
int
findg(
char
c);
int
findG(
char
c);
void
createFirstVT();
void
createTerminal();
void
createnoTerminal();
void
buildProduction(
CString
s);
bool
test(
CStrings);
void
parse();
//
语法分析
CString
gram;
//
存放文法;
Production
production[
product_num];
VTFirstVT;
VTLastVT;
int
locProduct;
//已有产生式个数
charG[num_noterminal];
charg[num_terminal];
int
i_G;
int
i_g;
CString
m_sen;
};
FunctorFirst.cpp
#include"FunctorFirst.h"
CMyDlg:
:
CMyDlg()
{
}
bool
CMyDlg:
:
test(
CString
s)
//测试是否是算符优先文法
{
bool
for(
t=1;
inti=0;iif(s[i]>64&&s[i]<91&&s[i+1
{
]>64&&s[i+1
]<91)
t=0;
break;
}
return
t;
}
voidCMyDlg:
:
InputRule()
{
stringinfile;
stringline;
cout<<"请输入语法文件的路径:
";
cin>>infile;
cout<ifstreaminput(infile.c_str());
if(!
input)
{
cout<
cout<<"!
!
!
请再次运行本程序!
!
!
"<exit(0);
}
while(getline(input,line))
{
if(test(line.c_str())==0)
{
cout<"<exit(0);
}
buildProduction(line.c_str());
}
cout<"<
input.close();
}
void
CMyDlg:
:
buildProduction(
CString
s)
{
int
int
int
i=0;
j=0;
k=0;
for
(k=0;k<
s.GetLength();k++)
//得到左部
{
if
(s[k]!
=
''
)
{
production[locProduct].Left=
break;
s[k];
}
}
for
(i=k+1;i<
s.GetLength();i++)
{
if
(
s[i-1
]==
'-'
&&s[i]==
'>'
)
break;
}
int
for
temp=i;
(i=temp+1;i<
s.GetLength();i++)
{
if
(s[i]!
=
'|'
)
{
if
(s[i]!
=
''
)
{
production[locProduct].Right[j]=
j++;
production[locProduct].num=j;
s[i];
}
}
else
{
locProduct++;
production[locProduct].Left=production[locProduct-1].Left;
j=0;
}
}
locProduct++;
}
void
CMyDlg:
:
createnoTerminal()
//建立非终结符索引
{
i_G=0;
//最后一个位置的下一个下标
intj=0;
for(int
i=0;i{
for
{
(j=0;jif
(production[i].Left!
=G[j])
j++;
else
break;
}
if
{
(j>i_G-1)
G[i_G]=production[i].Left;
i_G++;
}
}
}
void
CMyDlg:
:
createTerminal()
//建立终结符索引
{
i_g=0;
//最后一个位置的下一个下标
intj=0;
for(inti=0;i
{
for(intk=0;k{
chartemp=production[i].Right[k];
if(Dignose(temp))
{
for(j=0;j{
if(temp!
=g[j])
j++;
else
break;
}
if(j>i_g-1)
{
g[i_g]=temp;
i_g++;
}
}
}
}
}
void
CMyDlg:
:
createFirstVT()
//production
已完成,创建
FirstVT
{
inti,j;
StackS[100];
intsp=0;
for(i=0;i//初始化FirstVT
for(j=0;jFirstVT.vt[i][j]=
false;
for(i=0;i{
if(likea_(production[i]))
insertFirstVT(S,sp,production[i].Left,production[i].Right[0]);
if(likeQa_(production[i]))
insertFirstVT(S,sp,production[i].Left,production[i].Right[1]);
}
while(sp>0)
{
sp--;
charQ=S[sp].P;
chara=S[sp].a;
for(i=0;i{
if(likeQ_(production[i],Q))
insertFirstVT(S,sp,production[i].Left,a);
}
}
}
voidCMyDlg:
:
createLastVT()//创建Last集
{
inti,j;
StackS[100];
intsp=0;
for(i=0;ifor(j=0;jLastVT.vt[i][j]=false;
for(i=0;i{
if(like_a(production[i]))
insertLastVT(S,sp,production[i].Left,
production[i].Right[production[i].num-1]);
if(like_aQ(production[i]))
insertLastVT(S,sp,production[i].Left,
production[i].Right[production[i].num-2]);
}
while(sp>0)
{
sp--;
charQ=S[sp].P;
chara=S[sp].a;
for(i=0;i{
if(like_Q(production[i],Q))
insertLastVT(S,sp,production[i].Left,a);
}
}
}
int
CMyDlg:
:
findG(
char
c)
//定位c在G中的下标
{
int
for
i=0;
(i=0;iif(c==G[i])
break;
return
i;
}
int
CMyDlg:
:
findg(
char
c)
//定位c在g中的下标
{
int
for
i=0;
(i=0;iif(c==g[i])
break;
return
i;
}
boolCMyDlg:
:
Dignose(
非终结符false
{
char
c)
//判断c
是终结符还是非终结符,终结符
true
,
if
(
c>64&&c<91)
returnfalse;
else
return
true;
}
bool
CMyDlg:
:
likea_(
Production
prod)
{
if
(Dignose(
return
prod.Right[0]))
true;
else
return
false;
}
bool
CMyDlg:
:
like_a(
Production
prod)
//形如P->⋯a型产生式
{
if
(Dignose(return
prod.Right[true;
prod.num-1]))
else
return
false;
}
boolCMyDlg:
:
like_aQ(
Production
prod)
//形如P->⋯aQ型产生式
{
if(prod.num<1)
returnfalse;
else
{
if(Dignose(prod.Right[
prod.num-2])&&(!
Dignose(
prod.Right[prod.num-
1])))
return
true;
else
return
false;
}
}
boolCMyDlg:
:
likeQa_(
Production
prod)
{
if(prod.num<1)
returnfalse;
else
{
if(Dignose(prod.Right[1])&&(!
Dignose(returntrue;
prod.Right[0])))
else
return
false;
}
}
boolCMyDlg:
:
likeQ_(
Production
prod,charQ)
{
if(prod.Right[0]==
returntrue;
Q)
else
return
false;
}
boolCMyDlg:
:
like_Q(
Production
prod,charQ)
{
if(prod.Right[prod.num-1]==returntrue;
Q)
else
returnfalse;
}
voidCMyDlg:
:
createPreTable()
{
//创建优先表
//初始化优先表pretableinti,j;
for(i=0;ifor(j=0;jpretable[i][j]='';//表错误
for(j=0;j{
for(i=0;i{
charxi,xi1,xi2;
xi=production[j].Right[i];
xi1=production[j].Right[i+1];
xi2=production[j].Right[i+2];
if(Dignose(xi)&&Dignose(xi1))
pretable[findg(xi)][findg(xi1)]='=';
if(i(!
Dignose(xi1)))
pretable[findg(xi)][findg(xi2)]=
if(Dignose(xi)&&(!
Dignose(xi1)))
{
'=';
intN=findG(xi1);
for(intk=0;kif(FirstVT.vt[N][k]==
true)
pretable[findg(xi)][k]=
'<';
}
if((!
Dignose(xi))&&Dignose(xi1))
{
intN=findG(xi);
for(intk=0;kif(LastVT.vt[N][k]==
true)
pretable[k][findg(xi1)]=
'>';
}
}
}
}
voidCMyDlg:
:
ShowPreTable()
//
显示相关集合和优先表
{
CString
str=
"";
str
=str
+
"终结符"
+showTerminal(g)+"\r\n";
str
=str
+
"非终结符"+shownoTerminal(G)
+"\r\n";
str
=str
+
"First
集合:
\r\n"
+showFirstVT();
str
=str
+
"Lasst
集合:
\r\n"
+showLastVT();
str
=str
+
"
|"
;
int
i,j;
for
(i=0;istr
=str
+g[i]
+"|"
;
str
=str
+
"\r\n"
;
for
(j=0;jstr
=str
+"⋯⋯⋯⋯";
str
+="\r\n"
;
for
(i=0;i{
str
=str
+g[i]
+"|"
;
for(j=0;j