LR(1)分析表
阿新 • • 發佈:2018-06-03
ase ace using += man CI ont div cin
input.in:
S -> A A -> BB B -> aB B -> b
output.out:
CLOSURE -------------------- 0: A -> .BB, # B -> .aB, a B -> .aB, b B -> .b, a B -> .b, b S -> .A, # -------------------- 1: S -> A., # -------------------- 2: A -> B.B, # B -> .aB, # B -> .b, # -------------------- 3: B -> .aB, a B -> .aB, b B -> .b, a B -> .b, b B -> a.B, a B -> a.B, b -------------------- 4: B -> b., a B -> b., b -------------------- 5: A-> BB., # -------------------- 6: B -> .aB, # B -> .b, # B -> a.B, # -------------------- 7: B -> b., # -------------------- 8: B -> aB., a B -> aB., b -------------------- 9: B -> aB., # -------------------- LR(1)分析表 |--------------------------------------------------| | | ACTION | GOTO | | 狀態| a b #| A B| |--------------------------------------------------| | 0| s3 s4 | 1 2| | 1| acc| | | 2| s6 s7 | 5| | 3| s3 s4 | 8| | 4| r3 r3 | | | 5| r1| | | 6| s6 s7 | 9| | 7| r3| | | 8| r2 r2 | | | 9| r2| | |--------------------------------------------------| 狀態 符號 輸入串 1 0 # abab# 2 03 #a bab# 3 034 #ab ab# 4 038 #aB ab# 5 02 #B ab# 6 026 #Ba b# 7 0267 #Bab # 8 0269 #BaB # 9 025 #BB # 10 01 #A # 語法樹 (9,A) | (4,B) (8,B) (8,B) | (5,a) (7,B) (7,B) | (6,b) (4,B) | (1,a) (3,B) (3,B) | (2,b)
代碼:
1 #include <map> 2 #include <set> 3 #include <queue> 4 #include <stack> 5 #include <string> 6 #include <vector> 7 #include <iomanip> 8 #include <iostream> 9 using namespace std; 10 #define rep(i,a,n) for(int i=a;i<n;i++) 11 #define per(i,a,n) for(int i=n-1;i>=a;i--) 12 typedef pair<string, string> PSS; 13 typedef pair<PSS, char> Project; 14 const int WIDTH = 8; 15 // head 16 17 set<char> sc1{ ‘a‘,‘b‘,‘#‘ }; 18 set<char> sc2{ ‘A‘,‘B‘ }; 19 set<char> sc3{ ‘a‘,‘b‘,‘#‘,‘A‘,‘B‘ }; 20 string s = "ab#AB"; 21 map<char, int> Hash; 22 vector<PSS> vp; 23 set<PSS> sp; 24 vector<set<Project>> vsp(1); 25 string lr1[100][100]; 26 27 set<char> FIRST(string X) { 28 set<char> res; 29 rep(i, 0, X.length()) { 30 if (sc1.find(X[i]) != sc1.end()) { 31 res.insert(X[i]); 32 return res; 33 } 34 else { 35 int fg = 0; 36 rep(j, 0, vp.size()) { 37 if (vp[j].first[0] == X[i]) { 38 if (vp[j].second == "@") fg = 1; //@表示null 39 if (sc1.find(vp[j].second[0]) != sc1.end()) 40 res.insert(vp[j].second[0]); 41 else { 42 set<char> t = FIRST(vp[j].second); 43 res.insert(t.begin(), t.end()); 44 } 45 } 46 } 47 if (!fg) break; 48 } 49 } 50 return res; 51 } 52 53 void PROJECT() { 54 string a, b, c; 55 while (cin >> a >> b >> c) 56 vp.push_back(PSS(a, c)); 57 for (auto it : vp) { 58 a = it.first, b = it.second; 59 rep(i, 0, b.length() + 1) { 60 c = b; 61 c.insert(i, "."); 62 sp.insert(PSS(a, c)); 63 if (a == "S" && c[0] == ‘.‘) { 64 vsp[0].insert(Project(PSS(a, c), ‘#‘)); 65 } 66 } 67 } 68 } 69 70 set<Project> GO(set<Project> I, char X) { 71 set<Project> J; 72 for (auto it : I) { 73 string s = it.first.second; 74 int pos = s.find(‘.‘); 75 if (pos == s.length() - 1) continue; 76 if (s[pos + 1] == X) { 77 swap(s[pos], s[pos + 1]); 78 J.insert(Project(PSS(it.first.first, s), it.second)); 79 } 80 } 81 return J; 82 } 83 84 set<Project> CLOSURE(set<Project> I) { 85 while (1) { 86 int Size = I.size(); 87 for (auto it : I) { 88 string s = it.first.second; 89 int pos = s.find(‘.‘); 90 if (pos == s.length() - 1) continue; 91 char c = s[pos + 1]; 92 if (sc2.find(c) != sc2.end()) { 93 string B; 94 if (pos + 1 != s.length() - 1) B = s.substr(pos + 2); 95 B += it.second; 96 set<char> First = FIRST(B); 97 for (auto it1 : sp) { 98 if (it1.first[0] == c && it1.second[0] == ‘.‘) { 99 for (auto b : First) { 100 I.insert(Project(it1, b)); 101 } 102 } 103 } 104 } 105 } 106 if (Size == I.size()) break; 107 } 108 return I; 109 } 110 111 void LR1() { 112 vsp[0] = CLOSURE(vsp[0]); 113 rep(i, 0, vsp.size()) { 114 //規約 115 for (auto it : vsp[i]) { 116 int len = it.first.second.length(); 117 if (it.first.second[len - 1] == ‘.‘) { 118 it.first.second.erase(len - 1); 119 PSS p; 120 p.first = it.first.first; 121 p.second = it.first.second; 122 rep(j, 0, vp.size()) { 123 if (vp[j] == p) { 124 string t = "r" + to_string(j); 125 if (j == 0) t = "acc"; 126 lr1[i][Hash[it.second]] = t; 127 } 128 } 129 } 130 } 131 132 for (auto X : sc3) { 133 set<Project> J = GO(vsp[i], X); 134 J = CLOSURE(J); 135 if (!J.empty()) { 136 bool exist = false; 137 int k; 138 rep(j, 0, vsp.size()) { 139 if (vsp[j] == J) { 140 k = j; 141 exist = true; 142 break; 143 } 144 } 145 if (!exist) { 146 vsp.push_back(J); 147 k = vsp.size() - 1; 148 } 149 150 //移進和GOTO 151 int j = Hash[X]; 152 if (sc1.find(X) != sc1.end()) 153 lr1[i][j] = "s" + to_string(k); 154 else lr1[i][j] = to_string(k); 155 } 156 } 157 } 158 } 159 160 void PRINT() { 161 //輸出項目集規範族 162 cout << " CLOSURE" << endl; 163 rep(i, 0, 20) cout << ‘-‘; 164 cout << endl; 165 rep(i, 0, vsp.size()) { 166 cout << i << ":" << endl; 167 set<Project> sp = vsp[i]; 168 for (auto it : sp) 169 cout << " " << it.first.first << " -> " 170 << it.first.second << ", " << it.second << endl; 171 rep(i, 0, 20) cout << ‘-‘; 172 cout << endl; 173 } 174 cout << endl << endl << endl; 175 176 //輸出lr1分析表 177 rep(i, 0, 3) cout << setw(WIDTH) << ‘ ‘; 178 cout << "LR(1)分析表" << endl; 179 cout << ‘|‘; 180 rep(i, 0, 50) cout << ‘-‘; 181 cout << ‘|‘ << endl << ‘|‘; 182 cout << setw(WIDTH) << ‘ ‘; 183 cout << ‘|‘; 184 rep(i, 0, 1) cout << setw(WIDTH) << ‘ ‘; 185 cout << setw(WIDTH) << "ACTION"; 186 rep(i, 0, 1) cout << setw(WIDTH) << ‘ ‘; 187 cout << ‘|‘; 188 cout << setw(WIDTH*1.25) << "GOTO"; 189 cout << setw(WIDTH*0.75) << ‘ ‘; 190 cout << ‘|‘ << endl << ‘|‘; 191 cout << setw(WIDTH) << "狀態"; 192 cout << ‘|‘; 193 int n = vsp.size(); 194 int m = s.length(); 195 rep(i, 0, m) { 196 cout << setw(WIDTH) << s[i]; 197 if (s[i] == ‘#‘) cout << ‘|‘; 198 } 199 cout << ‘|‘ << endl << ‘|‘; 200 rep(i, 0, 50) cout << ‘-‘; 201 cout << ‘|‘ << endl << ‘|‘; 202 rep(i, 0, n) { 203 cout << setw(WIDTH) << i; 204 cout << ‘|‘; 205 rep(j, 0, m) { 206 cout << setw(WIDTH) << lr1[i][j]; 207 if (s[j] == ‘#‘) cout << ‘|‘; 208 } 209 cout << ‘|‘ << endl << ‘|‘; 210 } 211 rep(i, 0, 50) cout << ‘-‘; 212 cout << ‘|‘; 213 cout << endl << endl << endl; 214 } 215 216 void JUDGE(string str) { 217 int a[100], top = 1; 218 a[0] = 0; 219 string b = "#"; 220 string c = str + "#"; 221 222 cout << left << setw(WIDTH) << ""; 223 cout << left << setw(WIDTH) << "狀態"; 224 cout << left << setw(WIDTH) << "符號"; 225 cout << right << setw(WIDTH) << "輸入串" << endl; 226 227 int id = 1, cnt = 1; 228 vector<int> G[100]; 229 stack<int> S; 230 string value = " "; 231 while (1) { 232 string temp; 233 rep(i, 0, top) temp += to_string(a[i]); 234 cout << left << setw(WIDTH) << id++; 235 cout << left << setw(WIDTH) << temp; 236 cout << left << setw(WIDTH) << b; 237 cout << right << setw(WIDTH) << c << endl; 238 239 string action = lr1[a[top - 1]][Hash[c[0]]]; 240 if (action == "acc") break; 241 if (action == "") { 242 cerr << "error" << endl; 243 break; 244 } 245 if (action[0] == ‘s‘) { 246 action.erase(0, 1); 247 int num = atoi(action.c_str()); 248 a[top++] = num; 249 b += c[0]; 250 value += c[0]; 251 S.push(cnt++); 252 c.erase(0, 1); 253 } 254 else { 255 action.erase(0, 1); 256 int num = atoi(action.c_str()); 257 PSS p = vp[num]; 258 int len = p.second.length(); 259 queue<int> son; 260 while (len--) { 261 top--; 262 b.pop_back(); 263 son.push(S.top()); 264 S.pop(); 265 } 266 b += p.first; 267 value += p.first; 268 S.push(cnt++); 269 while (!son.empty()) { 270 G[cnt - 1].push_back(son.front()); 271 son.pop(); 272 } 273 a[top++] = atoi(lr1[a[top - 1]][Hash[p.first[0]]].c_str()); 274 } 275 } 276 cout << endl << endl; 277 278 cout << "語法樹" << endl; 279 per(i, 1, cnt) if (!G[i].empty()) { 280 cout << ‘(‘ << i << ‘,‘ << value[i] << ‘)‘ << " | "; 281 per(j, 0, G[i].size()) cout << ‘(‘ << G[i][j] << ‘,‘ << value[G[i][j]] << ‘)‘ << ‘ ‘; 282 cout << endl; 283 } 284 cout << endl << endl; 285 } 286 287 int main() { 288 freopen("C:\\Users\\Flowersea\\Desktop\\input.in", "r", stdin); 289 freopen("C:\\Users\\Flowersea\\Desktop\\output.out", "w", stdout); 290 291 rep(i, 0, s.length()) Hash[s[i]] = i; 292 PROJECT(); 293 LR1(); 294 PRINT(); 295 JUDGE("abab"); 296 297 fclose(stdin); 298 fclose(stdout); 299 return 0; 300 }
LR(1)分析表