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

📄 regularview.cpp

📁 编译原理---正则表达式到DFA的演示程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:

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

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CRegularView drawing

void CRegularView::OnDraw(CDC* pDC)
{
	CRegularDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// CRegularView diagnostics

#ifdef _DEBUG
void CRegularView::AssertValid() const
{
	CView::AssertValid();
}

void CRegularView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

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

/////////////////////////////////////////////////////////////////////////////
// CRegularView message handlers


//之前 ,nNodeNum 必须 =FirstNodeQuantity
void CRegularView::InitNodeArray()
{
//	NodeInfArray=new NodeInfor[nNodeNum+1];

	for(int i=0;i<nNodeNum;i++)
	{
		NodeInfArray[i].bDrawNode=1;  //初始化时全为1,表示全部要画
		NodeInfArray[i].xPos=-1;     //-1表示未定义
		NodeInfArray[i].yPos=-1;     //-1表示未定义
	}
	NodeInfArray[0].bDrawNode=0;


	bChangeLine=0;  //起初时不需换行,因为一条路径还没到
	nCountLine=0;   //累加行数
//	nEndNodeNum=1;  //记录结束结点的号,以备后面如果当前结点跟结束结点在同一条垂线上时当前结点x值要编移



/*	Node0=new Node;
	Node1=new Node;
	Node2=new Node;
	Node3=new Node;
	Node4=new Node;
	Node5=new Node;
	Node6=new Node;
	Node7=new Node;
	Node8=new Node;
	Node9=new Node;
	Node10=new Node;
	Node11=new Node;
	Node12=new Node;
	Node13=new Node;
	Node14=new Node;
*/

	//NodeTable[0]  保存结点1的状态
/*	NodeTable[0]=Node0;
	Node0->NeighborNode=1;      //指向开始结点1
	Node0->ConvertChar=' ';     
	Node0->NodeState=1;        //若为1,表示该结点为开始状态.
	Node0->Next=NULL;
*/
	//NodeTable[1]
/*	NodeTable[1]=Node1;
	Node1->NeighborNode=2;      //原为2
	Node1->ConvertChar='1';     //原为1
	Node1->NodeState=0;
	Node1->Next=Node2;

	Node2->NeighborNode=4;
	Node2->ConvertChar='E';
	Node2->NodeState=0;
	Node2->Next=Node3;
	
	Node3->NeighborNode=10;
	Node3->ConvertChar='E';
	Node3->NodeState=0;
	Node3->Next=NULL;

	//NodeTable[2]
	NodeTable[2]=Node4;
	Node4->NeighborNode=3;
	Node4->ConvertChar='0';
	Node4->NodeState=1;
	Node4->Next=NULL;

	//NodeTable[3]
	NodeTable[3]=NULL;

	//NodeTable[4]
	NodeTable[4]=Node5;
	Node5->NeighborNode=8;
	Node5->ConvertChar='E';
	Node5->NodeState=0;
	Node5->Next=Node6;

	Node6->NeighborNode=7;
	Node6->ConvertChar='1';
	Node6->NodeState=0;
	Node6->Next=Node7;

	Node7->NeighborNode=5;
	Node7->ConvertChar='0';
	Node7->NodeState=0;
	Node7->Next=NULL;

	//NodeTable[5]
	NodeTable[5]=Node8;
	Node8->NeighborNode=6;         
	Node8->ConvertChar='1';
	Node8->NodeState=0;
	Node8->Next=NULL;

	//NodeTable[6]
	NodeTable[6]=Node9;
	Node9->NeighborNode=4;
	Node9->ConvertChar='E';
	Node9->NodeState=0;
	Node9->Next=NULL;

	//NodeTable[7]
	NodeTable[7]=Node10;
	Node10->NeighborNode=6;
	Node10->ConvertChar='E';
	Node10->NodeState=0;
	Node10->Next=NULL;

	//NodeTable[8]
	NodeTable[8]=Node11;
	Node11->NeighborNode=9;
	Node11->ConvertChar='0';
	Node11->NodeState=0;
	Node11->Next=NULL;

	//NodeTable[9]
	NodeTable[9]=Node12;
	Node12->NeighborNode=3;
	Node12->ConvertChar='E';
	Node12->NodeState=1;
	Node12->Next=NULL;

	//NodeTable[10]
	NodeTable[10]=Node13;
	Node13->NeighborNode=11;
	Node13->ConvertChar='E';
	Node13->NodeState=0;
	Node13->Next=NULL;

	//NodeTable[11]
	NodeTable[11]=Node14;
	Node14->NeighborNode=3;
	Node14->ConvertChar='E';
	Node14->NodeState=1;
	Node14->Next=NULL;
*/
  }

void CRegularView::OnDrawNFA() 
{	
	
	FirstNodeQuantity=0;   //结点数量
	for(int i=0;i<20;i++)
	   AllChar[i]=0;   //接收到哪些字符 
	CharQuantity=0;   //接收字符个数,e除外 */
	linepos=0;

	//首先调用转换正则到NFA全局函数
	for(i=0;i<100;i++)
	{
		FirstTable[i]=0;
	}

	RegularToNFA();

	//设置nNodeNum大小
	nNodeNum=FirstNodeQuantity;  //只是初始化NodeInforArray[]

	NodeTable=FirstTable;

	int nStartx=30;
	int nStarty=30;
	NodeInfArray=new NodeInfor[nNodeNum+1];
	InitNodeArray();   //一系列初始化,初始化NodeInforArray[],NodeTable[]等

	Clear();
	//画NFA图
	DrawNFA(nStartx,nStarty,NodeTable[0],0);

	delete []NodeInfArray;


	CMenu *pMenu=AfxGetApp()->m_pMainWnd->GetMenu();
    ASSERT_VALID(pMenu);
    pMenu->EnableMenuItem(ID_DRAW,MF_ENABLED);
    pMenu->EnableMenuItem(ID_DRAW_DFA,MF_ENABLED);
    pMenu->EnableMenuItem(ID_DRAW_TABLE,!MF_ENABLED);
}

void CRegularView::DrawNFA(int x,int y,Node* pNode,int nLastNode)
{
	while(pNode)            //循环,直到每一邻接表的每一行的下一个结点为NULL
	{
		if(bChangeLine)
		{
			nCountLine +=nIntervaly;
			y=nCountLine;
			bChangeLine=0;  //复换行位为0.
		}
		
		if(NodeInfArray[pNode->NeighborNode].bDrawNode ==1 )  //1要画
		{
			if(pNode->NodeState==1)
				DrawCircle(x,y,32767,38,38);   //,结束状态,画外圈
		
			DrawCircle(x,y,pNode->NeighborNode,nRadusx,nRadusy);  //结点未画出,现在要画
			NodeInfArray[pNode->NeighborNode].xPos=x;             //记录已画结点坐标
			NodeInfArray[pNode->NeighborNode].yPos=y;             //记录已画结点坐标
			NodeInfArray[pNode->NeighborNode].bDrawNode = 0;     //结点已画出,bDrawNode[]设为0,表示以后不需画
		}
			//把上一个结点和当前结点连线
		if(nLastNode !=0)  //0结点不用画出
		{
		if(nLastNode !=pNode->NeighborNode)    //非自循环
			DrawLine(NodeInfArray[nLastNode].xPos+15, NodeInfArray[nLastNode].yPos,
				     x-16,y,
					 pNode->ConvertChar);
		else {
			DrawArc(x,y-20,x+40,y-20,x+40,y+20,x,y+20,pNode->ConvertChar);  //结点自循环,画弧
			pNode=pNode->Next;
			continue;
			}
		}

		Node* tem=NodeTable[pNode->NeighborNode];  //下个结点
		if(tem !=NULL)
		{
			if(NodeInfArray[tem->NeighborNode].bDrawNode ==1)  //如果下个结点已画,则不要再递归,否则进入回路,死循环
				DrawNFA(x+nIntervalx,y,NodeTable[pNode->NeighborNode],pNode->NeighborNode);  //pNode->NeighborNode是当前所画的结点

			//当前结点跟下个结点有连线,从当前结点向下个结点画线
			else 
			{
					if(tem->NeighborNode !=pNode->NeighborNode) //非自循环
						DrawLine(x+15,y,
						  NodeInfArray[tem->NeighborNode].xPos, 
						  NodeInfArray[tem->NeighborNode].yPos,
						  pNode->ConvertChar);
					else  DrawArc(x,y-20,x+40,y-20,x+40,y+20,x,y+20,pNode->ConvertChar);  //结点自循环,画弧

				bChangeLine =1;  //存在回路,需换行
			} //else
		} //tem !=NULL 下个结点不能为NULL.
			//		if(bDrawNode[pNode->NeighborNode])
			pNode=pNode->Next;
	}
   bChangeLine =1;  //pNode为NULL,说明到路径尽头,记为一条路径
}

void CRegularView::DrawCircle(int x,int y,int status,int deltax,int deltay )
{
//	Sleep(500);
	CClientDC dc(this);

	dc.Ellipse(x-deltax/2,y-deltay/2,x+deltax/2,y+deltay/2);
	if(status==32767)
		return;
	char buf[10]={0,};
	sprintf(buf,"%d ",status);
	dc.TextOut(x-5/*+10*/,y-8/*+5*/,buf,2);
}

//从(x1,y1)向(x2,y2)画线
void CRegularView::DrawLine(int x1, int y1, int x2, int y2, char ch)
{
	CClientDC dc(this);
	dc.SelectStockObject(NULL_BRUSH);
	CPen pen(PS_SOLID,1,RGB(255,0,0));
	dc.SelectObject(&pen);
	dc.MoveTo(x1,y1);        //在2分一长打印转换符号
	dc.LineTo(x2,y2);
	dc.TextOut((x1+x2)/2,(y1+y2)/2,&ch,1);  //在2分一处可保证转换符在连线上

	//画箭头
	int xa,xb,ya,yb;
	int delta_x=x1<x2 ? -6 : 6;  //6为箭头长度
	int delta_y=y1<y2 ? -6 : 6;  //6为箭头长度

	//定义三角形箭头A(xa,ya) B(xb,yb) C(x2,y2)
	if((y1 !=y2) && (x1 !=x2))
	{	ya=y2;
	    yb=y2+delta_y;
		xb=x2;          //B(xb,yb)
        xa=x2+delta_x; //A(xa,ya)
	}
	
	else if(y1==y2)                //y1==y2 ,箭头是水平情况
	{  ya=y2-delta_y+2;			   //2为微调参数,箭头角度大小
	   yb=y2+delta_y-2;
	   xa=xb=x2+delta_x;
   }

	else if(x1 ==x2)    //x1==x2, 箭头是垂直情况
	{  xb=x2+delta_x-2;   //B(xb,yb)
       xa=x2+delta_x+2;   //A(xa,ya)
	   ya=yb=y2+delta_y;
	   }

	//yb=y2+delta_ya;
//	CPen pen2(PS_SOLID,1,RGB(255,0,0));
//	dc.SelectObject(&pen2);

	dc.MoveTo(xa,ya);
	dc.LineTo(x2,y2);

	dc.MoveTo(xb,yb);
	dc.LineTo(x2,y2);
	
}

void CRegularView::DrawArc(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4,char ch)
{
	CClientDC dc(this);
	CPen pen(PS_SOLID,1,RGB(255,0,0));
	dc.SelectObject(&pen);
	dc.SelectStockObject(NULL_BRUSH);
	dc.Arc(x1,y1,x2,y2,x3,y3,x4,y4);
	dc.TextOut(x1+20,y1,&ch,1);
}

void CRegularView::OnInputExpression() 
{
Input in;
	if(in.DoModal()==IDOK)
	{
		string=new char[in.GetLength()+2];
		in.GetBufferData(string);
		string[in.GetLength()]='#';
		string[in.GetLength()+1]='\0';
	
	CMenu *pMenu=AfxGetApp()->m_pMainWnd->GetMenu();
    ASSERT_VALID(pMenu);
    pMenu->EnableMenuItem(ID_DRAW,MF_ENABLED);
    pMenu->EnableMenuItem(ID_DRAW_DFA,!MF_ENABLED);
    pMenu->EnableMenuItem(ID_DRAW_TABLE,!MF_ENABLED);
	}

}

void CRegularView::OnDrawDfa() 
{
	//首先调用转换正则到NFA全局函数
	for(int i=0;i<100;i++)
	{
		SecondTable[i]=0;
	}

	/* 从NFA到DFA的接口:(这些接口变量由正则到NFA的RegularToNFA()提供)
	 * Node* FirstTable[100];   
     * int FirstNodeQuantity;
     * char AllChar[20];   //接收到哪些字符
	 * int CharQuantity;   //接收字符个数,e除外
	 */
	NFA_DFA();

	//设置nNodeNum大小
	nNodeNum=SecondNodeQuantity;  //只是初始化NodeInforArray[]

	NodeTable=SecondTable;

	int nStartx=30;
	int nStarty=30;
	NodeInfArray=new NodeInfor[nNodeNum+1];
	InitNodeArray();   //一系列初始化,初始化NodeInforArray[],NodeTable[]等

	
	Clear();

	//画NFA图
	DrawNFA(nStartx,nStarty,NodeTable[0],0);

	delete []NodeInfArray;

	CMenu *pMenu=AfxGetApp()->m_pMainWnd->GetMenu();
    ASSERT_VALID(pMenu);
    pMenu->EnableMenuItem(ID_DRAW,MF_ENABLED);
    pMenu->EnableMenuItem(ID_DRAW_DFA,MF_ENABLED);
    pMenu->EnableMenuItem(ID_DRAW_TABLE,MF_ENABLED);

}

void CRegularView::OnDrawTable() 
{	
	Clear();
	CClientDC dc(this);
	PrintConvertTable(&dc);
	// TODO: Add your command handler code here
	
}

void CRegularView::Clear()
{
	CClientDC dc(this);
	CRect rec;
	GetClientRect(&rec);
	CBrush brush(RGB(255,255,255));
	dc.FillRect(&rec,&brush);
}






⌨️ 快捷键说明

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