编译原理LR(1)语法分析器 C++实现

2023-11-02

LR(1)语法分析器

C++语言编写,已通过VS2019调试


一、测试结果

部分测试结果截图
部分测试截图


二、测试文件

在D盘下建立test.txttoken.txt两个文件(文件路径可自行修改)

test.txt内容,第一行为终结符集
=*i
S->L=R
S->R
L->*R
L->i
R->L
token.txt内容,为分析字符串
*i=i

三、核心代码

void LR1_Analyse() {
	 CSS_LR1 p;
	 //初始项目 S’->.S ,# 
	 p.start = css[0].start + "'";
	 p.num = 0;//点在最前面 
	 p.tail.push_back("#");
	 p.next.push_back(css[0].start);

	 I[0] = CLOSURE(p);//求闭包后的I[0]
	 I[0].insert(I[0].begin(), p);
	 I_count = 1;

	 //计算项目集 
	 for (int i = 0; i < I_count; i++) {//每个项目集  项目集I(i) 

		 cout << "===================" << endl;
		 cout << "现在在计算项目集I" << i << endl;
		 showI(I[i]);//展示项目集 
		 cout << "===================" << endl;

		 //---------求ACTION的r部分-------------- 
		 vector<CSS_LR1>::iterator t;
		 for (t = I[i].begin(); t != I[i].end(); t++) {
			 CSS_LR1 t2 = *t;
			 if (t2.num == t2.next.size()) {
				 int num = 0;
				 for (int xp = 0; xp < CSSCount; xp++) {
					 if (css[xp].start == t2.start && css[xp].next == t2.next) {
						 num = xp;
						 break;
					 }
				 }
				 std::stringstream ss;
				 ss << num;
				 string s = ss.str();
				 for (int q = 0; q < t2.tail.size(); q++) {
					 ACTION[i][t2.tail[q]] = "r" + s;

				 }
				 if (t2.num == 1 && t2.next[0] == css[0].start) {
					 ACTION[i]["#"] = "acc";

				 }

			 }

		 }
		 //-------------------------------------- 



		 set<string>::iterator it;
		 for (it = VN.begin(); it != VN.end(); it++) {  //每个非终结符
			 vector<CSS_LR1> temp;
			 for (int j = 0; j < I[i].size(); j++) {
				 CSS_LR1 lr = I[i][j];
				 if (lr.num < lr.next.size() && lr.next[lr.num] == *it) {
					 //cout<<*it<<endl; 
					 vector<CSS_LR1> t2;
					 lr.num++;
					 t2 = CLOSURE(lr);
					 t2.push_back(lr);
					 temp = temp + t2;

				 }

			 }
			 //cout<<"temp.size"<< temp.size()<<endl;

			 if (temp.size() > 0) {
				 int k;
				 for (k = 0; k < I_count; k++) {//找一找项目集是否已经存在 
					 if (cmp_vector(I[k], temp)) {
						 break;

					 }

				 }
				 if (k == I_count) {
					 //产生了新的项目集 
					 I[I_count] = temp;
					 cout << "  I" << i << " -- " << *it << "->" << "I" << I_count << endl << endl;
					 GOTO[i][*it] = I_count;//更新goto表 
					 I_count++;

				 }
				 else {
					 //项目集已经存在,需要自己指向自己
					 cout << "  I" << i << " -- " << *it << "->" << "I" << k << endl << endl;
					 GOTO[i][*it] = k;


				 }


			 }


		 }
		 for (it = VT.begin(); it != VT.end(); it++) {  //每个终结符
				 //cout<<"项目集I"<<i<<"输入"<<*it<<endl; 
			 vector<CSS_LR1> temp;

			 for (int j = 0; j < I[i].size(); j++) {
				 CSS_LR1 lr = I[i][j];

				 if (lr.num < lr.next.size() && lr.next[lr.num] == *it) {
					 vector<CSS_LR1> t2;
					 lr.num++;
					 t2 = CLOSURE(lr);//闭包求出的结果不包含本身 
					 t2.insert(t2.begin(), lr);/求闭包遇到了一些问题 
					 //showI(t2);
					 temp = temp + t2;

				 }

			 }
			 //cout<<"temp.size"<< temp.size()<<endl;
			 if (temp.size() > 0) {
				 int k;
				 for (k = 0; k < I_count; k++) {//找一找项目集是否已经存在 
					 if (cmp_vector(I[k], temp)) {
						 break;

					 }

				 }
				 if (k == I_count) {
					 //产生了新的项目集 
					 I[I_count] = temp;
					 cout << "  I" << i << " -- " << *it << "->" << "I" << I_count << endl << endl;
					 std::stringstream ss;
					 ss << I_count;
					 string s = ss.str();
					 ACTION[i][*it] = "S" + s;//更新AVTION表 
					 I_count++;

				 }
				 else {
					 //项目集已经存在,需要自己指向自己
					 cout << "  I" << i << " -- " << *it << "->" << "I" << k << endl << endl;
					 std::stringstream ss;
					 ss << k;
					 string s = ss.str();
					 ACTION[i][*it] = "S" + s;
				 }
			 }
		 }
	 }
 }

四、完整代码

下载链接


感谢阅读!

如有错误,恳请指正!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编译原理LR(1)语法分析器 C++实现 的相关文章

随机推荐