LR--用棧實現移進--歸約分析(demo)
阿新 • • 發佈:2018-11-10
1.考慮文法
\(E->E+E\)
\(E->E*E\)
\(E->id\)
2.最右推導
不難看出,這個文法是而二義的,所以有多個最右推導
3.移進歸約
用一個棧存文法符號,用輸入快取區儲存要分析的輸入串,用$標記棧底
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<stack> using namespace std; const int maxn = 15; stack<string> stk, tmp; string w; bool flag = false; int main(void) { cin >> w; w += "$"; printf("----------|----------|----------\n"); printf(" 棧 | 輸入 | 動作 \n"); printf("----------|----------|----------\n"); int now = 0; while (!flag) { now = 0; if (stk.empty()) { stk.push("$"); cout << "$ |"; cout.setf(ios::right); cout.width(10); cout << w; cout<< "|移進" << endl; printf("----------|----------|----------\n"); string tt; if (w[now] == 'i') { tt = "id"; now = 2; } else { tt = w[now]; now = 1; } stk.push(tt); w = w.substr(now, w.size() - now); continue; } while (!stk.empty()) { tmp.push(stk.top()); stk.pop(); } while (!tmp.empty()) { cout << tmp.top(); stk.push(tmp.top()); tmp.pop(); } if (stk.top() == "id") { cout.width(10-stk.size()); cout << "|"; cout.setf(ios::right); cout.width(10); cout << w; cout<< "|按E-->id進行歸約" << endl; printf("----------|----------|----------\n"); stk.pop(); stk.push("E"); continue; } if (w[now]=='$'&&stk.size() == 2 && stk.top() == "E") { flag = true; cout<< " | $|接受"<< endl; printf("----------|----------|----------\n"); continue; } if (w[now]!='$') { string tp; if (w[now] == 'i') { tp = "id"; now = 2; } else { tp = w[now]; now = 1; } cout.width(11 - stk.size()); cout << "|"; cout.setf(ios::right); cout.width(10); cout << w; cout<< "|移進" << endl; printf("----------|----------|----------\n"); stk.push(tp); w = w.substr(now, w.size() - now); continue; } if (w[now] == '$' &&!flag) { string tc; tc = stk.top(); if (tc == "E") stk.pop(); tc += stk.top(); if (stk.top() != "E") { stk.pop(); tc += stk.top(); cout.setf(ios::right); cout.width(9- stk.size()); cout << "|"; cout << " $|"; cout << "按E-->"<<tc<<"歸約" << endl; printf("----------|----------|----------\n"); stk.pop(); stk.push("E"); } } } return 0; }
4.Sample
輸入
id*id+id