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

📄 ll1_parsingdlg.cpp

📁 LL(1)文法分析过程的可视化及教学应用研究
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// gramDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ll1_parsing.h"
#include "ll1_parsingDlg.h"
#include "operation.h"
#include "dlg1.h"
#include "dlg3.h"



#include <afxwin.h>


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

CGram gram;
Cdlg1 dlg;
Cdlg3 dlgc;

CString rexp[DEN];

char s_t[L_STR]={0},s_exp1[LEN]={0},s_exp2[LEN]={0};
int s_top1=0,s_top2=0,s_c=0,s_error=0;
int lx=-1,ly=-2;


/////////////////////////////////////////////////////////////////////////////
// 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)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Cll1_parsingDlg dialog

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

void Cll1_parsingDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(Cll1_parsingDlg)
	DDX_Control(pDX, IDC_LIST2, m_pro);
	DDX_Control(pDX, IDC_LIST1, m_list);
	DDX_Text(pDX, IDC_EDIT1, m_G);
	DDX_Text(pDX, IDC_EDIT5, m_grammar);
	DDX_Text(pDX, IDC_EDIT6, m_exp);
	DDX_Text(pDX, IDC_STATIC1, m_tag);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(Cll1_parsingDlg, CDialog)
	//{{AFX_MSG_MAP(Cll1_parsingDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
	ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
	ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
	ON_BN_CLICKED(IDC_BUTTON4, OnButton4)
	ON_BN_CLICKED(IDC_BUTTON5, OnButton5)
	ON_BN_CLICKED(IDC_BUTTON6, OnButton6)
	ON_EN_CHANGE(IDC_EDIT1, OnChangeEdit1)
	ON_BN_CLICKED(IDC_BUTTON7, OnButton7)
	ON_EN_CHANGE(IDC_EDIT6, OnChangeEdit6)
	ON_BN_CLICKED(IDC_BUTTON8, OnButton8)
	ON_BN_CLICKED(IDC_BUTTON9, OnButton9)
	ON_NOTIFY(NM_CLICK, IDC_LIST2, OnClickList2)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Cll1_parsingDlg message handlers

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

	// 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);


    m_list.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, \
		LVS_EX_GRIDLINES |LVS_EX_FULLROWSELECT);

    m_pro.SendMessage(LVM_SETEXTENDEDLISTVIEWSTYLE, 0, \
		LVS_EX_GRIDLINES |LVS_EX_FULLROWSELECT);


	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 Cll1_parsingDlg::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 Cll1_parsingDlg::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 Cll1_parsingDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void Cll1_parsingDlg::OnButton1() 
{
	UpdateData(1);
    char exp[L_STR] = {0};
    int k,j,i,s,t,c,pos;
//	int sign;
	CString str;
	
	if(m_grammar!="")
		memcpy(exp,m_grammar,m_grammar.GetLength());
	else
		memcpy(exp,m_G,m_G.GetLength());

	lx=-1;
	ly=-2;
	s_c=0;

if(m_G!=""||m_grammar!="")
{
	gram.initial();
	
	gram.save_grammar(exp);

	dlg.first=gram.get_first();
	dlg.follow=gram.get_follow();
	dlg.select=gram.get_select();

	dlg.m_follow="";
	dlg.m_select="";
	dlg.m_first="";

	m_tag="";
	m_list.DeleteAllItems();
	while(m_list.DeleteColumn(0));
	m_pro.DeleteAllItems();
	while(m_pro.DeleteColumn(0));
	
	GetDlgItem(IDC_BUTTON5)->EnableWindow(0);
	GetDlgItem(IDC_EDIT6)->EnableWindow(0);
	GetDlgItem(IDC_BUTTON3)->EnableWindow(0);
	GetDlgItem(IDC_BUTTON7)->EnableWindow(0);

	if(gram.tag[1]==1)
	    m_tag="文法格式不合法!\r\n";
	else if(gram.tag[2]==1)
		m_tag="文法右部中含有字符'#'!\r\n";
	else if(gram.tag[3]==1)
		m_tag="右部含有错误非终结符!\r\n";
	else if(gram.tag[5]==1)
		m_tag="有select集为空的规则!\r\n";
	else
	{

	GetDlgItem(IDC_BUTTON5)->EnableWindow(1);
    
	for(k=0;k<gram.fw;k++)
	{
	    dlg.m_follow+="follow(";
			dlg.m_follow+=gram.follow[k][0];
			dlg.m_follow+=") = { ";

		for(j=1;j<=gram.count_follow[k];j++)
		{
			dlg.m_follow+=gram.follow[k][j];
            if(j!=gram.count_follow[k])
			dlg.m_follow+=',';
		}
	    dlg.m_follow+=" }\r\n";
	}

	for(k=0;k<gram.n;k++)
	{
	    dlg.m_first+="first(";
		dlg.m_first+=gram.first[k][0];
		dlg.m_first+="->";

		for(j=1;j<=gram.G[k][0].tag;j++)
			dlg.m_first+=gram.G[k][j].letter;
		dlg.m_first+=") = { ";
		
		for(j=1;j<=gram.count_first[k];j++)
		{
			dlg.m_first+=gram.first[k][j];
            if(j!=gram.count_first[k])
			dlg.m_first+=',';
		}
	    dlg.m_first+=" }\r\n";
	}


	for(k=0;k<gram.n;k++)
	{
	    dlg.m_select+="select(";
		dlg.m_select+=gram.select[k][0];
		dlg.m_select+="->";

		for(j=1;j<=gram.G[k][0].tag;j++)
			dlg.m_select+=gram.G[k][j].letter;
		dlg.m_select+=") = { ";
		
		for(j=1;j<=gram.count_select[k];j++)
		{
			dlg.m_select+=gram.select[k][j];
            if(j!=gram.count_select[k])
			dlg.m_select+=',';
		}
	    dlg.m_select+=" }\r\n";
	}


	
	
	
/*	
		for(k=0;k<gram.n;k++)
		{
			m_grammar+=gram.G[k][0].letter;
			m_grammar+="->";

			for(j=1;j<=gram.G[k][0].tag;j++)
				m_grammar+=gram.G[k][j].letter;

			m_grammar+="\r\n";
		}

*/

/*	if(m_grammar=="")
	{
		for(k=0;k<gram.fw;k++)
		{
			sign=0;
			for(i=0;i<gram.n;i++)
			{
				if(gram.G[i][0].letter==gram.follow[k][0])
				{
					if(sign==0)
					{
						sign=1;
						m_grammar+=gram.follow[k][0];
						m_grammar+="->";
					}

					for(j=1;j<=gram.G[i][0].tag;j++)
					{
						m_grammar+=gram.G[i][j].letter;
					}
					m_grammar+='|';

				}
			}
			m_grammar=m_grammar.Left(m_grammar.GetLength()-1);
			m_grammar+="\r\n";
		}
	}

*/

	
	
	
	if(gram.tag[0]==1)
		m_tag="文法不是LL(1)文法!\r\n";
	else
	{
		m_tag="文法是LL(1)文法!\r\n";
    m_list.InsertColumn(0,"VN",LVCFMT_CENTER,30,-1);
	k=1;
	
	for(j=0;j<256;j++)
	{
		if(gram.vt[j]==2)
		{

			m_list.InsertColumn(k,(char*)&j,LVCFMT_CENTER,55,-1);
		    k++;
		}
	}

	for(j=0;j<256;j++)
	{
		if(gram.vn[j]==2)
		{
			pos=m_list.InsertItem(m_list.GetItemCount(),(char*)&j);

			for(i=0;i<gram.n;i++)
			{
				
				if(gram.select[i][0]==(char)j)
				{
					k=0;
					for(s=0;s<256;s++)
						if(gram.vt[s]==2)
						{
							for(t=1;t<=gram.count_select[i];t++)
							{
								if(gram.select[i][t]==(char)s)
								{
									str=gram.G[i][0].letter;
									str+="->";
									for(c=1;c<=gram.G[i][0].tag;c++)
										str+=gram.G[i][c].letter;
								}
							}
							k++;
							if(str!="")
							{
							    m_list.SetItemText(pos,k,str);
                                str="";
							}
						}
				}
			}
		}
	}
	}
	GetDlgItem(IDC_EDIT6)->EnableWindow(!gram.tag[0]);
	GetDlgItem(IDC_BUTTON3)->EnableWindow(!gram.tag[0]);
	GetDlgItem(IDC_BUTTON7)->EnableWindow(!gram.tag[0]);

}

	UpdateData(0);

}
}




void Cll1_parsingDlg::OnButton2() 
{
	UpdateData(1);
	CString addr;
    CFile file;
	char str[L_STR]={0};
	int fileread;

	
	CFileDialog fileDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
						"All Files (*.*)|*.*||", NULL);
	if (IDOK == fileDlg.DoModal())
	{
		addr = fileDlg.GetPathName();
	}
	
	
	if (!file.Open(addr, CFile::modeRead | CFile::typeBinary))
	{
		AfxMessageBox("文件不存在或打开文件出错!");
		return;

	}


	((CEdit*)GetDlgItem(IDC_EDIT5))->SetReadOnly(1);
	GetDlgItem(IDC_BUTTON5)->EnableWindow(0);
	GetDlgItem(IDC_EDIT6)->EnableWindow(0);
	GetDlgItem(IDC_BUTTON3)->EnableWindow(0);
	GetDlgItem(IDC_BUTTON7)->EnableWindow(0);
	GetDlgItem(IDC_BUTTON8)->EnableWindow(0);
	GetDlgItem(IDC_BUTTON9)->EnableWindow(0);


	fileread = file.Read(str, L_STR);
	file.Close();
	

	if ((addr.Right(5))=="#.txt")
	{
		GetDlgItem(IDC_BUTTON8)->EnableWindow(1);
		((CEdit*)GetDlgItem(IDC_EDIT5))->SetReadOnly(0);

		m_grammar=str;

	}
	else
		m_grammar="";
	

	gram.initial();
	dlg.m_first="";
	dlg.m_follow="";
	dlg.m_select="";
	dlgc.m_change="";
	m_exp="";
	m_process="";
    	m_tag="";
	m_G="";	
	lx=-1;
	ly=-2;
	s_c=0;
	m_list.DeleteAllItems();
	while(m_list.DeleteColumn(0));
	m_pro.DeleteAllItems();
	while(m_pro.DeleteColumn(0));

	gram.initial();

	m_G=str;
	
	UpdateData(0);
}


void Cll1_parsingDlg::OnButton3() 
{
    CString exp,tt;
	char t[L_STR]={0},exp1[LEN]={0},exp2[LEN]={0};
    int i=0,j=0,top1=0,top2=0,sign=0,c=0,error=0,pos;
	
	UpdateData(1);

	s_c=0;
	
    if(m_exp!="")
	{
	strcpy(t,m_exp);
	for(j=1,i=m_exp.GetLength()-1;i>=0;i--,j++)
		exp1[j]=t[i];
    exp1[0]='#';
	top1=j-1;

    exp2[0]='#';
	exp2[1]=gram.begin_ch;
    
	top2=1;
 
    m_pro.DeleteAllItems();
	while(m_pro.DeleteColumn(0));

	m_pro.InsertColumn(1,"步骤",LVCFMT_CENTER,40,-1);                           
    m_pro.InsertColumn(2,"分析栈",LVCFMT_LEFT,145,-1);
	m_pro.InsertColumn(3,"剩余输入串",LVCFMT_RIGHT,145,-1);
    m_pro.InsertColumn(4,"推导所用产生式或匹配",LVCFMT_CENTER,140,-1);

	while(top1>=0 || top2>=0)
	{
		c++;
        tt.Format("%d",c);
	    pos=m_pro.InsertItem(m_pro.GetItemCount(),tt);
        tt="";
		
		for(i=0;i<=top2;i++)
			tt+=exp2[i];

        m_pro.SetItemText(pos,1,tt);

		tt="";
		
		for(i=top1;i>=0;i--)
			tt+=exp1[i];

        m_pro.SetItemText(pos,2,tt);
		
		tt="";

		if(top1<0 ||top2<0)
		{
		    exp="匹配出错";
			error=1;
		}
		else if(gram.vt[exp2[top2]]!=0)
		{
			if(exp2[top2]==exp1[top1])
			{
			    exp="\'";
				exp+=exp2[top2];
				exp+="\'";
				exp+="匹配";
				top1--;
			    top2--;
				if(top1<0&&top2<0)
					exp="接受";
			}
			else
			{
				exp="匹配出错";
				error=1;
			}
		}

		else
		{
			sign=0;
			for(i=0;i<gram.n;i++)
			{
				if(gram.select[i][0]==exp2[top2])
					for(j=1;j<=gram.count_select[i];j++)
						if(gram.select[i][j]==exp1[top1])
						{
							sign=1;
							break;
						}

				if(sign==1)break;
			}

			if(sign==1)
			{
				top2--;
				for(j=gram.G[i][0].tag;j>=1;j--)
				{
					if(gram.G[i][j].letter!='@')
					    exp2[++top2]=gram.G[i][j].letter;
				}

				exp=gram.G[i][0].letter;
				exp+="->";
				for(j=1;j<=gram.G[i][0].tag;j++)
					exp+=gram.G[i][j].letter;
			}
			else
			{
				exp="匹配出错";
				error=1;
			}
		}

        m_pro.SetItemText(pos,3,exp);

		if(error==1)break;
	}
	}
	
	GetDlgItem(IDC_BUTTON7)->EnableWindow(1);
	UpdateData(0);
}

void Cll1_parsingDlg::OnButton4() 
{
	UpdateData(1);
	CString addr;
    CFile file;
	char str[L_STR]={0};

if(m_G!="")
{

	memcpy(str,m_G,m_G.GetLength());
	CFileDialog fileDlg(FALSE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
						"All Files (*.*)|*.*||", NULL);

	if (IDOK == fileDlg.DoModal())
	{
		addr = fileDlg.GetPathName();
	}
	
	if (!file.Open(addr, CFile::modeCreate|CFile::modeWrite))
	{
		AfxMessageBox("没有输入文件名或没有保存文件");
		return;
	}

	file.Write(m_G, m_G.GetLength());
	file.Close();
	UpdateData(0);
}
else
MessageBox("没有文法");
}



void Cll1_parsingDlg::OnButton5() 
{

	dlg.DoModal();
}




void Cll1_parsingDlg::OnButton6() 
{
	UpdateData(1);
    char exp[L_STR] = {0};
    int k,j,i,sign;

	dlg.m_first="";
	dlg.m_follow="";
	dlg.m_select="";
	m_exp="";
	m_process="";
    m_grammar="";
	m_tag="";
	dlgc.m_change="";
	m_list.DeleteAllItems();
	while(m_list.DeleteColumn(0));

⌨️ 快捷键说明

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