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

1、实验目的
设计、编制和调试一个典型的语法分析方法,进一步掌握常用的语法分析方法。
2、实验要求
(1) 根据LL(1)分析法编写一个语法分析程序,可根据自己实际情况,选择以下一项作为分析算法的输入:
a.直接输入根据已知文法构造的分析表M;
b.输入文法的FIRST(α)和FOLLOW(U)集合,由程序自动生成文法的分析表M;
c.输入已知文法,由程序自动构造文法的分析表M。
(2) 程序具有通用性
所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为LL(1)文法。
(3) 有运行实例
对于输入的文法和符号串,所编制的语法分析程序应能正确判断此串是否为文法的句子,并要求输出分析过程。
(4) 提交实验报告,报告内容参考“词法分析程序”


以上为要求,当然,这么庞大的要求我们要慢慢来,慢慢来。
我们先完成给定一个固定的文法的预测分析表,然后判断一个符号串是否属于该文法。我们的思路是这样的


  1. 不断判断分析栈的栈顶和剩余串的头是否一样
  2. 如果不同,则根据文法的预测分析表对分析栈栈顶进行推导
  3. 发生匹配后符号串减去头,栈弹出栈顶

当然为了流畅实现上述三个重复的活动,需要一些函数的辅助。以下为我的代码,如有谬误,望指出


#include 
#include 
#include
using namespace std;
string E[6]={"TE'","","","TE'","",""};
string E1[6]={"","+TE'","","","ε","ε"};
string T[6]={"FT'","","","FT'","",""};
string T1[6]={"","ε","*FT'","","ε","ε"};
string F[6]={"i","","","(E)","",""};

bool invertStack(stack<string> &one_stack)
{
    if (one_stack.empty())//if the stack is null,then don't invert it
    {
        return false;
    }else
    {
        //init a stack to save the inverted stack
        stack<string> invert;
        while(!one_stack.empty())
        {
            invert.push(one_stack.top());
            one_stack.pop();
        }
        //this moment the stack's inverted state is the stack invert ,so get it back
        one_stack=invert;
        return true;
    }
}
void displayStack(stack<string> one_stack)
{
    invertStack(one_stack);
    while(!one_stack.empty())
    {
        cout<cout<<"     ";
}
string configureProduction(stack<string> const &analyse,int char_index)
{
    if (analyse.top()=="E")
    {
        if (E[char_index]!="")
        {
            return E[char_index];
        }
    }else if (analyse.top()=="E'")
    {
        if (E1[char_index]!="")
        {
            return E1[char_index];
        }
    }else if (analyse.top()=="T")
    {
        if (T[char_index]!="")
        {
            return T[char_index];
        }
    }else if (analyse.top()=="T'")
    {
        if (T1[char_index]!="")
        {
            return T1[char_index];
        }
    }else if (analyse.top()=="F")
    {
        if (F[char_index]!="")
        {
        return F[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)//to find the Terminated char's index
{
    switch (some)
    {
    case 'i':return 0;
    case '+':return 1;
    case '*':return 2;
    case '(':return 3;
    case ')':return 4;
    case '#':return 5;
    default: 
        cout<<"error";
        return -1;
    }
}
bool display(stack<string> &analyse,string &odd)
{
    static int step=1;
    if (step==1)//while the first step is clearly
    {
        cout<"       ";
        displayStack(analyse);
        cout<"                ";
        int char_index=findTIndex(odd[0]);
        if (char_index==-1)
        {
            return false;
        }
        string production=configureProduction(analyse,char_index);
        cout<"->"<if (production=="error")
        {
            return false;
        }
        step++;
        analyse.pop();//pop the top element

        while(production.size()!=1)
        {
            if (production[production.length()-1]=='\'')
            {
                string temp=production.substr(production.length()-2,production.length()-1);
                analyse.push(temp);
                production=production.substr(0,production.length()-2);
            }else
            {
                string temp=production.substr(production.length()-1,production.length()-1);
                analyse.push(temp);
                production=production.substr(0,production.length()-1);
            }
        }
            analyse.push(production);
    }
    else
    {
        if (isMatching(analyse,odd[0]))
        {
            cout<"       ";
            displayStack(analyse);
            cout<"                ";
            if (odd[0]=='#')
            {
                cout<<"接受"<return false;
            }
            cout<<"“"<0]<<"”匹配"<1,odd.length()-1);//if match odd string decrease
            analyse.pop();
            step++;
            return true;
        }else
        {
            cout<"       ";
            displayStack(analyse);
            cout<"                ";
            int char_index=findTIndex(odd[0]);
            if (char_index == -1)
            {
                return false;
            }
            string production=configureProduction(analyse,char_index);
            cout<"->"<if (production=="error")
            {
                return false;
            }
            step++;
            if (production=="ε")
            {
                analyse.pop();
                return true;
            }
            analyse.pop();//pop the top element
            while(production.size()!=1)
            {
                if (production[production.length()-1]=='\'')
                {
                    string temp=production.substr(production.length()-2,production.length()-1);
                    analyse.push(temp);
                    production=production.substr(0,production.length()-2);
                }else
                {
                    string temp=production.substr(production.length()-1,production.length()-1);
                    analyse.push(temp);
                    production=production.substr(0,production.length()-1);
                }
            }
            analyse.push(production);
        }
    }
}
int main()
{
    cout<<"请输入符号串";
    string inputstring;
    cin>>inputstring;
    //init a stack to analyse
    stack<string> analyse_s;
    analyse_s.push("#");
    analyse_s.push("E");
    //init a odd string
    string odd =inputstring;
    cout<<"步骤       "<<"分析栈     "<<"剩余输入串       "<<"推导所用产生式或匹配"<//the first step is succeed
    while(!odd.empty()&&display(analyse_s,odd));
    system("pause");
    return 0;
}

因为机房里是VS2010所以注释是英文的,最后的代码会变成中文的注释。我们大概的分析过程出来了,那么下一步,我们从一个限定了格式的txt文件里面读出我们需要的预测分析表。

你可能感兴趣的:(C++)