基于SLR文法,将输入串翻译成三地址代码序列

要求:

输入:(b+c*d+c*d

输出:

t1= c*d

t2=b+t1

t3= c*d

t4=t2+t3

本次的题目和之前的功能很类似,都是基于SLR文法的,所有代码与之前有很多共同之处。

#include <iostream>
#include <string.h>
#include<stack>
using namespace std;
/*
E->E+T
E->T
T->T*F
T->F
F->(E)
F->id
*/
/*初始化分析表*/
void Initial(string analysis[12][9]){
	/*移进规约*/
	analysis[0][0] = "s5"; analysis[0][3] = "s4"; analysis[0][6] = "1"; analysis[0][7] = "2"; analysis[0][8] = "3";
	analysis[1][1] = "s6"; analysis[1][5] = "acc";
	analysis[2][1] = "r2"; analysis[2][2] = "s7"; analysis[2][4] = "r2"; analysis[2][5] = "r2";
	analysis[3][1] = "r4"; analysis[3][2] = "r4"; analysis[3][4] = "r4"; analysis[3][5] = "r4";
	analysis[4][0] = "s5"; analysis[4][3] = "s4"; analysis[4][6] = "8"; analysis[4][7] = "2"; analysis[4][8] = "3";
	analysis[5][1] = "r6"; analysis[5][2] = "r6"; analysis[5][4] = "r6"; analysis[5][5] = "r6";
	analysis[6][0] = "s5"; analysis[6][3] = "s4"; analysis[6][7] = "9"; analysis[6][8] = "3";
	analysis[7][0] = "s5"; analysis[7][3] = "s4"; analysis[7][8] = "10";
	analysis[8][1] = "s6"; analysis[8][4] = "ss";//s11
	analysis[9][1] = "r1"; analysis[9][2] = "s7"; analysis[9][4] = "r1"; analysis[9][5] = "r1";
	analysis[10][1] = "r3"; analysis[10][2] = "r3"; analysis[10][4] = "r3"; analysis[10][5] = "r3";
	analysis[11][1] = "r5"; analysis[11][2] = "r5"; analysis[11][4] = "r5"; analysis[11][5] = "r5";
	/*出现错误*/
	analysis[0][1] = analysis[0][2] = analysis[0][5] = analysis[4][1] = analysis[4][2] = analysis[4][5] = "e1";
	analysis[6][1] = analysis[6][2] = analysis[6][5] = analysis[7][1] = analysis[7][2] = analysis[7][5] = "e1";
	analysis[0][4] = analysis[1][4] = analysis[4][4] = analysis[6][4] = analysis[7][4] = "e2";
	analysis[1][0] = analysis[1][2] = analysis[1][3] = analysis[8][0] = analysis[8][2] = analysis[8][3] = "e3";
	analysis[8][5] = "e4";
	analysis[2][0] = analysis[2][3] = "r2";
	analysis[3][2] = analysis[3][3] = "r4";
	analysis[5][0] = analysis[5][3] = "r6";
	analysis[9][0] = analysis[9][3] = "r1";
	analysis[10][0] = analysis[10][3] = "r3";
	analysis[11][0] = analysis[11][3] = "r5";

}
/*输出移进还是规约,规约的话输出用到的产生式*/
void print(int into)
{
	if (into == 0)
	{
		cout << "--移进--" << endl;
		return;
	}
	cout << "--按";
	switch (into)
	{
	case 1:cout << "E->E+T"; break;
	case 2:cout << "E->T"; break;
	case 3:cout << "T->T*F"; break;
	case 4:cout << "T->F"; break;
	case 5:cout << "F->(E)"; break;
	case 6:cout << "F->id"; break;
	}
	cout << "规约--" << endl;
}
/*为终结符合非终结符编号*/
int NumOfSymbols(char c){
	/*switch (c){
	case 'a':return 0;
	case '+':return 1;
	case '*':return 2;
	case '(':return 3;
	case ')':return 4;
	case '#':return 5;
	case 'E':return 6;
	case 'T':return 7;
	case 'F':return 8;
	}*/
	if (c == 'a'){ return 0; }
	if (c == '+'){ return 1; }
	if (c == '*'){ return 2; }
	if (c == '('){ return 3; }
	if (c == ')'){ return 4; }
	if (c == '$'){ return 5; }
	if (c == 'E'){ return 6; }
	if (c == 'T'){ return 7; }
	if (c == 'F'){ return 8; }
}
char GetSymbol(int num){
	if (num == 0){ return 'a'; }
	if (num == 1){ return '+'; }
	if (num == 2){ return '*'; }
	if (num == 3){ return '('; }
	if (num == 4){ return ')'; }
	if (num == 5){ return '$'; }
	if (num == 6){ return 'E'; }
	if (num == 7){ return 'T'; }
	if (num == 8){ return 'F'; }
}
char sym[20];//把所有的符号,除了+*()$依顺序放进数组
/*将表达式从(a+b*c)+d*e的形式转换到(a+a*a)+a*a的形式才能进行SLR分析*/
char *Change(char* str){
	int len = strlen(str);
	int curr = 0;
	char * change = new char [len];
	for (int i = 0; i < len; i++){
		if (str[i] != '(' && str[i] != ')' && str[i] != '+' && str[i] != '*' && str[i] != '$'){
			change[i] = 'a';
			sym[curr] = str[i];
			curr++;
		}
		else{
			change[i] = str[i];
		}
	}
	return change;
}
void main(){
	string analysis[12][9];
	stack<int> s;
	stack<char> symstack;
	int curr = 0;
	char t = 49;
	char* input = "((a*c*d)+c*d)$";
	int len = strlen(input);
	cout << "输入表达式:" << input << endl;
	char *str = new char[len];
	str=Change(input);
	//cout << "化成LR文法可识别的形式为:" << str << endl;	
	Initial(analysis);
	s.push(0);
	/*循环中i表示当前处理得输入串中的角标*/
	for (int i = 0; i < len;){
		int stack_top = s.top();//记录栈顶状态
		//cout << "此时栈定状态为:" << stack_top;
		//cout << "  此时输入字符为:" << str[i] << endl;
		int lookahead = NumOfSymbols(str[i]);//记录当前输入串中,正在被处理的字符的标号
		/*移进*/
		if (analysis[stack_top][lookahead][0] == 's'){
			if (analysis[stack_top][lookahead][1] == 's'){
				//print(0);
				s.push(lookahead);
				s.push(11);
				//cout << "将状态11移进栈。" << endl;
				i++;
			}
			else{
				//print(0);
				s.push(lookahead);
				s.push(analysis[stack_top][lookahead][1] - '0');
				//cout << "将状态" << analysis[stack_top][lookahead][1] - '0' << "移进栈。" << endl;
				i++;//移进了一个后,就可以看下一个字符了  
			}
		}
		/*规约*/
		else if (analysis[stack_top][lookahead][0] == 'r'){
			int times;//如需规约,弹栈的次数
			int NumofNon_Terminal;//需要移进栈的终结符的编号
			//print(analysis[stack_top][lookahead][1] - '0');//输出规约的式子
			switch (analysis[stack_top][lookahead][1] - '0'){
			case 1: times = 6; NumofNon_Terminal = NumOfSymbols('E'); break;
			case 2: times = 2; NumofNon_Terminal = NumOfSymbols('E'); break;
			case 3: times = 6; NumofNon_Terminal = NumOfSymbols('T'); break;
			case 4: times = 2; NumofNon_Terminal = NumOfSymbols('T'); break;
			case 5: times = 6; NumofNon_Terminal = NumOfSymbols('F'); break;
			case 6: times = 2; NumofNon_Terminal = NumOfSymbols('F'); break;
			}
			for (int j = 0; j < times; j++){
				s.pop();
			}
			int pre_top = s.top();//记录此时的栈顶
			//cout << "弹栈" << times << "次后,栈顶状态为" << pre_top << endl;
			s.push(NumofNon_Terminal);
			char c = GetSymbol(NumofNon_Terminal);//为了输出字符,通过序号找到
			//cout << "放入" << c << endl;
			if (analysis[pre_top][NumofNon_Terminal].size() == 1){
				s.push(analysis[pre_top][NumofNon_Terminal][0] - '0');
				//cout << "将状态" << analysis[pre_top][NumofNon_Terminal][0] - '0' << "移进栈。" << endl;
			}
			else{
				s.push(10);
				//cout << "将状态10移进栈。" << endl;
			}
			/*为了能输出t1、t2这样的样式做了如下处理*/
			if (analysis[stack_top][lookahead][1] - '0' == 1){
				char temp1 = symstack.top();
				symstack.pop();
				char temp2 = symstack.top();
				symstack.pop();
				symstack.push(t);
				if (temp1 > 58 && temp2 > 58){
					cout << "t" << t << "=" << temp2 << "+" << temp1 << endl;
					t++;
				}
				if (temp1 < 58 && temp2 > 58){
					cout << "t" << t << "=" << temp2 << "+" << "t" << temp1 << endl;
					t++;
				}
				if (temp1 > 58 && temp2 < 58){
					cout << "t" << t << "=" << "t" << temp2 << "+" << temp1 << endl;
					t++;
				}
				if (temp1 < 58 && temp2 < 58){
					cout << "t" << t << "=" << "t" << temp2 << "+" << "t" << temp1 << endl;
					t++;
				}
			}
			if (analysis[stack_top][lookahead][1] - '0' == 3){
				char temp1 = symstack.top();
				symstack.pop();
				char temp2 = symstack.top();
				symstack.pop();
				symstack.push(t);
				if (temp1 > 58 && temp2 > 58){
					cout << "t" << t << "=" << temp2 << "*" << temp1 << endl;
					t++;
				}
				if (temp1 < 58 && temp2 > 58){
					cout << "t" << t << "=" << temp2 << "*" << "t" << temp1 << endl;
					t++;
				}
				if (temp1 > 58 && temp2 < 58){
					cout << "t" << t << "=" << "t" << temp2 << "*" << temp1 << endl;
					t++;
				}
				if (temp1 < 58 && temp2 < 58){
					cout << "t" << t << "=" << "t" << temp2 << "*" << "t" << temp1 << endl;
					t++;
				}
			}
			if (analysis[stack_top][lookahead][1] - '0' == 6){
				symstack.push(sym[curr]);
				curr++;
				//cout << "放入" << symstack.top() << endl;
			}
		}
		/*错误恢复*/
		else if (analysis[stack_top][lookahead][0] == 'e'){
			cout << "出现错误" << endl;
			switch (analysis[stack_top][lookahead][1]){
			case '1':{   //期望遇到a,那就把a放进去
						 s.push(0);
						 s.push(5);
						 cout << "缺少运算符,加入a" << endl;
						 break;
			}
			case '2':{
						 //遇见右括号,没有左括号,说明右括号错误
						 i++;
						 cout << "不匹配的右括号,将忽略该字符" << endl;
						 break;
			}
			case '3':{
						 //期望遇见运算符,加进+
						 s.push(1);
						 s.push(6);
						 cout << "缺少运算符,加入a" << endl;
						 break;
			}
			case '4':{
						 //提前结束,但期望遇见右括号,那就加入有括号
						 s.push(4);
						 s.push(11);
						 cout << "缺少右括号" << endl;
						 break;
			}
			}
		}
		else{
			if (analysis[stack_top][lookahead][0] == 'a'){
				cout << "接受" << endl;
				return;
			}
			else{
				cout << "无法识别,完蛋了!" << endl;
				return;
			}
		}

		//cout << "--------------------------------------" << endl;
	}
}

    原文作者:shl_shl
    原文地址: https://blog.csdn.net/shl_shl/article/details/53791724
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞