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

📄 算符优先文法dlg.cpp

📁 编译原理课程设计 算符优先算法的实现 输出FIRSTVT和LASTVT
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 算符优先文法Dlg.cpp : implementation file
//

#include "stdafx.h"
#include "算符优先文法.h"
#include "算符优先文法Dlg.h"


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

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyDlg dialog

CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMyDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMyDlg)
	m_grammar = _T("");
	m_sentence = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMyDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMyDlg)
	DDX_Control(pDX, IDC_LIST4, m_list4);
	DDX_Control(pDX, IDC_LIST3, m_list3);
	DDX_Control(pDX, IDC_LIST2, m_list2);
	DDX_Control(pDX, IDC_LIST1, m_list);
	DDX_Control(pDX, IDC_EDIT2, m_con_sentence);
	DDX_Control(pDX, IDC_EDIT1, m_con_grammar);
	DDX_Text(pDX, IDC_EDIT1, m_grammar);
	DDX_Text(pDX, IDC_EDIT2, m_sentence);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
	//{{AFX_MSG_MAP(CMyDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, OnBianyi)
	ON_BN_CLICKED(IDOK2, OnInputDefault)
	ON_BN_CLICKED(IDCENCEL, OnCencel)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyDlg message handlers

BOOL CMyDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	FlagOk=true;                     //假定能够成功规约
	m_grammar.Empty();
	CString str;
	str = "E->E+T|T\r\nT->T*F|F\r\nF->P^F|P\r\nP->(E)|i\r\n";
	m_con_grammar.SetWindowText(str);
	m_sentence.Empty();
	str.Empty();
	str = "i+i*(i+i)^i";
	m_con_sentence.SetWindowText(str);

	 m_list.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP);
     m_list.SetTextColor(RGB(0,0,255));                  //显示字体的颜色
     m_list.SetBkColor(RGB(240,247,233));             //选中此列的颜色
     m_list.SetTextBkColor(RGB(240,247,233));           //背景颜色

	 m_list2.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP);
     m_list2.SetTextColor(RGB(0,0,255));                  //显示字体的颜色
     m_list2.SetBkColor(RGB(240,247,233));             //选中此列的颜色
     m_list2.SetTextBkColor(RGB(240,247,233));           //背景颜色

	 m_list3.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP);
     m_list3.SetTextColor(RGB(0,0,255));                  //显示字体的颜色
     m_list3.SetBkColor(RGB(240,247,233));             //选中此列的颜色
     m_list3.SetTextBkColor(RGB(240,247,233));           //背景颜色

	 m_list4.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP);
     m_list4.SetTextColor(RGB(0,0,255));                  //显示字体的颜色
     m_list4.SetBkColor(RGB(240,247,233));             //选中此列的颜色
     m_list4.SetTextBkColor(RGB(240,247,233));           //背景颜色

	 m_list2.InsertColumn(0,"步骤");
	 m_list2.InsertColumn(1,"符号栈");
	 m_list2.InsertColumn(2,"输入串",LVCFMT_RIGHT);
	 m_list2.InsertColumn(3,"动作");
	 m_list2.InsertColumn(4,"原因");
	 m_list2.InsertColumn(5,"最左素短语");

	 m_list2.SetColumnWidth(0,40);
	 m_list2.SetColumnWidth(1,100);
	 m_list2.SetColumnWidth(2,100);
	 m_list2.SetColumnWidth(3,60);
	 m_list2.SetColumnWidth(4,110);
	 m_list2.SetColumnWidth(5,80);

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMyDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMyDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CMyDlg::InitVnVt(int Ptnum)                  //生成终结符集Vt
{                                                 //和非终结符集Vn
	Vn.Empty();
	Vt.Empty();
	Start.Empty();
	int i,j;
	Start=Pt[0].pleft;
	for(i=0;i<Ptnum;i++)
	{
		if(Vn.Find(Pt[i].pleft)==-1)
			Vn+=Pt[i].pleft;
		for(j=0;j<Pt[i].pright.GetLength();j++)
		{
			if(isupper(Pt[i].pright[j]))
			{
				if(Vn.Find(Pt[i].pright[j])==-1)
					Vn+=Pt[i].pright[j];
			}
			else
				if(Vt.Find(Pt[i].pright[j])==-1)
					Vt+=Pt[i].pright[j];
		}
	}
}
int CMyDlg::InitPt()                
{

	int i;
	int spacepos=0;
	int retpos=0;
	int retflag;
	int pos;
	for(i=0;i<50;i++)
	{
		Pt[i].pleft=' ';
		Pt[i].pright=" ";
	}
	i=0;


	CString s;
	CString temp1;
	CString temp2;
	CString ret;
	s.Empty();
	temp1.Empty();
	temp2.Empty();
	ret.Empty();
	s=m_grammar+"\r\n";

	while(1)                   //删除文法之前的字符
	{
		if(s!="")
		{
			if(!isupper(s[0]))
				s.Delete(0,1);
			else break;
		}
		else
		{
			AfxMessageBox("非算符优先文法~!");
			return(-1);
		}
			
	}

	while(1)                   //删除文法前中后的空格符
	{
		spacepos=s.Find(" ");
		if(spacepos==-1)
			break;
		s.Delete(spacepos,1);
	}

	spacepos=0;
	retflag=0;
	while(1)                   //删除文法前中后多余回车符
	{
		ret.Empty();
		retpos=s.Find("\r\n",retflag);
		if(retpos==-1)
			break;
		if(retpos<=s.GetLength()-3)
		{
			ret+=s[retpos+2];
			ret+=s[retpos+3];
		}
		if(ret=="\r\n")
		{
			s.Delete(retpos,2);
			retflag=retpos;
		}
		else retflag=retpos+1;
	}


////////////////
	m_grammar=s;
	UpdateData(false);

	Start=m_grammar[0];
	s="$->#"+Start+"#\r\n"+s;

	while(s.Find("\r\n")!=-1)          //利用文法生成Pt
	{								   //每条将文法的左部存在Pt.pleft(char)	
		pos=s.Find("->");              //右部存入Pt.pright(CString)
        temp1=s.Left(pos);
		s.Delete(0,pos+2);
		while(s.Find("\r\n") > s.Find("|") && s.Find("|") != -1)
		{
			pos=s.Find("|");
			temp2=s.Left(pos);
			s.Delete(0,pos+1);
			if(temp1=="")
			{
				AfxMessageBox("非算符优先文法~!");
				return(-1);
			}
			Pt[i].pleft=temp1[0];
			Pt[i].pright=temp2;
			i++;
		}
		if(s.Find("\r\n")!=-1)
		{
			pos=s.Find("\r\n");
			temp2=s.Left(pos);
			s.Delete(0,pos+2);
			if(temp1=="")
			{
				AfxMessageBox("非算符优先文法~!");
				return(-1);
			}
			Pt[i].pleft=temp1[0];
			Pt[i].pright=temp2;
			i++;
		}
	}
	for(i=0;Pt[i].pleft!=' ' && Pt[i].pright!="";i++) {}  //计算文法长度 
	InitVnVt(i);
	return i;
}

void CMyDlg::InsertFirstOrLast(char P,char a,CString flag)
{
	int intVn;
	int intVt;
	intVn=Vn.Find(P);
	intVt=Vt.Find(a);
	if(flag=="First")
	{
		if(F[intVn][intVt]==false)
		{
			F[intVn][intVt]=true;
			stack.push(P,a);
		}
	}
	if(flag=="Last")		
	{
		if(L[intVn][intVt]==false)
		{
			L[intVn][intVt]=true;
			stack.push(P,a);
		}
	}
}

void CMyDlg::SetFirstVt(int Ptnum)               //建立FirstVt集
{
	int i,j;
	char Q;
	char a;
	for(i=0;i<100;i++)
		for(j=0;j<100;j++)
			F[i][j]=false;

	for(i=0;i<Ptnum;i++)
	{
		if(Vt.Find(Pt[i].pright[0])!=-1)
			InsertFirstOrLast(Pt[i].pleft,Pt[i].pright[0],"First");
		if(Pt[i].pright.GetLength()>=2)
			if(Vn.Find(Pt[i].pright[0])!=-1 && Vt.Find(Pt[i].pright[1])!=-1)
				InsertFirstOrLast(Pt[i].pleft,Pt[i].pright[1],"First");
	}
	while(!stack.empty())
	{
		stack.pop(Q,a);
		for(i=0;i<Ptnum;i++)
			if(Pt[i].pright[0]==Q)
				InsertFirstOrLast(Pt[i].pleft,a,"First");
	}
	

}

void CMyDlg::SetLastVt(int Ptnum)                  //建立LastVt集
{
	int i,j;
	char Q;
	char a;
	for(i=0;i<100;i++)
		for(j=0;j<100;j++)
			L[i][j]=false;
	for(i=0;i<Ptnum;i++)
	{
		if(Vt.Find(Pt[i].pright.Right(1)[0]))
			InsertFirstOrLast(Pt[i].pleft,Pt[i].pright.Right(1)[0],"Last");
		if(Pt[i].pright.GetLength()>=2)
			if(Vt.Find(Pt[i].pright.Right(2)[0])!=-1 && Vn.Find(Pt[i].pright.Right(2)[1])!=-1)
				InsertFirstOrLast(Pt[i].pleft,Pt[i].pright.Right(2)[0],"Last");
	}
	while(!stack.empty())
	{
		stack.pop(Q,a);
		for(i=0;i<Ptnum;i++)
			if(Pt[i].pright[0]==Q)
				InsertFirstOrLast(Pt[i].pleft,a,"Last");
	}

			
}

void CMyDlg::Create_G_table(int Ptnum)                   //创建算符优先表
{
	int i;
	int j;
	int k;
	int Vnnum;
	int Pos0;
	int Pos1;
	int Pos2;
	for(i=0;i<100;i++)
		for(j=0;j<100;j++)
			G[i][j]=' ';
	for(i=0;i<Ptnum;i++)
		for(j=0;j<Pt[i].pright.GetLength()-1;j++)
		{
			Pos0=Vt.Find(Pt[i].pright[j]);
			Pos1=Vt.Find(Pt[i].pright[j+1]);

⌨️ 快捷键说明

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