编译原理实验:正则表达式->NFA->DFA->最小化DFA图并生成词法分析程序

本文介绍了华南师范大学编译原理实验中的XLEX项目,详细阐述了如何从正则表达式生成NFA、DFA并进行最小化,以及如何用C++实现词法分析程序。实验涉及双栈法、NFA转DFA、DFA简化等技术,还展示了界面操作流程。
摘要由CSDN通过智能技术生成

编译原理实验:XLEX - 词法自动生成器

本实验为华南师范大学编译原理实验二
作者:关竣佑
编译环境 Qt 4.3.0
代码仓库:https://github.com/guanjunyou/LexicalAnalysisGenerator
实现将正则表达式–>NFA—>DFA–>DFA最小化–>词法分析程序

  1. 正则表达式 支持单个字符,运算符号有: 连接、选择(|)、闭包(*)、括号()、可选(? )、正闭包(+ )

  2. 用户输入一行(一个)或多行(多个)正则表达式(可保存、打开正则表达式文件)

  3. 用户可以查看转换得到的NFA(用状态转换表呈现)

  4. 用户可以查看转换得到的DFA(用状态转换表呈现)

  5. 用户可以查看转换得到的词法分析程序(该分析程序用C++语言描述)

输入正则表达式可换行,换行默认在两行间加 选择(|)

可保存正则表达式 (默认保存为 regex.txt 在 release 目录下)

可选择任意正则表达式文件 (TXT格式) 载入为正则表达式输入

核心思路:
  1. 读入正则表达式,使用双栈法生成 NFA 图。类似于算术表达式的计算,一个栈存储正则表达式的运算符,另一个栈存储图的结构。
    在这里插入图片描述 在这里插入图片描述
    另外,为了方便后续的操作,还要存储每个NFA结点针对 # 边的出度和入度(不是所有的出度和入读都计入!)

  2. NFA转DFA图: 对每个 # 入度为0的边开始 DFS ,知道遍历到边缘点,把所有遍历到的NFA点合成为一个DFA结点,因为经历了上面的合并操作后,会出现一个DFA点有两条相同字母的出边分别连向不同的DFA点的情况,然而这是不允许的(因为路径将是不确定的),所以接着要将两条相同字母边指向的 DFA点合并为一个DFA点。
    在这里插入图片描述
    在这里插入图片描述

  3. DFA图化简: 首先将DFA结点划分为 终态和非终态两个大的新DFA结点。放入队列中。对于每个正则表达式运算符,“过滤”一遍队列,队头弹出一个DFA点,针对该运算符求出分裂后的新的DFA点(如果对于这个运算符的边到达了不同的之前的DFA点则分裂为两个),将分裂后的DFA结点插入队尾。(可参考二叉树层序遍历的思路,逐层操作)

在这里插入图片描述
在这里插入图片描述

  1. 通过最简的DFA点生成C++代码

界面示意
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

编译原理实验二通常指的是一个实验项目,其中可能会包括将正则表达式转换为确定有限自动机(DFA)的过程。在C++中实现这个过程,通常需要几个步骤: 1. 从正则表达式构造非确定有限自动机(NFA):首先,需要一个算法或程序来将正则表达式转换为等价的NFA。这通常通过Thompson构造法来完成,它是一种递归算法,能够将正则表达式的基本操作(如并联、串联、选择和闭包)转换为NFA状态和转移。 2. 将NFA转换为DFA:在得到NFA之后,通过子集构造法(也称为幂集构造法)来将NFA转换为等价的DFA。这一转换的核心在于识别NFA中所有可能的状态集合,并构造出一个新的DFA,其状态对应于原NFA的所有可能状态的组合。 3. 最小化DFA:得到的DFA可能包含许多无法到达的或等效的状态。最小化DFA可以通过删除不可达状态和合并等效状态来完成,使DFA变得尽可能简洁。 在C++中,你可以使用标准库中的数据结构,如`std::vector`来存储状态,`std::set`或`std::unordered_set`来存储状态集合,以及映射类型如`std::map`来表示状态转移函数。以下是一个高度简化的例子框架: ```cpp #include <iostream> #include <vector> #include <set> #include <map> #include <string> #include <stack> // 假设的状态类型 using State = int; // 状态转移函数类型 using TransitionFunction = std::map<std::pair<State, char>, State>; // DFA类型 struct DFA { std::set<State> states; std::set<State> alphabet; State startState; State acceptState; TransitionFunction transitions; }; // 1. 构造NFA的函数... // 2. 将NFA转换为DFA的函数... // 3. 最小化DFA的函数... int main() { // 正则表达式转换为DFA的过程... return 0; } ``` 这个框架只是一个起点,具体的实现会涉及到复杂的逻辑和数据结构操作。通常,这会是编译原理课程中的一个深入项目,需要学生对自动机理论有深刻理解。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

June_gjy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值