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'; }
}
void main(){
string analysis[12][9];
stack<int> s;
char* str = "(a+a*a)+a*a$";
cout << "輸入表達式:" << str << endl;
/*cin >> str;*/
int len = strlen(str);
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;
}

}
/*錯誤恢復*/
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;
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章