要求:
输入:(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;
}
}