1. 程式人生 > >LR(1)分析表

LR(1)分析表

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)分析表