实验三 自底向上的语法分析

设计要求
LR分析表

// 首先,感谢孙同学的Java版代码,让我有了参考
// 下面上C++代码,文件操作部分自行改写即可
#include <iostream>
#include <fstream>
#include <cstring>
#include <stack>
using namespace std;

stack<string> state_st; // 状态栈 
stack<string> sign_st; // 符号栈 
string input_str = ""; // 输入串 
string action_table[][3] = { {"0","b","S2"}, {"1","#","acc"}, {"2","i","S5"}, {"3",";","S7"},
                            {"3","e","S6"}, {"4",";","R3"}, {"4","e","R3"}, {"5","=","S8"},
                            {"6","#","R1"}, {"7","i","S5"}, {"8","i","S14"}, {"8","n","S15"},
                            {"8","(","S13"}, {"9",";","R2"}, {"9","e","R2"}, {"10","+","S16"},
                            {"10","-","S17"}, {"10",";","R4"}, {"10","e","R4"}, {"11","+","R7"},
                            {"11","-","R7"}, {"11","*","S18"}, {"11","/","S19"}, {"11",")","R7"},
                            {"11",";","R7"}, {"11","e","R7"}, {"12","+","R10"}, {"12","-","R10"},
                            {"12","*","R10"}, {"12","/","R10"}, {"12",")","R10"}, {"12",";","R10"},
                            {"12","e","R10"}, {"13","i","S14"}, {"13","n","S15"}, {"13","(","S13"},
                            {"14","+","R12"}, {"14","-","R12"}, {"14","*","R12"}, {"14","/","R12"},
                            {"14",")","R12"}, {"14",";","R12"}, {"14","e","R12"}, {"15","+","R13"},
                            {"15","-","R13"}, {"15","*","R13"}, {"15","/","R13"}, {"15",")","R13"},
                            {"15",";","R13"}, {"15","e","R13"}, {"16","i","S14"}, {"16","n","S15"},
                            {"16","(","S13"}, {"17","i","S14"}, {"17","n","S15"}, {"17","(","S13"},
                            {"18","i","S14"}, {"18","n","S15"}, {"18","(","S13"}, {"19","i","S14"},
                            {"19","n","S15"}, {"19","(","S13"}, {"20","+","S16"}, {"20","-","S17"},
                            {"20",")","S25"}, {"21","+","R5"}, {"21","-","R5"}, {"21","*","S18"},
                            {"21","/","S19"}, {"21",")","R5"}, {"21",";","R5"}, {"21","e","R5"},
                            {"22","+","R6"}, {"22","-","R6"}, {"22","*","S18"}, {"22","/","S19"},
                            {"22",")","R6"}, {"22",";","R6"}, {"22","e","R6"}, {"23","+","R8"},
                            {"23","-","R8"}, {"23","*","R8"}, {"23","/","R8"}, {"23",")","R8"},
                            {"23",";","R8"}, {"23","e","R8"}, {"24","+","R9"}, {"24","-","R9"},
                            {"24","*","R9"}, {"24","/","R9"}, {"24",")","R9"}, {"24",";","R9"},
                            {"24","e","R9"}, {"25","+","R11"}, {"25","-","R11"}, {"25","*","R11"},
                            {"25","/","R11"}, {"25",")","R11"}, {"25",";","R11"}, {"25","e","R11"}
                          };
const int action_length = 100;                    
string goto_table[][3] = { {"0","P","1"}, {"2","D","3"}, {"2","S","4"}, {"7","S","9"},
                          {"8","E","10"}, {"8","T","11"}, {"8","F","12"}, {"13","E","20"},
                          {"13","T","11"}, {"13","F","12"}, {"16","T","21"}, {"16","F","12"},
                          {"17","T","22"}, {"17","F","12"}, {"18","F","23"}, {"19","F","24"},
                        }; 
int goto_length = 16;
string production[][2] = { {}, {"P","bDe"}, {"D","D;S"}, {"D","S"}, {"S","i=E"},
                          {"E","E+T"}, {"E","E-T"}, {"E","T"}, {"T","T*F"}, {"T","T/F"},
                          {"T","F"}, {"F","(E)"}, {"F","i"}, {"F","n"}
                        };
char symbol_table[8] = { '=','+','-','*','/','(',')',';' }; 
int state_value[action_length] = {0};               

void readFile()
{
    fstream f;
    char sf[255] = "C:\\Users\\admin_Li\\Desktop\\outfile.txt";
    f.open(sf,ios::in);
    if(!f)  { cout<<"源文件打开失败!"; exit(1); }

    f>>input_str;
    f.close();
}

void get_state_value()
{
    for(int i = 0; i < action_length; i++)
    {
        string s = action_table[i][2];
        s.replace(0,1,"");
        if(s.length() == 2)
        {
            state_value[i] = (s[0]-48)*10 + (s[1]-48);
        }
        else
        {
            state_value[i] = s[0] - 48;
        } 
    } 
}

string return_state(string a, string b)
{
    string str = "";
    char ch = b.at(0);
    // 输入串为非终结符 
    if(ch>='A' && ch<='Z')
    {
        for(int i = 0; i < goto_length; i++)
        {
            if((goto_table[i][0].compare(a) == 0) && (goto_table[i][1].compare(b) == 0))
            {
                str = goto_table[i][2];
            }
        }
    }
    // 输入串为终结符 
    else 
    {
        if((ch>='a' && ch<='z') || ch == symbol_table[0] ||
            ch == symbol_table[1] || ch == symbol_table[2] || 
            ch == symbol_table[3] || ch == symbol_table[4] || 
            ch == symbol_table[5] || ch == symbol_table[6] ||
            ch == symbol_table[7])
        {
            for(int i = 0; i < action_length; i++)
            {
                if((action_table[i][0].compare(a) == 0) &&
                   (action_table[i][1].compare(b) == 0))
                {
                    string s = action_table[i][2];
                    str = s.replace(0,1,""); 
                }
            }
        }
    }
    return str;
}

void analyse()
{
    input_str += "#";
    bool success_flag = false;
    bool state_flag = false;
    // 状态栈,符号栈,剩余输入串 
    string state_s = "", sign_s = "", rest_str = input_str;
    string current_s = ""; // 当前状态 
    string start_str = input_str.substr(0,1); // 输入串首字符
    int next = 1, num = 1;

    state_st.push("0"); sign_st.push("#");
    state_s += "0"; sign_s += "#";
    cout<<num<<"\t"<<state_st.top()<<"\t\t"<<sign_st.top()<<"\t\t"<<input_str<<endl;

    while(!success_flag)
    {
        current_s = state_st.top();
        for(int i = 0; i < action_length; i++)
        {
            if((action_table[i][0].compare(current_s) == 0) &&
               (action_table[i][1].compare(start_str) == 0))
            {
                state_flag = true;
                if(action_table[i][2] == "acc") 
                {
                    success_flag = true;
                    cout<<"------------------------"<<endl;
                    cout<<"语法分析成功(自下而上)"<<endl;
                    return ;
                }
                // 移入项 
                if(action_table[i][2].at(0) == 'S')
                {
                    state_st.push(return_state(current_s, start_str));
                    state_s += return_state(current_s, start_str);;
                    sign_st.push(start_str);
                    sign_s += start_str;

                    start_str = input_str.at(next);
                    // cout<<start_str<<endl;
                    rest_str = input_str.substr(next, input_str.length()-1);
                    next++; num++;
                }
                // 规约项
                if(action_table[i][2].at(0) == 'R')
                {
                    for(int j = 0; j < production[state_value[i]][1].length(); j++)
                    {
                        sign_s = sign_s.substr(0, sign_s.length()-1);
                        string top_s = state_st.top();
                        state_st.pop();
                        state_s = state_s.substr(0, state_s.length() - top_s.length());
                    }
                    sign_st.push(production[state_value[i]][0]);
                    sign_s += production[state_value[i]][0];
                    state_s += return_state(state_st.top(), production[state_value[i]][0]);
                    state_st.push(return_state(state_st.top(), production[state_value[i]][0]));
                    num++;
                } 
            }
        }
        if(!state_flag)
            cout<<"error"<<endl; // 未处理
        cout<<num<<"\t"<<state_s<<"\t\t"<<sign_s<<"\t\t"<<rest_str<<endl;
    }
}

int main()
{
    readFile();
    get_state_value();
    analyse();
    return 0;
}

运行结果如下:
分析结果

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页