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

📄 4rdview.cpp

📁 编译原理实验
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 4rdView.cpp : implementation of the CMy4rdView class
//

#include "stdafx.h"
#include "4rd.h"

#include "4rdDoc.h"
#include "4rdView.h"

#include "function.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CDialogBar m_WndDlgBar;
/////////////////////////////////////////////////////////////////////////////
// CMy4rdView

IMPLEMENT_DYNCREATE(CMy4rdView, CScrollView)

BEGIN_MESSAGE_MAP(CMy4rdView, CScrollView)
	//{{AFX_MSG_MAP(CMy4rdView)
	ON_COMMAND(ID_Input, OnInput)
	ON_COMMAND(ID_Tree, OnTree)
	ON_WM_CHAR()
	ON_COMMAND(ID_Caculate, OnCaculate)
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_COMMAND(ID_Example1, OnExample1)
	ON_COMMAND(ID_Example2, OnExample2)
	ON_COMMAND(ID_Example3, OnExample3)
	ON_COMMAND(ID_Example4, OnExample4)
	ON_COMMAND(ID_Example5, OnExample5)
	ON_COMMAND(ID_Example6, OnExample6)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMy4rdView construction/destruction

CMy4rdView::CMy4rdView()
{
	// TODO: add construction code here
	input=false;
	m_input=false;
	m_Instring="";
	m_count=1;
	m_tree=false;
	m_cal=false;
	ptree=false;
	m_x=400;
	m_y=50;
	m_inVar=false;
	move=false;
	first=false;
}

CMy4rdView::~CMy4rdView()
{
}

BOOL CMy4rdView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMy4rdView drawing

void CMy4rdView::OnDraw(CDC* pDC)
{
	CMy4rdDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	RECT rt;
	GetWindowRect(&rt );
	CRect rect;
	GetClientRect(&rect);
	pDC->SetTextColor(RGB(128,128,128));
	pDC->TextOut(rt.top-320+rect.Width(),rt.left-20+rect.Height(),"tips:图形可以按住鼠标左键拖动");
	pDC->SetTextColor(RGB(0,0,0));
	///////////////输出输入字符串////////////
	pDC->SetTextColor(RGB(64,64,64));
	if(input==true)
		pDC->TextOut(0,0,m_Instring);
	pDC->SetTextColor(RGB(0,0,0));
	/////////////////////////////////////////

	///////////////输出语法树////////////////
	if(ptree==true)
		PTree(pDC);
	/////////////////////////////////////////

	///////////////输出单步计算//////////////
	if(out_cal==true)
		Caculate(pDC);
	/////////////////////////////////////////

	/////////////////单步计算时输出标识符的值///////////////
	if(m_id==true)
	{
		pDC->SetTextColor(RGB(255,0,0));//设置字体颜色
		CString str;
		int j=1;
		for(int i=1;i<=total;i++)
		{
			if(table[i].evaluated==true)
			{
				str.Format("=%.2f",table[i].value);
				pDC->TextOut(5,j*20,table[i].name+str);
				j++;
			}
		}//for
		pDC->SetTextColor(RGB(0,0,0));//把字体颜色设回黑色
	}
	////////////////////////////////////////////////////////
	if(m_result==true)
	{
		pDC->SetTextColor(RGB(255,0,0));
		pDC->TextOut(m_x-80,m_y,"最终结果=");
		pDC->SetTextColor(RGB(0,0,0));
	}

}

void CMy4rdView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	CSize sizeTotal;
	// TODO: calculate the total size of this view
	sizeTotal.cx = 10240;
	sizeTotal.cy = 8000;
	SetScrollSizes(MM_TEXT, sizeTotal);
}

/////////////////////////////////////////////////////////////////////////////
// CMy4rdView printing

BOOL CMy4rdView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CMy4rdView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CMy4rdView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CMy4rdView diagnostics

#ifdef _DEBUG
void CMy4rdView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CMy4rdView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CMy4rdDoc* CMy4rdView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy4rdDoc)));
	return (CMy4rdDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMy4rdView message handlers

void CMy4rdView::OnInput() 
{
	// TODO: Add your command handler code here
	initial();
	m_input=true;
	m_Instring="请输入表达式(以#或回车键结束):";
	SetScrollPos(SB_HORZ,0,TRUE);//另x轴返回最左边
	SetScrollPos(SB_VERT,0,TRUE);//另y轴返回最上边
	Invalidate();
	TEXTMETRIC metric;
	CClientDC dc(this);
	dc.GetTextMetrics(&metric);
	CreateSolidCaret(metric.tmAveCharWidth/8,metric.tmHeight);
	CSize size=dc.GetTextExtent(m_Instring);
	SetCaretPos(CPoint(size.cx,0));
	ShowCaret();
	m_WndDlgBar.GetDlgItem(ID_Tree)->SetWindowText("开始生成语法树(F5)");
	m_WndDlgBar.GetDlgItem(ID_Caculate)->SetWindowText("开始进行计算(F8)");
	this->SetFocus();	//设置焦点到输入框
}


void CMy4rdView::OnTree() 
{
	// TODO: Add your command handler code here
	if(m_tree==true)
	{
		if(first==true)
		{
			for(int i=0;i<100;i++)
			{
				table[i].evaluated=false;
				strcpy(table[i].name,"");
			}
			number=1;
			position=1;
			gettoken();
			root=extr();
			if(isok==false)	//遇到错误退出
			{
				m_tree=false;
				MessageBox("请重新输入!","编译原理");
				OnInput();	//重新输入
				return;
			}
			if(root->left==NULL||root->right==NULL)	//没可能跟结点的孩子为空
			{
				m_tree=false;
				MessageBox("输入错误!请重新输入!");
				OnInput();	//重新输入
				return;
			}
/*			if(!ErrorTest(root))	//错误检测
			{
				m_tree=false;
				MessageBox("ErrorTest函数检测到错误!");
				return;
			}
			*/
//			if(lookahead!=0)
//				MessageBox("不正常结束!");
//			MessageBox("语法树生成成功!");
			for(i=0;i<100;i++)
				Pos[i]=NULL;
			xy *p=new xy;
			p->x=m_x;
			p->y=m_y;
			Pos[root->No]=p;
			ZuoBiao(root->left,root,0);	//把所以结点的坐标算出来,储存在xy[]数组中
			ZuoBiao(root->right,root,0);
			number=1;
			first=false;
			ptree=true;
			Invalidate();
			m_WndDlgBar.GetDlgItem(ID_Tree)->SetWindowText("扩展下一个根(F5)");
//			MessageBox("语法树开始生成!按F5键继续!","编译原理");
		}
		else
		{
			number++;
			Invalidate();
			if(number>=root->No)
			{
				m_WndDlgBar.GetDlgItem(ID_Tree)->SetWindowText("开始生成语法树(F5)");
				MessageBox("语法树生成完毕!","编译原理");
				m_cal=true;
				out_cal=true;
				first2=true;
				m_tree=false;
			}
		}
	}
	else
		MessageBox("请先输入完整的表达式!","编译原理");
}

void CMy4rdView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_input==true)
	{
		if(isalpha(nChar)||isdigit(nChar)||nChar=='('||nChar==')'||nChar=='#'||
			nChar=='+'||nChar=='-'||nChar=='*'||nChar=='/'||nChar=='.'||nChar=='='||
			nChar==' ')
		{
			buffer[m_count]=nChar;
			m_count++;
			m_Instring+=nChar;
			CClientDC dc(this);
			CSize size=dc.GetTextExtent(m_Instring);
			SetCaretPos(CPoint(size.cx,0));		//重设光标位置
			Invalidate();
			if(nChar=='#')
			{
				m_input=false;	//输入结束
				m_tree=true;	//语法树可以开始生成了
				first=true;
				MessageBox("输入完毕","编译原理");
			}
		}
		if(nChar==VK_RETURN)	//遇到回车键的处理
		{
			buffer[m_count]=nChar;
			m_input=false;	//输入结束
			m_tree=true;	//语法树可以开始生成了
			first=true;
			MessageBox("输入完毕","编译原理");
		}
		if(nChar==VK_BACK)	//遇到回退键的处理
		{
			if(m_count>1)
			{
				m_count--;
				m_Instring="请输入表达式(以#或回车键结束):";
				int i=1;
				while(i<m_count)
				{
					m_Instring+=buffer[i];
					i++;
				}
				CClientDC dc(this);
				CSize size=dc.GetTextExtent(m_Instring);
				SetCaretPos(CPoint(size.cx,0));		//重设光标位置
				Invalidate();
			}
		}
	}

	CScrollView::OnChar(nChar, nRepCnt, nFlags);
}

void CMy4rdView::OnCaculate() 
{
	// TODO: Add your command handler code here
	if(m_cal==true)
	{	
		node *p;
		if(first2==true)	//按第一下
		{
			m_WndDlgBar.GetDlgItem(ID_Caculate)->SetWindowText("计算下一个运算(F8)");
			ptree=false;
			qe.EnQueue(root);
			while(!qe.IsEmpty())
			{
				p=qe.DelQueue();
				if(p->right!=NULL)
					qe.EnQueue(p->right);
				if(p->left!=NULL)
					qe.EnQueue(p->left);			
				if(p->left!=NULL&&p->right!=NULL)
					sl.Push(p);
			}
			first2=false;
			p=sl.GetTop();	//先取栈顶第一个元素出来判断,如果能运算才出栈,不能就不出	
			if(p->left->code==8&&p->right->code==8)	//左右子树都是数字,则可以立即运算
			{
				switch((int)p->code){
				case 1:
					p->value=p->left->value+p->right->value;
					break;
				case 2:
					p->value=p->left->value-p->right->value;
					break;
				case 3:
					p->value=p->left->value*p->right->value;
					break;
				case 4:
					if(p->right->value>-0.00001&&p->right->value<0.00001)
					{
						MessageBox("错误:除法时除数为0!");
						isok=false;
						m_cal=false;
						return;
					}
					p->value=p->left->value/p->right->value;
					break;
				case 9:
					if(p->right->value>-0.00001&&p->right->value<0.00001)
					{
						MessageBox("错误:整除时除数为0!");
						isok=false;
						m_cal=false;
						return;
					}
					if(p->left->value>=p->right->value)
						p->value=(int)p->left->value/(int)p->right->value;
					else
						p->value=0;
					break;
				case 10:
					if(p->right->value>-0.00001&&p->right->value<0.00001)
					{
						MessageBox("错误:求余时除数为0!");
						isok=false;
						m_cal=false;
						return;
					}
					p->value=(int)p->left->value%(int)p->right->value;
					break;
				case 11:

⌨️ 快捷键说明

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