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

📄 regularview.cpp

📁 编译原理---正则表达式到DFA的演示程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
      	   	for(p=1;p<=NodeGroup[curOut][0];p++)
      			{
					x +=intervalx;
					str.Format("%d,",NodeGroup[curOut][p]);
					pDC->TextOut(x,y,str);
            		//cout<<NodeGroup[curOut][p]<<",";
      			}

			    x+=intervalx;
				pDC->TextOut(x,y,"}",1);//		cout<<" }";
               for(p=distance*k+NodeGroup[curOut][0]*2+4;p<=distance*(k+1);p++)
			   {
				  x+=intervalx;
				  pDC->TextOut(x,y," ",1);  // cout<<" ";
			   }
            }

         }
      }
      //现在已经输出完一行
   }

}



void NFA_DFA()
{
   int i;


	ScanForAGroup(1);   //扫描得到第一个集。
   OpTempGroup( );   //对先保存在 TempGroup 中的集进行处理
    for(i=1;i<=curGroupNum;i++)  //注意:这里curGroupNum是动态的
   {                            //在for里面的操作中curGroupNum可能会增加。
  		SearchNewGroups(i);
   }

   //填充SecondTable
   FillSecondTable();

}


//返回一个集作为SecondTable状态点的状态:即是初始结点,中间结点,还是终止结点
int GetNodeState(int wishGroup)
{
   int i;
   int state=0;
   for(i=1;i<=NodeGroup[wishGroup][0];i++)
   {
   	if(NodeGroup[wishGroup][i]==FirstNodeQuantity)
      	return 1;
      if(NodeGroup[wishGroup][i]==1)
      	state=-1;
   }
   return state;
}


/////////////////////////
/*逐一填写SecondTable的每一行。
比如说:填第一行,即填写与NodeGroup中的第一个集的临接集,扫描GroupRelate[20][3]表
			中GroupRelate[i][0]=1 的关系,其对于的集就是必须填在第一行中的。
*/
void FillSecondTable()
{
   int i,j,flag;
   Node* pCurrent,* temp;

   //设置secondNodeQuantity 的值
	SecondNodeQuantity=curGroupNum;

   //初始化SecondTable
   for(i=1;i<=SecondNodeQuantity+1;i++)
   	SecondTable[i]=NULL;

   //在SecondTable[0]行中保存第一个状态的信息
   temp=new Node;
   temp->NeighborNode=1;
   temp->ConvertChar='@';
   temp->NodeState=GetNodeState(1);
   temp->Next=NULL;
   SecondTable[0]=temp;
  
   for(i=1;i<=SecondNodeQuantity;i++)
   {
      flag=0;
   	//SecondTable[i]=pCurrent;
   	for(j=1;j<=curRelateNum;j++)
      {
         if(GroupRelate[j][0]==i)
         {
         	flag++;
         	temp=new Node;
            temp->NeighborNode=GroupRelate[j][2];
            temp->ConvertChar=AllChar[(GroupRelate[j][1])];
            temp->NodeState=GetNodeState(temp->NeighborNode);
            temp->Next=NULL;

            if(flag==1)
             	SecondTable[i]=temp;
            else
            	pCurrent->Next=temp;

            pCurrent=temp;
         }
      }
   }

}

///////////////
//合并两个集的函数:
void CombineGroups()
{
	int i=1;
   int j=1;
   int Temp[30];
   int k=0;
   while(i>TempGroup[0][0]||j>TempGroup[1][0])
   {
   	if(TempGroup[0][i]<=TempGroup[1][j])
      {
         k++;
      	Temp[k]=TempGroup[0][i];
         if(TempGroup[0][i]==TempGroup[1][j])
         	j++;

         i++;
      }
      else
      {
         k++;
      	Temp[k]=TempGroup[1][j];
         j++;
      }
   }
  	while(i<=TempGroup[0][0])  // TempGroup[0] 中还有数的话,继续搬到 Temp 中
   {
      k++;
     	Temp[k]=TempGroup[0][i];
      i++;
   }
   while(j<=TempGroup[1][0])     // TempGroup[1] 中还有数的话,继续搬到 Temp 中
   {
    	k++;
     	Temp[k]=TempGroup[1][j];
      j++;
   }
   Temp[0]=k;
   for(i=0;i<=Temp[0];i++)           //将数据重新搬回到TempGroup【0】中
   	TempGroup[0][i]=Temp[i];

   TempGroup[curTempNum][0]=0;
   curTempNum=0;                     //置TempNum=0; 即合并后少了一集
};


//扫描程序开始:  这是通过e的
//扫描程序的作用是:从当前的状态结点开始(ScanStartNode),扫描通过一个或者
   //多个E可以到达的所有状态,将他们归为一个集
   //得到的临时集将放在 TempGroup中

void ScanForAGroup(int ScanStartNode)     //  应该可以在这里找出集的状态,但是这里生成的只是
{                                           //    临时的Group,是在这里吗???
   int i,temp;                              //    是不是用一个返回值来表征
   curTempNum++;
	TempGroup[curTempNum][0]=1;
   TempGroup[curTempNum][1]=ScanStartNode;

   Node* ScanCurrentNode;
	while(1)
   {
   	ScanCurrentNode=FirstTable[ScanStartNode];

      //出现问题:这里ScanCurrentNode=NULL
  		while(ScanCurrentNode!=NULL)     //扫描当前列,将为e的压入栈
   	{
   		if(ScanCurrentNode->ConvertChar=='@')
      	{
      		ObjStack.push(ScanCurrentNode->NeighborNode);
  //          cout<<"Stack push: "<<ObjStack.NodeStack[ObjStack.TopNode]<<endl;

      	}

      	ScanCurrentNode=ScanCurrentNode->Next;
   	}

      if(ObjStack.IsEmpty())   //如果是因为栈空而退出 while(!ObjStack.IsEmpty())
     		break;                //则也跳出 while(1)循环

   	while(!ObjStack.IsEmpty())
   	{
   		temp=ObjStack.pop();
   //      cout<<"Stack pop: "<<temp<<endl;

      	//注意:这里检查弹出的状态结点在之前是否已经有了,
      	// 			也就是说,是否出现了重复
       //	需要这样吗?
      	for(i=1;i<=TempGroup[curTempNum][0];i++)
      	{
         	if(temp==TempGroup[curTempNum][i])
       			break;
     		}

      	if(i>TempGroup[curTempNum][0])      //将状态号加入到TempGroup中
      	{
         	TempGroup[curTempNum][0]++;
         	i=TempGroup[curTempNum][0];
         	TempGroup[curTempNum][i]=temp;
    //        cout<<"Add "<<temp<<" in TempGroup"<<endl;

            ScanStartNode=temp;
         	break;    //跳出 while(!ObjStack.IsEmpty()) 循环
            			//它会进入while(1),也就是会重新扫描新的一行
      	}
   	}
   }

}

//注:栈的类型是否只要 int 就行了,而不用 Node×,或者是根本就不能用Node* ???

//扫描程序结束!


////////////////////
//一个集通过AllChar各元素获得新集:       这是通过char的
void SearchNewGroups(int curSourceGroup)  //curSouceGroup标志当前是对 NodeGroup
            											//这那一集进行操作
{
	int i,j,k;
   char curConvertChar;
   for(i=1;i<=CharQuantity;i++) //CharQuantity 林景灼给出的字符个数
   {
      curConvertChar=AllChar[i];
      k=SearchOneGroup(curSourceGroup,curConvertChar); //获取通过当前字符得到的新集
      if(k)
      {
      	j=OpTempGroup();

      	//在这里建立 集之间的关系!!!
      	curRelateNum++;
      	GroupRelate[curRelateNum][0]=curSourceGroup;
      	GroupRelate[curRelateNum][1]=i;
      	GroupRelate[curRelateNum][2]=j;
      }

   }
}

/////////////////////
//获取当前集通过当前字符得到的新集:

//现在是第一集通过'a'的扫描,结果是错误的多了一个10
int SearchOneGroup(int curSourceGroup,char curConvertChar)  // 这是通过char的
{
	int i,k,flag=0;
   Node* Temp;
   for(i=1;i<=NodeGroup[curSourceGroup][0];i++)
   {
      k=NodeGroup[curSourceGroup][i];  //取出当前集的第 i 个元素进行扫描
      											//则 k 为结点状态号
      Temp=FirstTable[k];
 
      if(Temp==NULL)
      	continue;           //这里曾经用了 return 0,导致错误
   	while(Temp!=NULL)
      {

      	if(Temp->ConvertChar==curConvertChar)
         {
           ScanForAGroup(Temp->NeighborNode); //扫描得到新组
           flag++;
         }

         if(curTempNum==1)
         {
           	CombineGroups(); //合并刚生成的两个集;
         }

         Temp=Temp->Next;
      }
   }
   return flag;
}

/////////////////////
/*处理一个临时集,为新集的话则加入到NodeGroup中:
重新定义返回值,返回临时集在NodeGroup中的位置 i。
	如果i<=curGroupNum,说明临时集不是新集,
   如果i>curGroupNum,说明其为新集。                 */
int OpTempGroup( )          //返回 1 时 ,表示临时集有效
{                                         //已经将其加入到NodeGroup中
   int i;
	SortAGroup();
   i=IsNewGroup( );               //否则,返回 0
   if(i==curGroupNum+1)
   {
     JointANewGroup( );
   }
   else
   	curTempNum=-1;

   return i;
}

///////////////////
//对一个集进行排序
void SortAGroup( )            //用冒泡排序
{
	int i,j,temp,flag;
   for(i=1;i<TempGroup[curTempNum][0];i++)
   {
   	flag=1;
      for(j=1;j<=TempGroup[curTempNum][0]-i;j++)
      {
      	if(TempGroup[curTempNum][j]>TempGroup[curTempNum][j+1])
         {
         	flag=0;
            temp=TempGroup[curTempNum][j];
            TempGroup[curTempNum][j]=TempGroup[curTempNum][j+1];
            TempGroup[curTempNum][j+1]=temp;
         }
      }
      if(flag)
      	break;
   }
}


/////////////////////
//定义返回值,返回临时集在NodeGroup中的位置 i。
//	如果i<=curGroupNum,说明临时集不是新集,
//   如果i>curGroupNum,说明其为新集。
int IsNewGroup( )
{
	int i,j;
   for(i=1;i<=curGroupNum;i++)      //只要有一集相同就可以退出,返回 0
   {
   	if(NodeGroup[i][0]==TempGroup[curTempNum][0])   //先判断元素个数是否相等,相等才处理
      {
      	for(j=1;j<=TempGroup[curTempNum][0];j++)
         {
         	if(NodeGroup[i][j]!=TempGroup[curTempNum][j])      //发现有不同元素,就跳出循环
            	break;
         }
         if(j>TempGroup[curTempNum][0])     //如果 if 成立的话,说明刚才
         	return i;                      //NodeGroup[i]与TempGroup[curTempNum]一样
      }
   }
   return curGroupNum+1;
}

/////////////////
//将一个临时集加入NodeGroup中
void JointANewGroup( )
{
   int i;
	curGroupNum++;
   for(i=0;i<=TempGroup[curTempNum][0];i++)
   	NodeGroup[curGroupNum][i]=TempGroup[curTempNum][i];

   TempGroup[curTempNum][0]=0;
   curTempNum=-1;

}



//////////////////////////////////
//栈的实现
TempStack::TempStack()
{
	MaxNum=20;
   TopNode=-1;
}

TempStack::~TempStack()
{
//Empty Now
}

int TempStack::push(int wishNode)
{
	if(TopNode==MaxNum-1)
   	return 0;

   TopNode++;
   NodeStack[TopNode]=wishNode;
   return 1;
}

int TempStack::pop( )
{
    if(TopNode==-1)
    	return 0;

    int temp;
    temp=NodeStack[TopNode];
    TopNode--;
    return temp;
}

int TempStack::IsEmpty()
{
	if(TopNode==-1)
   	return 1;

   return 0;
}


//从NFA到DFA完*******************************************************************


/////////////////////////////////////////////////////////////////////////////
// CRegularView

IMPLEMENT_DYNCREATE(CRegularView, CView)

BEGIN_MESSAGE_MAP(CRegularView, CView)
	//{{AFX_MSG_MAP(CRegularView)
	ON_COMMAND(ID_DRAW, OnDrawNFA)
	ON_COMMAND(ID_INPUT_EXPRESSION, OnInputExpression)
	ON_COMMAND(ID_DRAW_DFA, OnDrawDfa)
	ON_COMMAND(ID_DRAW_TABLE, OnDrawTable)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRegularView construction/destruction

CRegularView::CRegularView()
{

}

CRegularView::~CRegularView()
{
}

⌨️ 快捷键说明

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