實驗三 自底向上的語法分析
阿新 • • 發佈:2019-01-04
// 首先,感謝孫同學的Java版程式碼,讓我有了參考
// 下面上C++程式碼,檔案操作部分自行改寫即可
#include <iostream>
#include <fstream>
#include <cstring>
#include <stack>
using namespace std;
stack<string> state_st; // 狀態棧
stack<string> sign_st; // 符號棧
string input_str = ""; // 輸入串
string action_table[][3 ] = { {"0","b","S2"}, {"1","#","acc"}, {"2","i","S5"}, {"3",";","S7"},
{"3","e","S6"}, {"4",";","R3"}, {"4","e","R3"}, {"5","=","S8"},
{"6","#","R1"}, {"7","i","S5"}, {"8","i","S14"}, {"8","n","S15"},
{"8","(","S13"}, {"9" ,";","R2"}, {"9","e","R2"}, {"10","+","S16"},
{"10","-","S17"}, {"10",";","R4"}, {"10","e","R4"}, {"11","+","R7"},
{"11","-","R7"}, {"11","*","S18"}, {"11","/","S19"}, {"11",")","R7"},
{"11",";","R7"}, {"11","e","R7"}, {"12" ,"+","R10"}, {"12","-","R10"},
{"12","*","R10"}, {"12","/","R10"}, {"12",")","R10"}, {"12",";","R10"},
{"12","e","R10"}, {"13","i","S14"}, {"13","n","S15"}, {"13","(","S13"},
{"14","+","R12"}, {"14","-","R12"}, {"14","*","R12"}, {"14","/","R12"},
{"14",")","R12"}, {"14",";","R12"}, {"14","e","R12"}, {"15","+","R13"},
{"15","-","R13"}, {"15","*","R13"}, {"15","/","R13"}, {"15",")","R13"},
{"15",";","R13"}, {"15","e","R13"}, {"16","i","S14"}, {"16","n","S15"},
{"16","(","S13"}, {"17","i","S14"}, {"17","n","S15"}, {"17","(","S13"},
{"18","i","S14"}, {"18","n","S15"}, {"18","(","S13"}, {"19","i","S14"},
{"19","n","S15"}, {"19","(","S13"}, {"20","+","S16"}, {"20","-","S17"},
{"20",")","S25"}, {"21","+","R5"}, {"21","-","R5"}, {"21","*","S18"},
{"21","/","S19"}, {"21",")","R5"}, {"21",";","R5"}, {"21","e","R5"},
{"22","+","R6"}, {"22","-","R6"}, {"22","*","S18"}, {"22","/","S19"},
{"22",")","R6"}, {"22",";","R6"}, {"22","e","R6"}, {"23","+","R8"},
{"23","-","R8"}, {"23","*","R8"}, {"23","/","R8"}, {"23",")","R8"},
{"23",";","R8"}, {"23","e","R8"}, {"24","+","R9"}, {"24","-","R9"},
{"24","*","R9"}, {"24","/","R9"}, {"24",")","R9"}, {"24",";","R9"},
{"24","e","R9"}, {"25","+","R11"}, {"25","-","R11"}, {"25","*","R11"},
{"25","/","R11"}, {"25",")","R11"}, {"25",";","R11"}, {"25","e","R11"}
};
const int action_length = 100;
string goto_table[][3] = { {"0","P","1"}, {"2","D","3"}, {"2","S","4"}, {"7","S","9"},
{"8","E","10"}, {"8","T","11"}, {"8","F","12"}, {"13","E","20"},
{"13","T","11"}, {"13","F","12"}, {"16","T","21"}, {"16","F","12"},
{"17","T","22"}, {"17","F","12"}, {"18","F","23"}, {"19","F","24"},
};
int goto_length = 16;
string production[][2] = { {}, {"P","bDe"}, {"D","D;S"}, {"D","S"}, {"S","i=E"},
{"E","E+T"}, {"E","E-T"}, {"E","T"}, {"T","T*F"}, {"T","T/F"},
{"T","F"}, {"F","(E)"}, {"F","i"}, {"F","n"}
};
char symbol_table[8] = { '=','+','-','*','/','(',')',';' };
int state_value[action_length] = {0};
void readFile()
{
fstream f;
char sf[255] = "C:\\Users\\admin_Li\\Desktop\\outfile.txt";
f.open(sf,ios::in);
if(!f) { cout<<"原始檔開啟失敗!"; exit(1); }
f>>input_str;
f.close();
}
void get_state_value()
{
for(int i = 0; i < action_length; i++)
{
string s = action_table[i][2];
s.replace(0,1,"");
if(s.length() == 2)
{
state_value[i] = (s[0]-48)*10 + (s[1]-48);
}
else
{
state_value[i] = s[0] - 48;
}
}
}
string return_state(string a, string b)
{
string str = "";
char ch = b.at(0);
// 輸入串為非終結符
if(ch>='A' && ch<='Z')
{
for(int i = 0; i < goto_length; i++)
{
if((goto_table[i][0].compare(a) == 0) && (goto_table[i][1].compare(b) == 0))
{
str = goto_table[i][2];
}
}
}
// 輸入串為終結符
else
{
if((ch>='a' && ch<='z') || ch == symbol_table[0] ||
ch == symbol_table[1] || ch == symbol_table[2] ||
ch == symbol_table[3] || ch == symbol_table[4] ||
ch == symbol_table[5] || ch == symbol_table[6] ||
ch == symbol_table[7])
{
for(int i = 0; i < action_length; i++)
{
if((action_table[i][0].compare(a) == 0) &&
(action_table[i][1].compare(b) == 0))
{
string s = action_table[i][2];
str = s.replace(0,1,"");
}
}
}
}
return str;
}
void analyse()
{
input_str += "#";
bool success_flag = false;
bool state_flag = false;
// 狀態棧,符號棧,剩餘輸入串
string state_s = "", sign_s = "", rest_str = input_str;
string current_s = ""; // 當前狀態
string start_str = input_str.substr(0,1); // 輸入串首字元
int next = 1, num = 1;
state_st.push("0"); sign_st.push("#");
state_s += "0"; sign_s += "#";
cout<<num<<"\t"<<state_st.top()<<"\t\t"<<sign_st.top()<<"\t\t"<<input_str<<endl;
while(!success_flag)
{
current_s = state_st.top();
for(int i = 0; i < action_length; i++)
{
if((action_table[i][0].compare(current_s) == 0) &&
(action_table[i][1].compare(start_str) == 0))
{
state_flag = true;
if(action_table[i][2] == "acc")
{
success_flag = true;
cout<<"------------------------"<<endl;
cout<<"語法分析成功(自下而上)"<<endl;
return ;
}
// 移入項
if(action_table[i][2].at(0) == 'S')
{
state_st.push(return_state(current_s, start_str));
state_s += return_state(current_s, start_str);;
sign_st.push(start_str);
sign_s += start_str;
start_str = input_str.at(next);
// cout<<start_str<<endl;
rest_str = input_str.substr(next, input_str.length()-1);
next++; num++;
}
// 規約項
if(action_table[i][2].at(0) == 'R')
{
for(int j = 0; j < production[state_value[i]][1].length(); j++)
{
sign_s = sign_s.substr(0, sign_s.length()-1);
string top_s = state_st.top();
state_st.pop();
state_s = state_s.substr(0, state_s.length() - top_s.length());
}
sign_st.push(production[state_value[i]][0]);
sign_s += production[state_value[i]][0];
state_s += return_state(state_st.top(), production[state_value[i]][0]);
state_st.push(return_state(state_st.top(), production[state_value[i]][0]));
num++;
}
}
}
if(!state_flag)
cout<<"error"<<endl; // 未處理
cout<<num<<"\t"<<state_s<<"\t\t"<<sign_s<<"\t\t"<<rest_str<<endl;
}
}
int main()
{
readFile();
get_state_value();
analyse();
return 0;
}
執行結果如下: