编译原理语法分析实验二Word格式文档下载.docx
- 文档编号:17127994
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:16
- 大小:62.52KB
编译原理语法分析实验二Word格式文档下载.docx
《编译原理语法分析实验二Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《编译原理语法分析实验二Word格式文档下载.docx(16页珍藏版)》请在冰豆网上搜索。
public:
CAboutDlg();
//DialogData
//{{AFX_DATA(CAboutDlg)
enum{IDD=IDD_ABOUTBOX};
//}}AFX_DATA
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);
//DDX/DDVsupport
//}}AFX_VIRTUAL
//Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg:
:
CAboutDlg():
CDialog(CAboutDlg:
IDD)
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
voidCAboutDlg:
DoDataExchange(CDataExchange*pDX)
CDialog:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
//Nomessagehandlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//CSyntaxAnalysisDlgdialog
CSyntaxAnalysisDlg:
CSyntaxAnalysisDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CSyntaxAnalysisDlg:
IDD,pParent)
//{{AFX_DATA_INIT(CSyntaxAnalysisDlg)
m_strCode=_T("
"
);
m_strResult=_T("
//NotethatLoadIcondoesnotrequireasubsequentDestroyIconinWin32
m_hIcon=AfxGetApp()->
LoadIcon(IDR_MAINFRAME);
voidCSyntaxAnalysisDlg:
//{{AFX_DATA_MAP(CSyntaxAnalysisDlg)
DDX_Control(pDX,IDC_LIST1,m_ListCtrl);
DDX_Text(pDX,IDC_EDIT_Code,m_strCode);
DDX_Text(pDX,IDC_EDIT_Result,m_strResult);
BEGIN_MESSAGE_MAP(CSyntaxAnalysisDlg,CDialog)
//{{AFX_MSG_MAP(CSyntaxAnalysisDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_Analysis,OnBTNAnalysis)
//CSyntaxAnalysisDlgmessagehandlers
BOOLCSyntaxAnalysisDlg:
OnInitDialog()
OnInitDialog();
ASSERT((IDM_ABOUTBOX&
0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<
0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->
AppendMenu(MF_SEPARATOR);
AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
SetIcon(m_hIcon,TRUE);
//Setbigicon
SetIcon(m_hIcon,FALSE);
//Setsmallicon
//TODO:
Addextrainitializationhere
//初始化给定文法
m_VN[0]="
S"
;
m_VN[1]="
E"
m_VN[2]="
T"
m_VN[3]="
K"
m_VN[4]="
F"
m_VT[0]="
i"
m_VT[1]="
+"
m_VT[2]="
*"
m_VT[3]="
("
m_VT[4]="
)"
m_Gl[0]=0;
m_Gr[0]="
TE"
m_Gl[1]=1;
m_Gr[1]="
+TE"
m_Gl[2]=1;
m_Gr[2]="
ε"
m_Gl[3]=2;
m_Gr[3]="
FK"
m_Gl[4]=3;
m_Gr[4]="
*FK"
m_Gl[5]=3;
m_Gr[5]="
m_Gl[6]=4;
m_Gr[6]="
(S)"
m_Gl[7]=4;
m_Gr[7]="
Cal_Symbol();
Cal_First();
Cal_Follow();
DrawMList();
returnTRUE;
//returnTRUEunlessyousetthefocustoacontrol
OnSysCommand(UINTnID,LPARAMlParam)
if((nID&
0xFFF0)==IDM_ABOUTBOX)
CAboutDlgdlgAbout;
dlgAbout.DoModal();
else
CDialog:
OnSysCommand(nID,lParam);
OnPaint()
if(IsIconic())
CPaintDCdc(this);
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&
rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
//Drawtheicon
dc.DrawIcon(x,y,m_hIcon);
OnPaint();
OnQueryDragIcon()
return(HCURSOR)m_hIcon;
Cal_Symbol()//求出能推出ε的非终结符
inti,j,k,nEnd;
CStringGr[8];
for(i=0;
i<
5;
i++)
m_nFlags[i]=0;
//置初值,0表示否
8;
Gr[i]=m_Gr[i];
if(Gr[i]=="
)
m_nFlags[m_Gl[i]]=1;
//1表示是,即能推出ε
do
nEnd=0;
for(i=0;
i++)//检查每一个非终结符
if(m_nFlags[i]==1)//如果该非终结符能推出ε,就将所有表达式右部删去该终结符
{
for(j=0;
j<
j++)//查找每一个表达式
{
if(Gr[j].IsEmpty()||Gr[j]=="
)continue;
for(k=0;
k<
Gr[j].GetLength();
k++)//查找表达式右部的每一个字符
{
if(Gr[j].GetAt(k)==m_VN[i])//找到该终结符
{
Gr[j]=Gr[j].Left(k)+Gr[j].Right(Gr[j].GetLength()-k-1);
//删去该终结符
nEnd=1;
break;
}
}
if(Gr[j].IsEmpty())m_nFlags[m_Gl[j]]=1;
//如果右部为空,就在表中填是
}
}
}while(nEnd);
Cal_First()//求各非终结符的First集合
inti,j,k,nEnd,n;
CStringstrFirst;
for(j=0;
6;
j++)
m_First[i][j]=0;
if(m_Gr[i].Left
(2)=="
m_First[m_Gl[i]][5]=1;
continue;
strFirst=m_Gr[i].GetAt(0);
if(strFirst==m_VT[j])//如果右部第一个字符是终结符
m_First[m_Gl[i]][j]=1;
break;
do
n=0;
strFirst=m_Gr[i].GetAt(0);
do
if(strFirst==m_VN[j])//如果右部第一个字符是非终结符
for(k=0;
k++)
if(m_First[m_Gl[i]][k]!
=m_First[j][k])
{
m_First[m_Gl[i]][k]=m_First[j][k];
nEnd=1;
}
if(m_First[j][5]==1&
&
n<
m_Gr[i].GetLength()-1)//前一字符能推出ε,则下一字符的first集也包含于first(x)
strFirst=m_Gr[i].GetAt(++n);
else
strFirst="
break;
if(j==5)break;
}while(!
strFirst.IsEmpty());
Cal_Follow()//求各非终结符的Follow集合
DrawMList()//构造预测分析表
inti,j;
m_M[i][j]="
m_M[0][0]="
m_M[0][3]="
m_M[1][1]="
m_M[1][4]="
m_M[1][5]="
m_M[2][0]="
m_M[2][3]="
m_M[3][1]="
m_M[3][2]="
m_M[3][4]="
m_M[3][5]="
m_M[4][0]="
m_M[4][3]="
m_ListCtrl.SetExtendedStyle(LVS_EX_GRIDLINES);
m_ListCtrl.InsertColumn(0,"
LVCFMT_CENTER,50);
m_ListCtrl.InsertColumn(1,"
m_ListCtrl.InsertColumn(2,"
m_ListCtrl.InsertColumn(3,"
m_ListCtrl.InsertColumn(4,"
m_ListCtrl.InsertColumn(5,"
m_ListCtrl.InsertColumn(6,"
#"
m_ListCtrl.InsertItem(i,m_VN[i]);
if(!
m_M[i][j].IsEmpty())
m_ListCtrl.SetItemText(i,j+1,"
→"
+m_M[i][j]);
OnBTNAnalysis()
UpdateData(true);
if(m_strCode.IsEmpty())
MessageBox("
请输入要分析的句子!
"
提醒"
return;
if(Analysis())
m_strResult+="
归约过程如下:
\r\n\r\n"
+m_sPro.Right(m_sPro.GetLength()-3);
UpdateData(false);
//主要的程序算法
Analysis()
CStringstack[100];
intpStack;
//定义一个顺序栈
stack[0]="
stack[1]="
pStack=1;
//初始化栈
intn=0;
CStringsStack,sCode,str,strCode,strPro;
strCode=m_strCode+"
//输入串
m_sPro="
<
=S"
strPro="
while
(1)
if(n==m_strCode.GetLength()&
pStack==0)//分析成功
m_strResult="
符合给定文法."
returntrue;
sStack=stack[pStack];
//栈顶字符
sCode=strCode.GetAt(n);
//剩余输入串的首字符
if(sStack==sCode)//匹配
pStack--;
n++;
if(sStack==m_VN[i])
if(i==5)
不符合给定文法!
returnfalse;
if(sCode==m_VT[j])
if(j==5&
sCode!
="
不可识别的字符:
"
+sCode;
str=m_M[i][j];
if(str.IsEmpty())
if(str=="
strPro=strPro.Left(n)+strPro.Right(strPro.GetLength()-n-1);
m_sPro="
="
+strPro+"
\r\n"
+m_sPro;
strPro=strPro.Left(n)+str+strPro.Right(strPro.GetLength()-n-1);
m_sPro="
pStack--;
str.GetLength();
pStack++;
stack[pStack]=str.GetAt(str.GetLength()-j-1);
五、运行结果
分析句子(i+i)*i正确并写出归约
此次实验我继续使用VC++6.0平台编译程序,见面力求简洁,以满足实验功能为主。
输入句子i+i)*i时候程序判断不符合给定文法进行报错。
当输入(i+i)*i@时候出现不合法的字符@程序就会报错。
六、小结(不少于100字)
这是第二次编译原理的实验;
其主要目的是通过通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
加深对课堂教学的理解,深刻理解语法分析的整个过程,提高语法分析方法的实践能力。
经历过第一次的词法分析之后,我决定本次实验继续采用VC++6.0的编译平台;
在保持自己编程风格的简洁、朴实的前提下,尽我所能追求完善程序的界面。
在编写过程中遇到的主要问题就是如何正确分析first集合、follow集合和select集合,构造预测分析表;
另外一个难点就是根据算法和预测分析表分析给定表达式是否是该文法识别的正确的算术表达式。
在要求程序能够完成以上的功能的同时,正确报告出错类型和错误位置着实很费力气。
在编写过程中我的主要精力在于这两项功能的算法实现;
最后经过查阅资料和向同学讨论商量使得问题得到了最终的解决。
概括来讲,这一次语法分析程序很有的难度(比第一次的词法分析难一些),但是有了上一次实验的经验可以遵循,编写过程倒也还顺利;
关键的难题在于将编译原理课程所学的知识与实际编程操作有机的结合起来。
我也通过这次实验得到了这方面的锻炼。
在今后的学习中,在课余时间还需要经常加以练习才可以得到更好的提高和更深层次的理解。
在此基础上可以根据自己的兴趣多做课外的延伸和练习。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 语法分析 实验