⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winsuanfudoc.cpp

📁 算符优先实验,可以输入文法
💻 CPP
字号:
// WinsuanfuDoc.cpp : implementation of the CWinsuanfuDoc class
//

#include "stdafx.h"
#include "Winsuanfu.h"

#include "WinsuanfuDoc.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CWinsuanfuDoc

IMPLEMENT_DYNCREATE(CWinsuanfuDoc, CDocument)

BEGIN_MESSAGE_MAP(CWinsuanfuDoc, CDocument)
	//{{AFX_MSG_MAP(CWinsuanfuDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CWinsuanfuDoc construction/destruction

charstack s;

CWinsuanfuDoc::CWinsuanfuDoc()
{
	ClearDoc();
}

void CWinsuanfuDoc::ClearDoc()
{
	int i,j;

	memset(buffer, 0, sizeof(buffer));
	pnum = 0;
	Vn.Empty();
	Vt.Empty();
	Start.Empty();

	for(i=0; i<100; i++)	
		for(j=0; j<100; j++)
		{
			F[i][j]=false;
			L[i][j]=false;
			table[i][j]=0;
		}	

	for(i=0; i<100; i++)
	{
		p6[i].pleft=0;
		p6[i].pright.Empty();
	}
}

CWinsuanfuDoc::~CWinsuanfuDoc()
{
}

BOOL CWinsuanfuDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CWinsuanfuDoc serialization

void CWinsuanfuDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CWinsuanfuDoc diagnostics

#ifdef _DEBUG
void CWinsuanfuDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CWinsuanfuDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CWinsuanfuDoc commands
void CWinsuanfuDoc::fill_VnVtStart()
{
	Start += p6[0].pright[1];

	for(int i=0; i<pnum; i++)
	{
		if(Vn.Find(p6[i].pleft) == -1)
			Vn+=p6[i].pleft;
		for(int j=0; j<p6[i].pright.GetLength(); j++)
		{
			if(isupper(p6[i].pright[j]))
			{
				if(Vn.Find(p6[i].pright[j]) == -1)
					Vn+=p6[i].pright[j];
			}else
				if(Vt.Find(p6[i].pright[j]) == -1)
					Vt+=p6[i].pright[j];
		}
	}
}


int CWinsuanfuDoc::ConvertP(CString str)
{	
	int i=0;
	int retpos=0;
	int orpos=0;
	int arrowpos=0;
	CString s,temps1,temps2;

	if(str.Find('#') == -1)
	{
		str.TrimLeft();
		if(!isupper(str[0])) return -1;

		temps1.Empty();
		temps1+="$->#";
		temps1+=str[0];
		temps1+="#\r\n";
		
		str.Insert(0,temps1);				
		temps1.Empty();
	}

	s+=str;
	s+="\r\n";

	retpos = s.Find("\r\n");
	while(retpos!=-1) 
	{
		temps1=s.Left(retpos);
		
		s.Delete(0, retpos+2);
		retpos = s.Find("\r\n");

		if(temps1.IsEmpty()) continue;
	
		temps1.TrimLeft();
		arrowpos=temps1.Find("->");
		if(temps1.Left(arrowpos).GetLength()!=1)
		{
			MessageBox(NULL,"非上下文无关文法!","CWinsuanfuDoc::ConvertP",MB_ICONEXCLAMATION);
			return -1;
		}
		
		char pleft=temps1.Left(arrowpos)[0];	
		temps1.Delete(0, arrowpos+2);

		temps1+='|';
		orpos = temps1.Find('|');
		while(orpos != -1) 
		{
			temps2=temps1.Left(orpos);				
			if(temps2.IsEmpty()) continue;

			temps2.TrimLeft();
			temps2.TrimRight();
			p6[i].pleft=pleft;
			p6[i].pright=temps2;

			temps1.Delete(0, orpos+1);
			orpos = temps1.Find('|');
			i++;
		}//while '|'		
	
	}//while 0d 0a
	pnum = i;

	fill_VnVtStart();

	return pnum;
}


CString CWinsuanfuDoc::display_G()
{
	CString str;
	
	str += "Vn={" + Vn + "}\r\n";
	str += "Vt={" + Vt + "}\r\n";
	str += "S={" + Start + "}\r\n";

	for(int i=0; i<pnum; i++)
	{
		str += p6[i].pleft;
		str += " -> ";
		str += p6[i].pright;
		str += "\r\n";		
	}

	return str;
}

void CWinsuanfuDoc::InsertF(char p, char a)
{
	int p1=Vn.Find(p);
	int a1=Vt.Find(a);
	
	ASSERT(p1!=-1 && a1!=-1);

	if(!F[p1][a1])
	{
		F[p1][a1] = true;
		s.push(p,a);
	}
}

void CWinsuanfuDoc::InsertL(char p, char a)
{
	int p1=Vn.Find(p);
	int a1=Vt.Find(a);
	
	ASSERT(p1!=-1 && a1!=-1);

	if(!L[p1][a1])
	{
		L[p1][a1] = true;
		s.push(p,a);
	}
}

void CWinsuanfuDoc::FirstVt()
{
	char a0,a1;
	int row = Vn.GetLength();
	int col = Vt.GetLength();

	for(int i=0; i<row; i++)
		for(int j=0; j<col; j++)
			F[i][j] = false;

	for(i=0; i<pnum; i++)
	{
		a0=p6[i].pright[0];
		if(Vt.Find(a0) != -1)
		{
			InsertF(p6[i].pleft, a0);
			continue;
		}
		
		if(p6[i].pright.GetLength() <= 1) continue;

		a1=p6[i].pright[1];
		if(Vn.Find(a0) != -1 && Vt.Find(a1) != -1)
			InsertF(p6[i].pleft, a1);
	}

	while(!s.empty())
	{
		char q, a;		
		s.pop(q, a);
		for(i=0; i<pnum; i++)
			if(p6[i].pright[0]  == q)
				InsertF(p6[i].pleft, a);

	}

}

void CWinsuanfuDoc::LastVt()
{
	char a0,a1;
	int row = Vn.GetLength();
	int col = Vt.GetLength();

	for(int i=0; i<row; i++)
		for(int j=0; j<col; j++)
			L[i][j] = false;

	for(i=0; i<pnum; i++)
	{
		a0=p6[i].pright.Right(1)[0];
		if(Vt.Find(a0) != -1)
		{
			InsertL(p6[i].pleft, a0);
			continue;
		}
		
		if(p6[i].pright.GetLength() <= 1) continue;

		a1=p6[i].pright.Right(2)[0];
		if(Vn.Find(a0) != -1 && Vt.Find(a1) != -1)
			InsertL(p6[i].pleft, a1);
	}

	while(!s.empty())
	{
		char q, a;		
		s.pop(q, a);
		for(i=0; i<pnum; i++)
			if(p6[i].pright.Right(1)[0]  == q)
				InsertL(p6[i].pleft, a);

	}
}


void CWinsuanfuDoc::createtable(CString str)
{
	ClearDoc();
	
	int findspace = str.Find(' ');
	while(findspace!=-1)
	{
		str.Delete(findspace,1);
		findspace = str.Find(' ');
	}

	if(ConvertP(str) == -1) return;
	FirstVt();
	LastVt();
	
	int vtnum = Vt.GetLength();
	
	for(int j=0; j<pnum; j++)
	{
		for(int i=0; i<p6[j].pright.GetLength()-1; i++)
		{
			char xi = p6[j].pright[i];
			char xi1 = p6[j].pright[i+1];
			int pxi = Vt.Find(xi);
			int pxi1 = Vt.Find(xi1);

			if(pxi != -1 && pxi1 != -1) 
			{
				if(table[pxi][pxi1] == 0)
					table[pxi][pxi1] = '=';
				else
				{
					MessageBox(NULL, "不是算符优先文法", NULL, MB_ICONEXCLAMATION);
					return;
				}
				continue;
			}

			if(i+2 < p6[j].pright.GetLength())
			{
				char xi2 = p6[j].pright[i+2];
				int pxi2 = Vt.Find(xi2);

				if(pxi != -1 && pxi1 == -1 && pxi2 != -1)
				{
					if(table[pxi][pxi2] == 0)
						table[pxi][pxi2] = '=';
					else
					{
						MessageBox(NULL, "不是算符优先文法", NULL, MB_ICONEXCLAMATION);
						return;
					}
				}
			}

			if(pxi != -1 && pxi1 == -1)
			{
				pxi1 = Vn.Find(xi1);
				ASSERT(pxi1 != -1);
				for(int k=0; k<vtnum; k++)
					if(F[pxi1][k]) 
					{
						if(table[pxi][k] == 0)
							table[pxi][k] = '<';
						else
						{
							MessageBox(NULL, "不是算符优先文法", NULL, MB_ICONEXCLAMATION);
							return;
						}
					}
				continue;
			}
			
			if(pxi == -1 && pxi1 != -1)
			{
				pxi = Vn.Find(xi);
				ASSERT(pxi != -1);
				for(int k=0; k<vtnum; k++)
					if(L[pxi][k])
					{
						if(table[k][pxi1] == 0)
							table[k][pxi1] = '>';
						else
						{
							MessageBox(NULL, "不是算符优先文法", NULL, MB_ICONEXCLAMATION);
							return;
						}
					}
			}
		} 
	}
}

CString CWinsuanfuDoc::display_firstvt()
{	
	char p, a;
	CString str;

	int row = Vn.GetLength();
	int col = Vt.GetLength();

	for(int i=0; i<row; i++)
	{
		p = Vn[i];
		str += "FIRSTVT(";
		str +=  p;
		str += ") = {";
		for(int j=0; j<col; j++)
			if (F[i][j])
			{
				a = Vt[j];
				str += a;
				str += " ";
			}
		str+= "}\r\n";
	}
	return str;
}

CString CWinsuanfuDoc::display_lastvt()
{
	char p, a;
	CString str;

	int row = Vn.GetLength();
	int col = Vt.GetLength();

	for(int i=0; i<row; i++)
	{
		p = Vn[i];
		str += "LASTVT(";
		str += p;
		str += ") = {";
		for(int j=0; j<col; j++)
			if (L[i][j])
			{
				a = Vt[j];
				str += a;
				str += " ";
			}
		str += "}\r\n";
	}
	
	return str;
}

CString CWinsuanfuDoc::display_table()
{
	CString str;

	str+="文法 \r\n";
	str+=display_G();

	str+="\r\nFIRSTVT和LASTVT \r\n";
	str+=display_firstvt();
	str+=display_lastvt();

	int row = Vt.GetLength();
	int col = Vt.GetLength();

	str += "\r\n算符优先表\r\n";
	for(int i=0; i<=col; i++)
		str += "----+";
	str+="\r\n";

	str+="    |";
	
	for(i=0; i<col; i++)
	{
		str += Vt[i];
		str += "   |";
	}
	str+="\r\n";

	for(i=0; i<=col; i++)
		str+="----+";
	str+="\r\n";
	
	for(i=0; i<row; i++)
	{
		str += Vt[i];
		str += "   |";
		for(int j=0; j<col; j++)
		{
			str+=table[i][j]?table[i][j]:' ';
			str+="   |";
		}
		str += "\r\n";
		for(j=0; j<=col; j++)
			str += "----+";
		str+="\r\n";
	}
	return str;
	
}


int CWinsuanfuDoc::mymatch(CString str)
{
	int ret=-1;
	
	//首先找出最匹配的产生式,即终结符全部匹配
	for(int i=0; i<pnum; i++)
	{
		//长度匹配
		if(p6[i].pright.GetLength() != str.GetLength()) continue;

		for(int j=0; j<str.GetLength(); j++)
		{
			if(str[j] == p6[i].pright[j]) continue;

			int sj=Vt.Find(str[j]);				//字符串
			int pj=Vt.Find(p6[i].pright[j]);	//产生式

			if((sj==-1 && pj!=-1) || 
				(sj!=-1 && pj==-1)) break;		//一个是终结符一个是非终结符
			if(sj != -1 && pj != -1) break;		//终结符不匹配
		}

		if(j>=str.GetLength()) break;
	}
	
	if(i >= pnum) return -1;

	//然后看str能否归约到这个产生式
	int matchpos = i;
	int count =0;
	while(p6[matchpos].pright.Compare(str)!=0)
	{
		if(count++ > pnum) return -1;

		for(int j=0; j<str.GetLength(); j++)
		{
			if(str[j] == p6[matchpos].pright[j]) continue;

			for(i=0; i<pnum; i++)
			{
				if(p6[i].pright.GetLength() == 1 &&
					p6[i].pright[0] == str[j])
				{
					str.Delete(j);
					str.Insert(j, p6[i].pleft);	
					break;
				}
			}
			if(i < pnum) break;
		}
	}

	
	return matchpos;
}

CString CWinsuanfuDoc::analyzer(CString str)
{
	if(str.Find('#')==-1) str+='#';

	int row=0;
	int i=0,k=0,j=0;
	int pa,pq,pj;
	char a,q;
	CString s;
	CString endstr;
	CString retstr;
	CString tmpstr;

	retstr = "步骤		栈		输入串		动作	原因\r\n";
	retstr +="-------------------------------------------------------------\r\n";

	s += '#';
	endstr += '#';
	endstr += Start;
	
	while(1)
	{
		tmpstr.Empty();
		tmpstr.Format("%d\t%10s%20s", row, s, str.Right(str.GetLength()-i));
		retstr+=tmpstr;

		row++;
		a=str[i];
		if(a == '#')
		{
			if(s.Compare(endstr) == 0)
				break;
			
			if(s.GetLength() == 2)
			{
				int r=mymatch(s.Right(1));
				int count=0;
				while(p6[r].pleft != Start[0] && count++ < pnum)				
					r=mymatch(s.Right(1));	
				
				if(p6[r].pleft != Start[0])
				{
					MessageBox(NULL, "error1", "analysis", MB_ICONEXCLAMATION);
					break;
				}

				s.Delete(1);
				s.Insert(1, Start);

				tmpstr.Empty();
				tmpstr.Format("%14s  LastVn\r\n","归约");
				retstr += tmpstr;

				continue;
			}
		}
		

		if(Vt.Find(s[k]) != -1)
			j=k;
		else
			j=k-1;

		if(j<0)
		{
			MessageBox(NULL, "error2", "analysis", MB_ICONEXCLAMATION);
					break;
		}
		
		pa=Vt.Find(a);
		pj=Vt.Find(s[j]);
		ASSERT(pa!=-1 && pj!=-1);
		if(table[pj][pa] == '>')
		{
			tmpstr.Empty();
			tmpstr.Format("%14s     %c%c%c\r\n","归约",Vt[pj],table[pj][pa],Vt[pa]);
			retstr += tmpstr;

			do
			{
				q=s[j];
				pq=Vt.Find(q);

				if(Vt.Find(s[j-1])!=-1) j-=1;
				else j-=2;			

				pj=Vt.Find(s[j]);
				ASSERT(pj != -1 && pq != -1);				
			}
			while(table[pj][pq] == '>' || table[pj][pq] == '=');

			//归约
			for(int len=0; len<pnum; len++)
			{
				if(p6[len].pright.Compare(s.Right(s.GetLength()-j-1)) == 0)
					break;
			}
			
			if(len >= pnum)
			{				
				len = mymatch(s.Right(s.GetLength()-j-1));
				if(len == -1)
				{
					MessageBox(NULL, "error3", "analysis", MB_ICONEXCLAMATION);
					break;
				}				
			}

			k=j+1;			
			s.Delete(k, s.GetLength()-k);
			s+=p6[len].pleft;
			continue;
		}

		if(table[pj][pa] == '<' || table[pj][pa] == '=')
		{			
			tmpstr.Empty();
			tmpstr.Format("%14s     %c%c%c\r\n","移进",Vt[pj],table[pj][pa],Vt[pa]);
			retstr += tmpstr;

			k++;
			s += a;
		}
		if(table[pj][pa] == 0)
		{
			tmpstr.Empty();
			tmpstr.Format("error:%c和%c没有优先关系\r\n",Vt[pj],Vt[pa]);

			MessageBox(NULL, tmpstr, "analysis", MB_ICONEXCLAMATION);
					break;
		}
		i++;
	}
	
	retstr += "\r\n";

	return retstr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -