C++:基于LL(1)方法的语法分析程序-3

来源:互联网 发布:网络教育是全日制吗 编辑:程序博客网 时间:2024/06/04 18:51

前面两次我们完成了对于固定的文法进行分析和从txt文件中生成预测分析表。下面我们改动第一次文件中本来应该可变的部分。


首先,我们修改关于分析表的一些函数,例如寻找产生式、寻找终结符的索引……然后我们进行一些优化,认为分析栈顶元素和剩余串时只有匹配和不匹配进行推导两种情况,并分别处理。最后,对于多于一个字符的非终结符进行处理。


#include"FileExchanger.h"#include<stack>FileExchanger fe;bool invertStack(stack<string> &one_stack){    if (one_stack.empty())//如果栈是空的不进行倒置    {        return false;    }    else    {        //初始化一个栈来储存倒置后的栈        stack<string> invert;        while (!one_stack.empty())        {            invert.push(one_stack.top());            one_stack.pop();        }        //赋值回去        one_stack = invert;        return true;    }}void displayStack(stack<string> one_stack)//此处为值传递,不会改变原来的栈,用于栈的倒叙输出{    invertStack(one_stack);    while (!one_stack.empty())    {        cout << one_stack.top();        one_stack.pop();    }    cout << "       ";}string configureProduction(stack<string> const &analyse, int char_index){    int line = 0;    //确定栈顶非终结符所在的行号    for (int i =1; i < fe.getLineNumber(); i++)    {        if (analyse.top()==fe.analyse_sheet[i][0])        {            line = i;        }    }    //如果非空,返回规则    if (fe.analyse_sheet[line][char_index]!="null")    {        return fe.analyse_sheet[line][char_index];    }    return "error";}bool isMatching(stack<string> const &analyse, char odd_first_char){    if (analyse.top()[0] == odd_first_char)    {        return true;    }    return false;}int findTIndex(char some)//查找终结符在分析表中的列号{    //temp完成字符向字符串的转换    string temp="a";    temp[0] = some;    for (int i = 1; i < fe.getColumnNumber(); i++)    {        if (fe.analyse_sheet[0][i]==temp)        {            return i;        }    }    return -1;}bool display(stack<string> &analyse, string &odd){    static int step = 1;    if (isMatching(analyse, odd[0]))    {        cout << step << "       ";        displayStack(analyse);        cout << odd << "                ";        if (odd[0] == '#')        {            cout << "接受" << endl;            return false;        }        cout << "“" << odd[0] << "”匹配" << endl;        odd = odd.substr(1, odd.length() - 1);//if match odd string decrease        analyse.pop();        step++;        return true;    }    else    {        //输出步骤        cout << step << "       ";        //输出分析栈        displayStack(analyse);        //输出剩余串        cout << odd << "                ";        //输出推倒所用产生式        int char_index = findTIndex(odd[0]);        if (char_index == -1)        {            return false;        }        string production = configureProduction(analyse, char_index);        cout << analyse.top() << "->" << production << endl;        if (production == "error")        {            return false;        }        step++;        if (production == "ε")        {            analyse.pop();            return true;        }        analyse.pop();//弹出栈顶元素        while (production.size()!=1)        {            string temp_one = production.substr(production.size() - 1, production.size() - 1);//获取最后一个字符            string temp_two = production.substr(production.size() - 2, production.size() - 1);//获取最后两个字符            //如果有非终结符是由三个以上字符组成只需在此处在添加处理            bool c = false;            for (int i = 1; i < fe.getLineNumber(); i++)            {                if (temp_one==fe.analyse_sheet[i][0])                {                    analyse.push(temp_one);                    production = production.substr(0, production.length() - 1);                    c = true;                }            }            if (c)            {                continue;            }            for (int i = 1; i < fe.getLineNumber(); i++)            {                if (temp_two == fe.analyse_sheet[i][0])                {                    analyse.push(temp_two);                    production = production.substr(0, production.length() - 2);                }            }        }        analyse.push(production);    }}int main(){    //产生预测分析表    fe.vInLine();//初始化终结符数组和非终结符数组    fe.buildSheet();//初始化整个预测分析表    cout << "请输入符号串,注意,以#号结尾"<<endl;    string inputstring;    cin >> inputstring;    //声明一个分析栈    stack<string> analyse_s;    analyse_s.push("#");    string identifer = fe.analyse_sheet[1][0];    analyse_s.push(identifer);    //声明剩余串    string odd = inputstring;    cout << "步骤     " << "分析栈       " << "剩余输入串     " << "推导所用产生式或匹配" << endl;    //the first step is succeed    while (!odd.empty() && display(analyse_s, odd));    system("pause");    return 0;}

以下是所有代码的云共享:
http://yunpan.cn/c33zRqaRCUyyV 访问密码 e648

0 0
原创粉丝点击