正规式转换到非确定有穷自动机转换的一般算法

要求

  • 用C++ 实现;
  • input.txt描述正规式,需要编程加以解析,该文件规定的格式为:第一行写处正规式的符号集,规定符号集为0-9共10个数字符,第二行写正规式,如:
    • 0123456789
    • (0|1)*0.10* (注:*表示闭包运算,.表示连接该符号可省略)
  • output.txt为描述非确定有穷自动机的文件,有程序生成,生成时需按如下格式:
    • 第一行写出状态集,用大写字母A-Z表示,如:ABCD
    • 第二行描述自动机的符号集为0-9共10个数字符,如:0123456789
    • 第三行写初态集,如:A
    • 第四行写终态集,如:CD
    • 第五行写出转移函数,如(A,0,B)表示A状态的出边0到达B状态。上例正规式可表为(A,0,A)(A,1,A)(A,0,B)(B,1,C)(C,0,D)(D,0,D)。

思路

使用Thompson构造法,输入为字母表Σ上的正规式,输出为相等的NFA。具体方法为:

首先将构成r的各个元素分解,对于每一个元素,按下述规则1和规则2生成NFA。(注意:如果r中记号a出现了多次,那么对于a的每次出现都需要生成一个单独的NFA。)之后依照正规表达式r的文法规则,将生成的NFA按照下述规则3组合在一起。

  • 规则1 对于空记号ε,生成下面的NFA。
    在这里插入图片描述
  • 规则2 对于Σ的字母表中的元素a,生成下面的NFA。
    在这里插入图片描述
  • 规则3 令正规表达式R和S的NFA分别为N(R)和N(S)。
  • 对于R|S,按照以下的方式生成NFA N(R|S)。
    在这里插入图片描述
  • 对于RS,按照以下的方式生成NFA N(RS)。
    在这里插入图片描述
  • 对于R*,按照以下的方式生成NFA N(R*)。
    在这里插入图片描述

流程图

  • 总体流程图
    在这里插入图片描述
  • 在正规式中加入省略的连接符
    在这里插入图片描述
  • 将式子转为后缀表达式
    在这里插入图片描述
  • 将后缀表达式转换成NFA
    在这里插入图片描述

数据结构

struct edge
{
	char weight;
	char next;
};

string option,expression, suffix, infix, postion;
map<char, int> precedence;
map<char, vector<edge>> nfa;
vector<string> tfunction;
// 具体解释如下:
// edge:NFA图中的边;
// option:输入的符号集;
// expression:输入的正规式;
// infix:增加连接符的正规式;
// suffix:转换成的后缀表达式;
// postion:状态集;
// precedence:规定运算符优先级;
// nfa:生成的NFA(使用map生成了一个char与edge向量的映射,char代表NFA中的顶点,也就是生成了一个顶点与从顶点出发边的集合的映射);
// tfunction:转移函数。

代码详见 Github上,欢迎star!

发布了5 篇原创文章 · 获赞 1 · 访问量 283

猜你喜欢

转载自blog.csdn.net/weixin_44318192/article/details/102873906