LR--用栈实现移进--归约分析(demo)

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

5.To be continued.

猜你喜欢

转载自www.cnblogs.com/FlyerBird/p/9940723.html