LR分析表

Posted baocong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LR分析表相关的知识,希望对你有一定的参考价值。

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分析表的主要内容,如果未能解决你的问题,请参考以下文章

P15 LR 分析表编译原理

编译原理-第四章 语法分析-4.6 简单LR技术

编译原理—翻译方案属性栈代码

LR分析表

LR分析表的程序构建

LR分析-demo2