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

前面两次我们完成了对于固定的文法进行分析和从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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值