给定正规式转化为等价的NFA代码实现

词法分析程序题

题目

给定正规式,转化为等价的NFA

算法

结构体介绍

state结构体

struct state//定义状态结构体

{

         string input;//输入符号集合

         vector<state*> *next;//输出状态集合,与输入符号集合一一对应

};

input[i]和(*next)[i]一一对应,若next.size()为0则表示到了终点

unit结构体

struct unit//正规文法单元,记录当前单元的开始状态地址和结束状态地址,最后不断壮大的单元即为所需的NFA

{

         char id;//0表示最小单元,()|*表示辅助字母,1表示曾通过()将状态绑定在一起以便更好区分(ab)*和ab*的处理

         state *begin;//开始状态地址

         state *end;//结束状态地址

};

该结构体采用正规文法的思想,使用正规文法到正规式转化的逆思想,将正规式不断单元化,最后再合并。

算法介绍

遍历正规式,对正规式每一个输入进行相应处理。

输入’(‘:构造unit单元,id设为’(‘,起始状态和终止状态都为NULL,压入unit栈

输入’|’: 构造unit单元,id设为’|‘,起始状态和终止状态都为NULL,压入unit栈

输入’)’:判断’()’内是否含有’|’,若有,则分’|’右边和左边,右边按出栈顺序依次联结成一个unit单元,左边也按出栈顺序依次联结成一个unit单元,然后构造空串,如下图

图1



若无’|’,则直接按出栈顺序依次联结’()’内单元

输入’*’:判断栈顶单元标识,若id==’1’,表示该单元内内容通过’()’进行过绑定,直接通过添加空串状态指向begin状态和begin状态指向空串,再次联结成一个新单元

若id==’0’,表示该单元内内容未通过’()’进行过绑定,直接通过添加空串状态指向end状态和end状态指向空串

输入其他字符:默认为输入字符,判断该字符是否为首字符或右边为’(‘或’|’,若是则创建新状态并构建新单元压入栈,否则创建新状态联结进栈顶单元

输入完毕:联结栈内所有单元,输出该单元

源程序

#include
    
    
     
     
#include
     
     
      
      
#include"d_stack.h"//栈类头文件
#include
      
      
       
       
using namespace std;
struct state//定义状态结构体
{
	string input;//输入符号集合
	vector
       
       
        
         *next;//输出状态集合,与输入符号集合一一对应
};
struct unit//正规文法单元,记录当前单元的开始状态地址和结束状态地址,最后不断壮大的单元即为所需的NFA
{
	char id;//0表示最小单元,()|*表示辅助字母,1表示曾通过()将状态绑定在一起以便更好区分(ab)*和ab*的处理
	state* begin;//开始状态地址
	state* end;//结束状态地址
};
class NFA
{
public:
	unit* REtoNFA(string RE)//regular expression to NFA
	{
		miniStack
        
        
          *s=new miniStack 
         
           (); for(int i=0;i 
          
            id='(';//标识为'(',压入栈 u1->begin=NULL; u1->end=NULL; s->push(u1); break; } case')': { unit* u1; unit* u2; unit* u3; u1=NULL; u3=NULL; bool exist=false; while(s->top()->id!='(')//联结'|"右边的单元 { if(s->top()->id=='0'&&u1==NULL||s->top()->id=='1'&&u1==NULL)//当u1未初始化时 { u1=s->top(); s->pop(); } else if(s->top()->id!='|')//未遇到'|'前联结所有单元 { unit* tempu1=s->top(); tempu1->end->n
  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值