编译原理 与正规文法等价的FA的生成程序

 

  • 实验名称

与正规文法等价的FA的生成程序  

  • 实验目的

1.掌握根据正规文法转化为FA的原理;

2.实现FA的生成程序。

  • 实验内容和要求
  1. 输入正规文法,并构造其等价的有穷自动机(FA)。
  2. 对构造出的FA进行判断——是不确定的有穷自动机(NFA)还是确定的有穷自动机(DFA)。
  • 实验环境

VS 2022

  • 算法设计思想

构造一个fa[][]结构体表,结点内放置一个string类字符串,供存储后继态。接收终结符和非终结符集,都用string接收,fa表行对应一个非终结符,列对应一个终结符,

由于正规文法必定由三个或两个字符输入组成(无后继的文法用#号填充),则用三个char类型字符接收,然后做分析,利用第一个非终结符找到行,利用第二个终结符找到列,然后将第三个字符存入fa表对应的行列中,如果第三个字符为#号,则手动存入Z字符。判断NFA或DFA,在分析存状态的同时,查看string.size()字符长度,如果超过1,则存在多个后继态,判断出FA为NFA。

  • 主要问题与解决方法
  1. 如何在最后判断FA为NFA或DFA。利用一个标记judge,如算法思想中说的,如果查找过程中,发现当前存的字符串大小超过1,则存在多个后继态,即为NFA,此时judge置为1,默认为0,待fa表全输出后,做一个判断if(judge),然后输出NFA或DFA。
  2. #号如何处理。判断,若第三个字符为#号时,则往该结点字符串存入‘Z’字符。‘Z’表示终态。
  • 实验结果

编译原理 与正规文法等价的FA的生成程序_第1张图片

编译原理 与正规文法等价的FA的生成程序_第2张图片

  • 体会、质疑、建议

代码中的奥妙,其乐无穷!!!

  • 源代码
#include
#include
#include
#define N 100
using namespace std;
void creat();
int main()
{	/************************************主函数实现部分,通过while实现即时多次使用程序**************************/
	creat();
	while (1) {
	/***********************************简单的用户交互设计******************************************************/
		int choice;
		cout << "1.Try new FA./2.Exit" << endl;
		cout<< "Press:";
		cin >> choice;
		if (choice == 1)creat();
		else return 0;
	}
}
void creat()
{   /************************************初始化,创建FA表和VN,VT集*********************************************/
	struct {                 //定义结构体,结点内存放一个string字符串,方便处理
		string state;
	}fa[N][N];                       
	string VN;                   //存储非终结符
	string VT;                   //存储终结符
	int sum, judge=0;            //sum为FA文法个数,judge用来判断DFA或NFA
	char vn, vt, z;              //用三个char字符来接受每一条文法
	/************************************开始读取VN,VT,sum***************************************************/
	cout << "Please input the VN word:" << endl;
	cin >> VN;
	cout << "Please input the VT word:" << endl;
	cin >> VT;
	cout << "Please input the amount of the FA rules:" << endl;
	cin >> sum;
	cout << "Please input the FA rule:" << endl;
	/************************************开始读取文法,同时做处理**********************************************/
	for (int s = 0;s < sum;s++) {
		cin >> vn >> vt >> z;
		if (z != '#')fa[VN.find(vn)][VT.find(vt)].state.push_back(z);//若z不为#号,往fa表中字符串存放入z
		else fa[VN.find(vn)][VT.find(vt)].state.push_back('Z');       //若z为#号,则fa表中直接手动存入终态'Z'
		if (fa[VN.find(vn)][VT.find(vt)].state.size() >1)judge = 1;    //若字符串长度.size()不小于2,则表示,该状态集存在两个以上终态,因此judge置为1
	}
	/************************************FA文法表输出**********************************************************/
	cout << "The FA table is as followed:" << endl << " ";
	for (auto i : VT)cout << right << setw(5) << i;//先将第一行终结符按格式输出
	cout << endl;         
	for (int i = 0;i < VN.size();i++) {                   //逐行输出FA表
		cout << VN.at(i);                                    //输出每行首位非终结符
		for (int j = 0;j < VT.size();j++)cout << right << setw(5) << fa[i][j].state;//依次输出FA表内每行状态集
		cout << endl;
	}
	/************************************FA文法表判断**********************************************************/
	if (judge)cout << "The FA is NFA." << endl;
	else cout << "The FA is DFA." << endl;
}

/*案例数据1       NFA
SAB
ab
8
SaA
SbB
Sa#
AaB
AbA
BaS
BbA
Bb#

案例数据2         DFA
SAB
ab
6
SaA
SbB
AaA
AbB
BbA
Ba#
*/

你可能感兴趣的:(c++,算法,开发语言)