实验二 自上而下的语法分析

设计要求

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

char p_relation[][2] = { {'P','b'}, {'D','i'}, {'A','e'}, {'A',';'},
                         {'S','i'}, {'E','i'}, {'E','('}, {'E','n'},
                         {'B','e'}, {'B',';'}, {'B','+'}, {'B','-'},
                         {'B',')'}, {'T','i'}, {'T','('}, {'T','n'},
                         {'C','e'}, {'C',';'}, {'C','+'}, {'C','-'},
                         {'C','*'}, {'C','/'}, {'C',')'}, {'F','i'},    
                         {'F','('}, {'F','n'} }; 

/*
string p_relation[] = { "Pb","Di","Ae","A;","Si","Ei","E(","En","Be",
                       "B;","B+","B-","B)","Ti","T(","Tn","Ce","C;",
                       "C+","C-","C*","C/","C)","Fi","F(","Fn" }; 
*/
string p_content[][2] = { {"P","bDe"}, {"D","SA"} ,{"A","@"} ,{"A",";SA"},
                          {"S","i=E"}, {"E","TB"} ,{"E","TB"} ,{"E","TB"},
                          {"B","@"}, {"B","@"} ,{"B","+TB"} ,{"B","-TB"},
                          {"B","@"}, {"T","FC"} ,{"T","FC"} ,{"T","FC"},
                          {"C","@"}, {"C","@"} ,{"C","@"} ,{"C","@"},
                          {"C","*FC"}, {"C","/FC"} ,{"C","@"} ,{"F","i"},
                          {"F","(E)"}, {"F","n"} };
int production_length = 26;
char symbol_table[] = { '=','+','-','*','/','(',')',';'};
string str = "";
char start_ch = ' ';
char top_ch = ' ';
stack<char> st;

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>>str;
    f.close();
}

bool isProduction(char a, char b)
{
    bool fit_flag = false;
    for(int i = 0; i < production_length; i++)
    {
        if((p_relation[i][0] == a) && (p_relation[i][1] == b))
        {
            fit_flag = true;
            break;
        }
    }
    return fit_flag; 
}

void analyse()
{
    str += "#";
    bool success_flag = false;
    int next = 1, num = 1;
    // 符号栈: s,剩余输入串: rest_str,产生式: production_str
    string s = "", rest_str = str, production_str = "";
    st.push('#'); st.push('P');
    s += "#"; s += "P";
    start_ch = str.at(0);
    cout<<num<<"\t"<<s<<"\t\t"<<rest_str<<endl;
    num++;
    while(!success_flag)
    {
        top_ch = st.top();
        st.pop();
        s = s.substr(0, s.length()-1);
        // 处理终结符 
        if((top_ch>='a' && top_ch<='z') || top_ch == symbol_table[0] || 
            top_ch == symbol_table[1] || top_ch == symbol_table[2] || 
            top_ch == symbol_table[3] || top_ch == symbol_table[4] || 
            top_ch == symbol_table[5] || top_ch == symbol_table[6] || 
            top_ch == symbol_table[7])
        {
            if(top_ch == start_ch)
            {
                start_ch = str.at(next);
                rest_str = str.substr(next, str.length()-1);
                next++;
                cout<<num<<"\t"<<s<<"\t\t"<<rest_str<<"\t\t"<<production_str<<endl;
                num++;
            } 
            else
            {
                cout<<"error1"<<endl; // 未处理 
                return ;
            }
        }
        // 处理非终结符 
        else if(isProduction(top_ch, start_ch))
        {
            // 判断为产生式编号 
            int i;
            for(i = 0; i < production_length; i++)
            {
                if((p_relation[i][0] == top_ch) && (p_relation[i][1] == start_ch))
                    break;
            }
            production_str =  p_content[i][0] + "->" + p_content[i][1];
            for(int j = p_content[i][1].length()-1; j >= 0; j--)
            {
                if(p_content[i][1].at(j) != '@')
                {
                    st.push(p_content[i][1].at(j));
                    s += p_content[i][1].at(j);
                }
            }
            cout<<num<<"\t"<<s<<"\t\t"<<rest_str<<"\t\t"<<production_str<<endl;
            num++;
        }
        // 处理结束符号: # 
        else if(top_ch == '#')
        {
            if(top_ch == start_ch)
                success_flag = true;
            else
            {
                cout<<"error2"<<endl; // 未处理 
                return ;
            }
        }
    }
    cout<<"------------------------"<<endl; 
    cout<<"语法分析成功(自顶向下)"<<endl; 
}

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

运行结果:
分析结果

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