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

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;
				 }
			 }
		 }
	 }
 }

四、完整代码

下载链接


感谢阅读!

如有错误,恳请指正!

  • 16
    点赞
  • 132
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
LR语法分析器编译原理中的一种语法分析方法,它可以根据给定的文法规则,对输入的程序代码进行分析和解析。LR语法分析器使用自底向上的分析方法,通过构建一个状态机来识别输入的符号串是否符合给定的文法规则。 LR语法分析器实现通常使用工具,如Bison(Yacc的GNU版本),它可以根据给定的文法规则自动生成相应的语法分析器LR语法分析器的工作原理如下: 1. 构建LR分析表:根据给定的文法规则,LR语法分析器会构建一个分析表,该表记录了在不同状态下,对应不同输入符号的移进、规约或接受操作。 2. 状态转移:LR语法分析器通过状态转移来处理输入符号串。它从初始状态开始,根据当前状态和下一个输入符号,查找分析表中对应的操作,并执行相应的移进或规约操作。 3. 移进操作:当遇到终结符号时,LR语法分析器会将该符号移入栈中,并读取下一个输入符号。 4. 规约操作:当遇到非终结符号时,LR语法分析器会根据文法规则进行规约操作,将栈中的符号按照规约规则进行替换。 5. 接受操作:当输入符号串被完全分析并符合文法规则时,LR语法分析器会执行接受操作,表示输入符号串被成功地分析和解析。 通过使用LR语法分析器,可以对程序代码进行语法分析,并生成相应的抽象语法树(AST)。抽象语法树可以用于后续的语义分析和代码生成等编译过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

电影中的梦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值