实验二语法分析算符优先2.docx
《实验二语法分析算符优先2.docx》由会员分享,可在线阅读,更多相关《实验二语法分析算符优先2.docx(21页珍藏版)》请在冰豆网上搜索。
实验二语法分析算符优先2
实验二--语法分析(算符优先)-
(2)
编译原理实验报告
实验名称:
语法分析器设计
专业:
计算机科学与技术
姓名:
田莉莉
学号:
201117906
语法分析—算符优先分析程序
一.实验要求
⑴选择最有代表性的语法分析方法,如算符优先法、递归子程序法或LR分析法
⑵选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
⑶实习时间为6学时。
二.实验内容及要求
(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
三.程序设计思想及实现步骤
程序的设计思想:
按照编译原理教材提供的算法,本程序的设计主要实现三个主要的过程:
(1)求解FristVT集和LastVT集:
利用CString数组存放VT集,利用数组下标对应非终结符关系;
(2)输出算符优先分析表:
利用MFC中的ClistCtrl控件输出显示算符表,比利用二维数组对应其在内存中的关系。
(3)利用算符优先分析表进行归约:
根据教材所给算法,并对其进行实现在屏幕上输出归约过程。
实现步骤:
1、为程序各变量设计存储形式,具体设计如下所示:
CStringm_strTElem[T_LEN];//终结符
CStringm_strNTElem[NT_LEN];//非终结符
CMapStringToPtrm_mapProdu;//存放产生式
CMapStringToPtrm_mapProduEX;//存放扩展产生式
CStringm_strFristVT[NT_LEN];//fristVT集
CStringm_strLastVT[NT_LEN];//lastVT集
intm_nPriSheet[T_LEN+1][T_LEN+1];//优先表;无穷大表示空白,-1表示小于,0表示相等,1表示大于
Findm_F[STACK_LEN];//bool数组
CStrackm_stack;//堆栈
2、为程序设计各个过程,具体设计如下所示:
voidCreateFristVT(Find*F);//为每一个非终结符创建FristVT集
voidCreateLastVT(Find*F);//为每一个非终结符/创建LastVT集
voidSearchPForFirtVT(Find&f);//搜索形如P->a….或P->Qa….的产生式
voidSearchQForFristVT(void);//搜索形如P->....Q的产生式
voidSearchPForLastVT(Find&f);//搜索形如P->...aQ或P->...a的产生式
voidSearchQForLastVT(void);//搜索形如P->....Q的产生式
OnBnClickedBtnAnasysic();//点击按钮启动分析
3、对各个过程进行实现;
4、调试运行并检验实验结果,结果如图2.1和2.2所示:
图2.1分析成功图
图2.2分析失败图
四.程序源码
产生式初始化:
//产生式
CString*str=newCString;
*str=_T("|E+T|T|");
m_mapProdu.SetAt(_T("E"),(void*)str);
CString*str1=newCString;
*str1=_T("|T*F|F|");
m_mapProdu.SetAt(_T("T"),(void*)str1);
CString*str2=newCString;
*str2=_T("|(E)|i|");
m_mapProdu.SetAt(_T("F"),(void*)str2);
CString*str3=newCString;
*str3=_T("|E+T|F+F|F*F|E+F|T|F|");
m_mapProduEX.SetAt(_T("E"),(void*)str3);
CString*str4=newCString;
*str4=_T("|T*F|F|");
m_mapProduEX.SetAt(_T("T"),(void*)str4);
CString*str5=newCString;
*str5=_T("|(E)|i|(F)|");
m_mapProduEX.SetAt(_T("F"),(void*)str5);
程序主要代码:
voidCGrammarAnalysisDlg:
:
InitFind(void)
{
inti,j;
intk=0;
while(k{
for(i=0;ifor(j=0;j{
m_F[k].m_strNTerm=m_strNTElem[i];
m_F[k].m_strTerm=m_strTElem[j];
m_F[k].m_bIsVT=FALSE;
k++;
}
}
}
//查找P->a...和P->Qa...
voidCGrammarAnalysisDlg:
:
SearchPForFirtVT(Find&f)
{
CString*str;
m_mapProdu.Lookup(f.m_strNTerm,(void*&)str);
intnFrist=0;
intnLen=0;
while(nLen+1GetLength())//P->a...P和P->Qa...
{
nFrist=nLen;
nLen=str->Find('|',nFrist+1);
CStringstrProduce=str->Mid(nFrist+1,nLen-nFrist-1);
if(IsNT(strProduce,0)&&IsT(strProduce,1))
{
if(strProduce.GetAt
(1)==f.m_strTerm)
{
if(!
f.m_bIsVT)
{
f.m_bIsVT=TRUE;
//CreateFristVT(f);
m_stack.PushStack(f);
}
}
}
if(IsT(strProduce,0))
{
if(strProduce.GetAt(0)==f.m_strTerm)
{
if(!
f.m_bIsVT)
{
f.m_bIsVT=TRUE;
//CreateFristVT(f);
m_stack.PushStack(f);
}
}
}
}
}
//判断产生式第nLocat位置的字符是否是非终结符
BOOLCGrammarAnalysisDlg:
:
IsNT(CStringstrProduc,intnLocat)
{
for(inti=0;i{
if(strProduc.GetAt(nLocat)==m_strNTElem[i])
return1;
}
return0;
}
//判断产生式第nLocat位置的字符是否是终结符
BOOLCGrammarAnalysisDlg:
:
IsT(CStringstrProduc,intnLocat)
{
for(inti=0;i{
if(strProduc.GetAt(nLocat)==m_strTElem[i])
return1;
}
if(strProduc.GetAt(nLocat)=='#')
return1;
return0;
}
//遍历所有的产生式P->Q
voidCGrammarAnalysisDlg:
:
SearchQForFristVT(void)
{
FindQ;
CStringstrNT;
CString*str;
while(m_stack.m_nTop!
=0)
{
m_stack.PopStack(Q);
POSITIONpos=m_mapProdu.GetStartPosition();
while(pos)
{
m_mapProdu.GetNextAssoc(pos,strNT,(void*&)str);
intnFrist=0;
intnLen=0;
while(nLen+1GetLength())
{
nFrist=nLen;
nLen=str->Find('|',nFrist+1);
CStringstrProduce=str->Mid(nFrist+1,nLen-nFrist-1);
if(IsNT(strProduce,0))
{
if(strProduce.GetAt(0)==Q.m_strNTerm)
{
//Q.m_bIsVT=TRUE;
for(inti=0;i{
if(m_F[i].m_strNTerm==strNT&&m_F[i].m_strTerm==Q.m_strTerm)
{
if(!
m_F[i].m_bIsVT)
{
m_F[i].m_bIsVT=TRUE;
m_stack.PushStack(m_F[i]);
break;
}
}
}
}
}
}
}
}
}
////P->...aQ或P->...a
voidCGrammarAnalysisDlg:
:
SearchPForLastVT(Find&f)
{
CString*str;
m_mapProdu.Lookup(f.m_strNTerm,(void*&)str);
intnFrist=0;
intnLen=0;
while(nLen+1GetLength())//P->a...P和P->Qa...
{
nFrist=nLen;
nLen=str->Find('|',nFrist+1);
CStringstrProduce=str->Mid(nFrist+1,nLen-nFrist-1);
intnLocat=strProduce.GetLength();
if(nLocat-2>0)
{
if(IsNT(strProduce,nLocat-1)&&IsT(strProduce,nLocat-2))
{
if(strProduce.GetAt(nLocat-2)==f.m_strTerm)
{
if(!
f.m_bIsVT)
{
f.m_bIsVT=TRUE;
m_stack.PushStack(f);
}
}
}
}
if(IsT(strProduce,nLocat-1))
{
if(strProduce.GetAt(nLocat-1)==f.m_strTerm)
{
if(!
f.m_bIsVT)
{
f.m_bIsVT=TRUE;
m_stack.PushStack(f);
}
}
}
}
}
////P->....Q
voidCGrammarAnalysisDlg:
:
SearchQForLastVT(void)
{
FindQ;
CStringstrNT;
CString*str;
while(m_stack.m_nTop!
=0)
{
m_stack.PopStack(Q);
POSITIONpos=m_mapProdu.GetStartPosition();
while(pos)
{
m_mapProdu.GetNextAssoc(pos,strNT,(void*&)str);
intnFrist=0;
intnLen=0;
while(nLen+1GetLength())
{
nFrist=nLen;
nLen=str->Find('|',nFrist+1);
CStringstrProduce=str->Mid(nFrist+1,nLen-nFrist-1);
intnLocat=strProduce.GetLength();
if(IsNT(strProduce,nLocat-1))
{
if(strProduce.GetAt(nLocat-1)==Q.m_strNTerm)
{
//Q.m_bIsVT=TRUE;
for(inti=0;i{
if(m_F[i].m_strNTerm==strNT&&m_F[i].m_strTerm==Q.m_strTerm)
{
if(!
m_F[i].m_bIsVT)
{
m_F[i].m_bIsVT=TRUE;
m_stack.PushStack(m_F[i]);
break;
}
}
}
}
}
}
}
}
}
voidCGrammarAnalysisDlg:
:
OnBnClickedBtnAnsysic()
{
//TODO:
在此添加控件通知处理程序代码
//初始化列表控件
//m_lbResult.AddString(_T("kjl"));
m_lst.SetExtendedStyle(LVS_EX_AUTOSIZECOLUMNS|LVS_EX_GRIDLINES);
CRectrc;
m_lst.GetClientRect(rc);
intnWidth=rc.Width()/(T_LEN+2);
inti=0;
m_lst.InsertColumn(i,_T(""),LVCFMT_CENTER,nWidth);
for(i=1;i{
m_lst.InsertColumn(i,m_strTElem[i-1],LVCFMT_CENTER,nWidth);
}
m_lst.InsertColumn(i,_T("#"),LVCFMT_CENTER,nWidth);
for(i=0;i{
m_lst.InsertItem(i,m_strTElem[i]);
}
m_lst.InsertItem(i,_T("#"));
//
//FirstVT
InitFind();
//Findf(_T("+"),_T("E"));
for(inti=0;iSearchPForFirtVT(m_F[i]);
SearchQForFristVT();
CreateFristVT(m_F);
//LastVT
InitFind();
//Findf(_T("+"),_T("E"));
for(inti=0;iSearchPForLastVT(m_F[i]);
SearchQForLastVT();
CreateLastVT(m_F);
//遍历产生式构造算符优先表
CString*str;
POSITIONpos=m_mapProdu.GetStartPosition();
CStringstrNT;
intnColumn;
intnItem;
while(pos)
{
m_mapProdu.GetNextAssoc(pos,strNT,(void*&)str);
intnFrist=0;
intnLen=0;
while(nLen+1GetLength())
{
nFrist=nLen;
nLen=str->Find('|',nFrist+1);
CStringstrProduce=str->Mid(nFrist+1,nLen-nFrist-1);
intnLocat=strProduce.GetLength();
for(inti=0;i{
if(IsT(strProduce,i)&&IsT(strProduce,i+1))
{
nItem=FindTLocat(strProduce.GetAt(i));
nColumn=FindTLocat(strProduce.GetAt(i+1));
m_nPriSheet[nItem][nColumn]=0;
m_lst.SetItemText(nItem,nColumn+1,_T("="));
}
if(i<=nLocat-2&&IsT(strProduce,i)&&IsT(strProduce,i+2)&&IsNT(strProduce,i+1))
{
nItem=FindTLocat(strProduce.GetAt(i));
nColumn=FindTLocat(strProduce.GetAt(i+2));
m_nPriSheet[nItem][nColumn]=0;
m_lst.SetItemText(nItem,nColumn+1,_T("="));
}
if(IsT(strProduce,i)&&IsNT(strProduce,i+1))
{
nItem=FindTLocat(strProduce.GetAt(i));
intnNTLocat=FindNTLocat(strProduce.GetAt(i+1));
intnVTLen=m_strFristVT[nNTLocat].GetLength();
for(intj=0;j{
nColumn=FindTLocat(m_strFristVT[nNTLocat].GetAt(j));
m_nPriSheet[nItem][nColumn]=-1;
m_lst.SetItemText(nItem,nColumn+1,_T("<"));
}
}
if(IsNT(strProduce,i)&&IsT(strProduce,i+1))
{
nColumn=FindTLocat(strProduce.GetAt(i+1));
intnNTLocat=FindNTLocat(strProduce.GetAt(i));
intnVTLen=m_strLastVT[nNTLocat].GetLength();
for(intj=0;j{
nItem=FindTLocat(m_strLastVT[nNTLocat].GetAt(j));
m_nPriSheet[nItem][nColumn]=1;
m_lst.SetItemText(nItem,nColumn+1,_T(">"));
}
}
}
}
}
//处理‘#',,行
nItem=T_LEN;
wchar_tch='(';
for(inti=0;i{
switch(m_nPriSheet[FindTLocat(ch)][i])
{
case0:
break;
caseINFI:
break;
case-1:
m_nPriSheet[nItem][i]=-1;
m_lst.SetItemText(nItem,i+1,_T("<"));
break;
case1:
m_nPriSheet[nItem][i]=1;
m_lst.SetItemText(nItem,i+1,_T(">"));
break;
}
}
//处理‘#’,,列
nColumn=T_LEN;
ch=')';
for(inti=0;i{
switch(m_nPriSheet[i][FindTLocat(ch)])
{
case0:
break;
caseINFI:
break;
case-1:
m_nPriSheet[i][nColumn]=-1;
m_lst.SetItemText(i,nColumn+1,_T("<"));
break;
case1:
m_nPriSheet[i][nColumn]=1;
m_lst.SetItemT