编译原理 字符串识别分析

 

  • 实验名称

字符串识别分析

  • 实验目的
  1. 掌握DFA构造
  2. 掌握利用DFA识别字符串
  • 实验内容和要求

根据已知DFA,识别分析字符串

  • 实验环境

VS 2022

  • 算法设计思想

  • 主要问题与解决方法

如何判断分析结束。当待分析字符串分析完毕,并且分析得到的最后一个非终结字符为某一终态,则判断得分析结束且成功,否则识别失败。

  • 实验结果

编译原理 字符串识别分析_第1张图片

编译原理 字符串识别分析_第2张图片

  • 体会、质疑、建议

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

  • 源代码
#include
#include
#include
#define N 100
using namespace std;
void creat();
void string_recognize();
    /************************************初始化,创建FA表和VN,VT集*********************************************/
struct {                 //定义结构体,结点内存放一个string字符串,方便处理
	string state;
}DFA[N][N];
//其实也可以这样定义string DFA[N][N];,用法会不同罢了
string VN;                   //存储非终结符
string VT;                   //存储终结符
int main()
{
	/************************************主函数部分************************************************************/
	int choice;
	creat();
	string_recognize();
	
	while (1) {
	/********************************设计简单的用户交互********************************************************/
		cout << "1.Try new string/2.Exit" << endl;
		cout << "Press:";
		cin >> choice;
		if (choice == 1)string_recognize();
		else return 0;
	}
}
void string_recognize()
{
	/************************************主要分析识别部分*****************************************************/
	string str;															//待分析字符串定义
	int  step = 1;														//step做步骤
	cout << "Please input the string ready to be recognized:" << endl;
	cin >> str;
	char vn=VN.front();													//取开始非终结字符赋给vn,vn为非终结符
	cout << left << setw(14) << "步骤" << setw(18) << "当前初态" << setw(20) << "剩余字符串" << "产生式" << endl;//分析过程标题
	while(!str.empty()){												//当str到空时结束分析
		cout << left << setw(14) << step << right << setw(8) << vn << setw(20) << str << setw(10) << " ";
		if (VT.find(str.front()) > VT.size()) {							//如果待分析字符出现不存在的字符,则报错并退出
			cout << str.front() << "无法识别" << endl;
			break;
		}
		cout << vn << "->" << str.front();								//输出产生式
		vn = DFA[VN.find(vn)][VT.find(str.front())].state.front();		//取到下一个非终结符态赋给vn,vn为下一个初态
		str.erase(str.begin());											//删除首字符
		cout << vn << endl;												//
		if (vn == 'Z')break;											//当vn到达规定终态‘Z’,则结束分析
		step++;															//步骤加一
	}
	if (str.empty() && vn == 'Z')cout << "Congratulation!!!   This string can be recognized successfully!" << endl;//如果待分析字符串空了并且终态为‘Z’则识别成功
	else  cout << "Sorry!!!   This string can not be recognized!" << endl;//否则识别失败


}
void creat()
{
	/************************************构造DFA部分*****************************************************/
	int sum;            //sum为FA文法个数
	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 != '#')DFA[VN.find(vn)][VT.find(vt)].state.push_back(z);//若z不为#号,往fa表中字符串存放入z
		else DFA[VN.find(vn)][VT.find(vt)].state.push_back('Z');       //若z为#号,则fa表中直接手动存入终态'Z'
	}
	/************************************DFA表输出**********************************************************/
	cout << "The DFA 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) << DFA[i][j].state;//依次输出FA表内每行状态集
		cout << endl;
	}
}

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

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