一、题目

  对下列文法,用SLR(1)分析法对任意输入的符号串进行分析:

  (1)S->E

  (2)E->E+T

  (3)E->T

  (4)T->T*F

  (5)T->F

  (6)F->(E)

  (7)F->i

二、设计思路

(1)总控程序,也可以称为驱动程序。对所有的LR分析器总控程序都是相同的。

(2)分析表或分析函数,不同的文法分析表将不同,同一个文法采用的LR分析器不同时,分析表将不同,分析表又可以分为动作表(ACTION)和状态转换(GOTO)表两个部分,它们都可用二维数组表示。

(3)分析栈,包括文法符号栈和相应的状态栈,它们均是先进后出栈。

分析器的动作就是由栈顶状态和当前输入符号所决定。

 LR分析器由三个部分组成:

其中:SP为栈指针,S[i]为状态栈,X[i]为文法符号栈。状态转换表用GOTO[i,X]=j表示,规定当栈顶状态为i,遇到当前文法符号为X时应转向状态j,X为终结符或非终结符。

 ACTION[i,a]规定了栈顶状态为i时遇到输入符号a应执行。动作有四种可能:

(1)移进:

    action[i,a]= Sj:状态j移入到状态栈,把a移入到文法符号栈,其中i,j表示状态号。

(2)归约:

    action[i,a]=rk:当在栈顶形成句柄时,则归约为相应的非终结符A,即文法中有A- B的产生式,若B的长度为R(即|B|=R),则从状态栈和文法符号栈中自顶向下去掉R个符号,即栈指针SP减去R,并把A移入文法符号栈内,j=GOTO[i,A]移进状态栈,其中i为修改指针后的栈顶状态。

(3)接受acc:

    当归约到文法符号栈中只剩文法的开始符号S时,并且输入符号串已结束即当前输入符是'#',则为分析成功。

(4)报错:

当遇到状态栈顶为某一状态下出现不该遇到的文法符号时,则报错,说明输入端不是该文法能接受的符号串。

三、源代码

ivregress 2sls结果怎么分析 slr(1)分析_i++

ivregress 2sls结果怎么分析 slr(1)分析_状态栈_02

#include<bits/stdc++.h>
using namespace std;

char vt[6] = { 'i', '+', '*', '(', ')', '#' }; //终结符
char vn[3] = { 'E', 'T', 'F' }; //非终结符

//文法
string wf[7] =
{
    "S->E",
    "E->E+T",
    "E->T",
    "T->T*F",
    "T->F",
    "F->(E)",
    "F->i"
};

//action表
string action[12][6] =
{
    "s5", "^", "^", "s4", "^", "^",
    "^", "s6", "^", "^", "^", "acc",
    "^", "r2", "s7", "^", "r2", "r2",
    "^", "r4", "r4", "^", "r4", "r4",
    "s5", "^", "^", "s4", "^", "^",
    "^", "r6", "r6", "^", "r6", "r6",
    "s5", "^", "^", "s4", "^", "^",
    "s5", "^", "^", "s4", "^", "^",
    "^", "s6", "^", "^", "s11", "^",
    "^", "r1", "s7", "^", "r1", "r1",
    "^", "r3", "r3", "^", "r3", "r3",
    "^", "r5", "r5", "^", "r5", "r5"
};

//goto表
int goto_[12][3] =
{
    1, 2, 3,
    0, 0, 0,
    0, 0, 0,
    0, 0, 0,
    8, 2, 3,
    0, 0, 0,
    0, 9, 3,
    0, 0, 10,
    0, 0, 0,
    0, 0, 0,
    0, 0, 0,
    0, 0, 0
};

//当前状态
string nowcout="0";
//输入串的游标
int com = 0;
int num = 1;

int t=0;
//输入串
string input = "";

stack <char> symbols;//创建一个符号栈

stack <int> status;//创建一个状态栈

void show(string statuA,int statuG);
void init()
{
    cout<<"输入的文法"<<endl;
    for (int j = 0; j < 6; j++)
    {
        cout << wf[j] << endl;
    }
    cout << "VT:";
    for (int i = 0; i < 6; i++)
    {
        cout << vt[i] << "\t";
    }
    cout << endl<< "VN:";
    for (int i = 0; i <3; i++)
    {
        cout << vn[i] << "\t";
    }
    cout << endl;
    symbols.push('#');
    status.push(0);

}
//获取非终结符所在下标
int getVtNowIndex(char now)
{
    for(int i=0;i<6;i++)
    {
        if(now==vt[i])
        {
            return i;
        }
    }
    return -1;
}
//获取终结符所在下标
int getVnNowIndex(char now)
{
    for(int i=0;i<3;i++)
    {
        if(now==vn[i])
        {
            return i;
        }
    }
    return -1;
}

//输出栈中元素但是不破坏栈的结构
int showStack(stack<int >&s){
    stack <int> temp;
    int num=s.size();
    for(int i=0;i<num;i++)
    {
        temp.push(s.top());
        s.pop();
    }
    for(int i=0;i<num;i++)
    {
        cout<<temp.top();
        s.push(temp.top());
        temp.pop();
    }
}

//输出栈中元素但是不破坏栈的结构
char showStack(stack<char >&s){
    stack <char> temp;
    int num=s.size();
    for(int i=0;i<num;i++)
    {
        temp.push(s.top());
        s.pop();
    }
    for(int i=0;i<num;i++)
    {
        cout<<temp.top();
        s.push(temp.top());
        temp.pop();
    }
}
//格式化输出
void show(string statuA,int statuG)
{
    showStack(status);
    cout<<"\t";
    showStack(symbols);
    cout<<"\t";
    cout<<input.substr(com);
    cout<<"\t\t"<<nowcout<<"\t"<<statuG<<endl;


}
//移进
void yj(int statu,char symbol)
{

    symbols.push(symbol);
    status.push(statu);
    string statuA = "s"+statu;
    show(statuA,0);
    com++;
}
//规约
void gy(int index)
{

    int n = wf[index].length()-3;
    for(int i=0;i<n;i++)
    {
        symbols.pop();
        status.pop();
    }
    symbols.push(wf[index][0]);
    int indexj = getVnNowIndex(wf[index][0]);
    int indexi = status.top();
    status.push(goto_[indexi][indexj]);
    string statuA = "r"+index;
    show(statuA,goto_[indexi][indexj]);
}
//分析
void analysis(string s)
{
    while(com<input.size())
    {
        int i = status.top();
        char ch = s[com];
        t=getVtNowIndex(ch);
        nowcout=action[i][t];
        if (action[i][t][0] == 's')
        {
            int t1 = action[i][t][1]-'0';
            yj(t1, ch);
        }
        else if (action[i][t][0] == 'r')
        {
            gy(action[i][t][1]-'0');
        }
        else if (action[i][t] == "^")
        {
            cout << "\tError" << endl;
            break;
        }
        else if (action[i][t] == "acc")
        {
            show("",0);
            //cout << "acc" << "\t 分析成功" << endl;
            break;
        }
    }
}

int main()
{
    init();
    cout<<"输入的文法:"<<endl;
    cin>>input;
    cout<<"状态栈\t符号栈\t输入串\t\tACTION\tGOTO\n";
    show("0",0);
    analysis(input);
    return 0;
}

View Code

四、运行结果

ivregress 2sls结果怎么分析 slr(1)分析_归约_03