1. 程式人生 > >實驗三 自底向上的語法分析

實驗三 自底向上的語法分析

設計要求
LR分析表

// 首先,感謝孫同學的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; }

執行結果如下:
分析結果