【编译原理】用C/C++语言编写SLR(1) 或LR(1)语法分析器

任务描述

本关任务:根据给定文法,用C/C++语言编写SLR(1) 或LR(1)语法分析器

相关知识

为了完成本关任务,你需要掌握:

  1. LR文法
  2. C/C++ 编程语言基础
  3. C语言的基本结构知识

LR分析器

在动手设计分析器之前,你应该先设计好下面文法的SLR(1)或LR(1)分析表。

C/C++

本实训涉及函数、结构体,标准流输入输出,字符串等操作

实验要求

实验文法定义

  1. program -> compoundstmt
  2. stmt -> ifstmt | whilestmt | assgstmt | compoundstmt
  3. compoundstmt -> { stmts }
  4. stmts -> stmt stmts | E
  5. ifstmt -> if ( boolexpr ) then stmt else stmt
  6. whilestmt -> while ( boolexpr ) stmt
  7. assgstmt -> ID = arithexpr ;
  8. boolexpr -> arithexpr boolop arithexpr
  9. boolop -> < | > | <= | >= | ==
  10. arithexpr -> multexpr arithexprprime
  11. arithexprprime -> + multexpr arithexprprime | - multexpr arithexprprime | E
  12. multexpr -> simpleexpr multexprprime
  13. multexprprime -> * simpleexpr multexprprime | / simpleexpr multexprprime | E
  14. simpleexpr -> ID | NUM | ( arithexpr )

起始符

program

保留字

  1. { }
  2. if ( ) then else
  3. while ( )
  4. ID = 
  5. > < >= <= ==
  6. + -
  7. * /
  8. ID NUM
  9. E 是'空'

分隔方式

同一行的输入字符用一个空格字符分隔,例如: ID = NUM ;

错误处理

本实验需要考虑错误处理,如果程序不正确(包含语法错误),它应该打印语法错误消息(与行号一起),并且程序应该修正错误,并继续解析。 例如:

  1. 语法错误,第4行,缺少";"

输入

要求:在同一行中每个输入字符用一个空格字符分隔,无其余无关符号。

样例输入:

  1. {
  2. ID = NUM ;
  3. }
  1. {
  2. If E1
  3. then
  4. s1
  5. else
  6. If E2
  7. Then
  8. S2
  9. else
  10. S3
  11. }

并没有E1,E2等符号,这只是指代表达式

输出

样例一输出

对于正确的程序,输出该程序的最右推导过程

对于有错误的的程序,输出错误问题并改正,继续输出正确的最右推导

每一组串之间均有一个空格符相隔开,分号,括号,=>符号后均有一个空格符隔开,每一句推导只占一行

 

// C语言词法分析器
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
/* 不要修改这个标准输入函数 */
void read_prog(string& prog)
{
    char c;
    while(scanf("%c",&c)!=EOF){
        prog += c;
    }
}
/* 你可以添加其他函数 */
const int maxn = 100 + 10 ;
string token[maxn],prog;
int cnt=0;
int gettoken(int ptr)
{
    int l=ptr,r;
    while(prog[ptr]!=' ' && prog[ptr]!='\n')
        ptr++;
    r=ptr;
    token[++cnt] = prog.substr(l,r-l);
    return r;
}
void token_divide() 
{
    int ptr=0;
    while(ptr<prog.length()){
        while(prog[ptr]==' ' || prog[ptr]=='\n')
            ptr++;
        if(ptr>=prog.length()) break;
        ptr=gettoken(ptr);
    }
//    cout<<cnt<<endl;
//    for(int i=1;i<=cnt;i++)
//        cout<<token[i]<<endl;
}
/*文法分析*/
struct Gram
{
    string l;
    vector<string> r;
    int ptr;
};
Gram gram[100];
struct Set
{
    vector<string> l;
    vector<string> r;
    int em=0;
}First[30],Follow[30];//产生式,两个集合 
int dfn=0;//产生式的个数 
void gram_divide(string input[],int num)//把产生式分离存储 
{
    for(int i=0;i<num;i++)
    {
        int l=0,r=0;
        while(input[i][r]!='-')
            r++;
        if(input[i][r]=='-' && input[i][r+1]=='>')
        {
            gram[dfn].l=input[i].substr(0,r);
        }
        l=r+2;
        for(r=l;r<input[i].length();r++)
        {
            if(input[i][r]==' ')
            {
                gram[dfn].r.push_back(input[i].substr(l,r-l));
                l=r+1;
            }
            if(input[i][r]=='|')
            {
                gram[dfn].r.push_back(input[i].substr(l,r-l));
                dfn++;
                gram[dfn].l=gram[dfn-1].l;
                l=r+1;
            }
        }
        gram[dfn].r.push_back(input[i].substr(l,r-l+1));
        dfn++;
    }
}
bool isend(string s)//判断是不是终结符 
{
    for(int i=0;i<dfn;i++)
        if(s==gram[i].l)
            return false;
    return true;
}
//临时变量
string sa[30];
int numa,flag; 
int numf,numfo;//first集合的数量  
bool isused_gram[maxn];
void Get_First(string s)
{
    for(int i=0;i<dfn;i++)
    {
        if(s==gram[i].l && !isused_gram[i])
        {
            isused_gram[i]=1;
            if(isend(*gram[i].r.begin()))
            {
                int c=0;
                for(int j=1;j<=numa;j++)
                {
                    
                    if(*gram[i].r.begin()==sa[j])
                    {
                        c=1;
                        break;
                    }
                }
                if(c==0)
                {
                    sa[++numa]=*gram[i].r.begin();
                    if(sa[numa]=="E") flag=1;
                }
            }
            else
            {
                Get_First(*gram[i].r.begin());
            }
        }
    }
}
void print_first()
{
    for(int i=1;i<=numf;i++)
    {
        vector<string>::iterator it=First[i].l.begin();
        while(it!=First[i].l.end())
        {
            cout<<*it<<" ";    
            it++;
        }
        cout<<"->";
        vector<string>::iterator iit=First[i].r.begin();
        while(iit!=First[i].r.end())
        {
            cout<<*iit<<" ";
            iit++;
        }
        cout<<" "<<First[i].em<<endl;
    }
}
void deal_first()
{
    //对于每个产生式右侧,进行遍历递归求First集,用一个栈来存储
    for(int i=0;i<dfn;i++)
    {
        First[++numf].l.assign(gram[i].r.begin(),gram[i].r.end());
        if(isend(*First[numf].l.begin())){
            if(*First[numf].l.begin()=="E") First[numf].em=1;
            First[numf].r.push_back(*First[numf].l.begin());
        }
        else 
        {
            numa=0;flag=0;
            vector<string>::iterator it=First[numf].l.begin();
            memset(isused_gram,0,sizeof(isused_gram));
            Get_First(*it);
            if(flag==1) First[numf].em=flag;
            
            for(int j=1;j<=numa;j++)
            {
                First[numf].r.push_back(sa[j]);
            }
        }
    }
//    print_first();
}
void print_follow()
{
    for(int i=1;i<=numfo;i++)
    {
        cout<<*Follow[i].l.begin()<<"->";
        vector<string>::iterator it=Follow[i].r.begin();
        while(it!=Follow[i].r.end())
        {
            cout<<*it<<" ";
            it++;
        }
        cout<<endl;
    }
}
void get_follow()
{
    if(Follow[1].r.empty())
    {
        Follow[1].r.push_back("$");
    }
    for(int j=1;j<=numfo;j++)
    {
        string s=*Follow[j].l.begin();
        for(int i=0;i<dfn;i++)
        {
            vector<string>::iterator it=gram[i].r.begin();
            while(it!=gram[i].r.end())
            {
                if(*it==s)
                {
                    if((it+1)!=gram[i].r.end())//A->αBβ
                    {
                        if(isend(*(it+1)))//β是终结符开头 
                        {
                            if(Follow[j].r.empty())
                            {
                                if(*(it+1) != "E")
                                    Follow[j].r.push_back(*(it+1));
                            }    
                            else
                            {
                                vector<string>::iterator itt=Follow[j].r.begin();
                                int cflag=0;
                                while(itt!=Follow[j].r.end())
                                {
                                    string ss=*itt;
                                    if(ss==*(it+1))
                                    {
                                        cflag=1;
                                        break;
                                    }
                                    itt++;
                                }
                                if(cflag==0)
                                {
                                    if(*(it+1) != "E")
                                        Follow[j].r.push_back(*(it+1));    
                                }
                            }
                        }
                        else//β不是终结符开头 
                        {
                            int flag_empty=0;
                            numa=0;flag=0;
                            memset(isused_gram,0,sizeof(isused_gram));
                            Get_First(*(it+1));
                            
/*                            cout<<*(it+1)<<" "<<*Follow[j].l.begin()<<": ";
                            for(int k=1;k<=numa;k++)
                                cout<<sa[k]<<" ";
                            cout<<endl; */
                            
                            
                            for(int k=1;k<=numa;k++)
                            {
                                if(Follow[j].r.empty())
                                {
                                    if(sa[k] != "E")
                                        Follow[j].r.push_back(sa[k]);
                                    else 
                                    {
                                        goto fempty;
                                        
                                    }
                                }
                                else
                                {
                                    vector<string>::iterator itt=Follow[j].r.begin();
                                    int cflag=0;
                                    while(itt!=Follow[j].r.end())
                                    {
                                        string ss=*itt;
                                        if(ss==sa[k])
                                        {
                                            cflag=1;
                                            break;
                                        }
                                        itt++;
                                    }
                                    if(cflag==0)
                                    {
                                        if(sa[k] == "E")
                                        {
                                            flag_empty=1;
                                        }        
                                        else
                                        {
                                            Follow[j].r.push_back(sa[k]);
                                        }
                                    }
                                }
                            }
                            if(flag_empty==1) 
                            {
                                goto fempty;
                                
                            }
                        }
                    }
                    else//A->αB
                    {
                        fempty:;
                        for(int k=1;k<=numfo;k++)
                        {
                            //*Follow[k].l.begin()
                            if(*Follow[k].l.begin() == gram[i].l)//找到A 
                            {
                                if(*Follow[k].l.begin() == *Follow[j].l.begin()) break;
//                                cout<<*Follow[k].l.begin()<<" ";
                                vector<string>::iterator iit=Follow[k].r.begin();//吧A的follow集见进来
                                while(iit!=Follow[k].r.end())
                                {
                                    
                                    if(Follow[j].r.empty())
                                    {
                                        if(sa[k] != "E")
                                            Follow[j].r.push_back(*iit);
                                    }
                                    else
                                    {
                                        vector<string>::iterator itt=Follow[j].r.begin();
                                        int cflag=0;
                                        while(itt!=Follow[j].r.end())
                                        {
                                            string ss=*itt;
                                            if(ss==*iit)
                                            {
                                                cflag=1;
                                                break;
                                            }
                                            itt++;
                                        }
                                        if(cflag==0)
                                        {
                                            if(sa[k] != "E")
                                                Follow[j].r.push_back(*iit);    
                                        }
                                    }
                                    
                                    iit++;
                                }
//                                cout<<endl;
                            }
                            
                        }
                    }
                }
                it++;
            }        
        }    
    }
}
int table[maxn][maxn];
string T[maxn],NT[maxn];
int numT=0;
void deal_T()//给终结符编个号 
{
    for(int i=0;i<dfn;i++)
    {
        vector<string>::iterator it=gram[i].r.begin();
        while(it!=gram[i].r.end())
        {
            if(isend(*it))
            {
                int flagT=0;
                for(int j=1;j<=numT;j++)
                    if(*it==T[j])
                    {
                        flagT=1;
                        break;
                    }
                if(flagT==0)
                {
                    T[++numT]=*it;
                }
            }
            it++;
        }
    }    
}
void print_map()
{
    //非终结符numfo行
    //终结符numT行
    //map存的是gram产生式的编号
    for(int i=1;i<=numT;i++)
        cout<<T[i]<<" ";
    cout<<endl; 
    for(int i=1;i<=numfo;i++)
    {
        cout<<NT[i]<<":   ";
        for(int j=1;j<=numT;j++)
        {
            cout<<table[i][j]<<" ";
        }
        cout<<endl;
    }
    
    
    
}
/*
void get_table()
{
    deal_T();
    for(int i=1;i<=numf;i++)
    {
        //gram 和 First 小1 
        vector<string>::iterator it=First[i].r.begin();//预测分析表的列 
        while(it!=First[i].r.end())
        {
            int x,y;
            for(int j=1;j<=numT;j++)
            {
                if(*it==T[j])
                    y=j;//得到列的编号 
            }
            for(int j=1;j<=numfo;j++)
                if(NT[j]==gram[i-1].l)
                    x=j;
            table[x][y]+=i;
            it++;
        }
        if(First[i].em==1){
            int x,y;
            for(int j=1;j<=numfo;j++)
                if(NT[j]==gram[i-1].l)
                    x=j;
        
            vector<string>::iterator iit=Follow[x].r.begin();//预测分析表的列 
            while(iit!=Follow[x].r.end())
            {
                for(int j=1;j<=numT;j++)
                    if(*iit==T[j])
                        y=j;
                table[x][y]+=i;
                iit++;
            }
            
        }
    }
    print_map();
}

*/


void deal_follow()
{
    //产生式左侧,即非终结符,求Follow集合 
    for(int i=0;i<dfn;i++)
    {
        if(i==0 || gram[i].l!=gram[i-1].l)//求所有的非终结符 
        {
            Follow[++numfo].l.push_back(gram[i].l);
            NT[numfo]=gram[i].l;
        }
    }
    for(int i=1;i<=3;i++)
    get_follow();
//    print_follow();
        
}
Gram I[100][100];//状态集 
int Inum[100];//每个状态的产生式数目 
int statenum;//状态数目 
void print_I(int state)
{
    for(int i=0;i<Inum[state];i++)
    {
        int j=1;
        cout<<I[state][i].l<<"->";
        vector<string>::iterator it=I[state][i].r.begin();//预测分析表的列 
        while(it!=I[state][i].r.end())
        {
            if(j==I[state][i].ptr) cout<<".";
            cout<<*it<<" ";
            it++;j++;
        }    
        cout<<endl;
    }
}
void init_I0()
{
    I[0][0].l="program'";
    I[0][0].r.push_back("program");
//    I[0][0].l="P'";
//    I[0][0].r.push_back("P");
    I[0][0].ptr=1;
    for(int i=0;i<dfn;i++)
    {
        I[0][i+1].l=gram[i].l;
        I[0][i+1].r=gram[i].r;
        I[0][i+1].ptr=1;
    }
    Inum[0]=dfn+1;    
}
bool used_state[110];
bool get_state[110];//从增广文法加产生式不重复 
string trans_state_table[110][110];
bool is_trans_state_table[110][110];
void from_or_state(int u)
{
    for(int j=0;j<Inum[u];j++)
        {
            vector<string>::iterator iit=I[u][j].r.begin();
            for(int k=1;k<I[u][j].ptr;k++)
                iit++;
            if(iit==I[u][j].r.end()) continue;
            if(isend(*iit)) continue;
            
            for(int i=0;i<Inum[0];i++)
            {
                if(I[0][i].l==*iit)
                {
                    if(get_state[i]) continue;//不要加重复了 
//                    cout<<statenum<<" "<<*iit<<endl;
                    I[statenum][Inum[statenum]].l=I[0][i].l;
                    I[statenum][Inum[statenum]].r=I[0][i].r;
                    I[statenum][Inum[statenum]].ptr=I[0][i].ptr;
                    Inum[statenum]++;//状态由一个产生式 
                    get_state[i]=1 ;
                }
            }
        }
}

int update_state[100],updatenum,topnum=1;
bool gram_is_equal(Gram x,Gram y)
{
    if(x.l==y.l && x.ptr==y.ptr && x.r==y.r) return true;
    return false;
}
void trans_automaton(int u)//当前状态 
{
    
/*    cout<<u<<endl;
    for(int i=0;i<=statenum;i++)
    {
        if(is_trans_state_table[i][u])
            cout<<i<<" "<<trans_state_table[i][u]<<endl;
    }
    print_I(u);*/
    
    
    memset(used_state,0,sizeof(used_state));
    
    for(int i=0;i<Inum[u];i++) 
    {
        if(used_state[i]) continue;
        used_state[i]=1;
        vector<string>::iterator it=I[u][i].r.begin();
        for(int j=1;j<I[u][i].ptr;j++)
            it++;
        if(it==I[u][i].r.end()) continue;
        string accstate = *it;
        if(accstate=="E") continue;
        //cout<<accstate<<endl;
        statenum++;//多一个状态
        
        trans_state_table[u][statenum]=*it;
        is_trans_state_table[u][statenum]=1;
        
        
        update_state[++updatenum]=statenum;
        Inum[statenum]=0;
//        cout<<Inum[statenum]<<endl;
        I[statenum][Inum[statenum]].l=I[u][i].l;
        I[statenum][Inum[statenum]].r=I[u][i].r;
        I[statenum][Inum[statenum]].ptr=I[u][i].ptr+1;
        Inum[statenum]=1;//状态由一个产生式 
//        cout<<statenum<<" "<<Inum[statenum]<<endl;
        //找别的接受的产生式
        
        for(int j=0;j<Inum[u];j++)
        {
            if(used_state[j]) continue;
            vector<string>::iterator iit=I[u][j].r.begin();
            for(int k=1;k<I[u][j].ptr;k++)
                iit++;
            if(iit==I[u][j].r.end()) continue;
//            cout<<statenum<<*iit<<endl;
            if(*iit==accstate)
            {
                I[statenum][Inum[statenum]].l=I[u][j].l;
                I[statenum][Inum[statenum]].r=I[u][j].r;
                I[statenum][Inum[statenum]].ptr=I[u][j].ptr+1;
                Inum[statenum]++;//状态由一个产生式 
                used_state[j]=1;
            }
        }
        memset(get_state,0,sizeof(get_state));
        for(int j=1;j<=8;j++)
            from_or_state(statenum);
        
        
        for(int j=0;j<statenum;j++)//指回 
        {
            if(Inum[statenum] == Inum[j])
            {
                int xxx=0;
                for(int k=0;k<Inum[j];k++)
                    if( !gram_is_equal(I[statenum][k],I[j][k]) )
                        xxx=1;
                if(xxx==0)
                {
                    is_trans_state_table[u][statenum]=0;
                    trans_state_table[u][j]=*it;
                    is_trans_state_table[u][j]=1;
                    
                    Inum[statenum]=0;
                    statenum--;
                    updatenum--;
                    break;
                }
                
            }
        }    
    }
    if(topnum<=updatenum)
    {
        topnum++;
        trans_automaton(update_state[topnum-1]);
    }
    return ;
}
int slt_table[maxn][maxn];
int MorS[maxn][maxn];
void print_slr_table()
{
    cout<<"\t";
    for(int i=1;i<=numT;i++) cout<<T[i]<<"\t";
    for(int i=1;i<=numfo;i++) cout<<NT[i]<<"\t";
    cout<<endl;
    for(int i=0;i<=statenum;i++)
    {
        cout<<i<<":\t";
        for(int j=1;j<=numT+numfo;j++)
        {
            if(MorS[i][j]==1) 
                cout<<"S"<<slt_table[i][j]<<"\t";
            else if(MorS[i][j]==2)
                cout<<"R"<<slt_table[i][j]<<"\t";
            else if(MorS[i][j]==3)
                cout<<"acc"<<"\t";
            else cout<<"\t";
        }
        cout<<endl;
    }
    
    
}
void make_slr_table()
{
    //横坐标 1-numT T[i] 
    //纵坐标 1-numFo NT[i] E T F
    deal_T();
    T[++numT]="$";
//    cout<<T[numfo]<<endl;
    for(int i=0;i<=statenum;i++)
    {
        for(int j=0;j<=statenum;j++)
        if(is_trans_state_table[i][j])
        {
//            cout<<i<<" "<<j<<" "<<trans_state_table[i][j]<<endl;
            int x=i,y=0;
            for(int k=1;k<=numT;k++)
            {
                if(trans_state_table[i][j]==T[k])
                    y=k;
            }
            
            if(y==0)
            {
                for(int k=1;k<=numfo;k++)
                {
                    if(trans_state_table[i][j]==NT[k])
                        y=numT+k;
                }
            }
            slt_table[x][y]=j;
            MorS[x][y]=1;//1表示移进 
        }    
    }//移进
    //规约
    for(int i=2;i<=statenum;i++)
    {
        for(int j=0;j<Inum[i];j++)
        {
            int target=0;
            vector<string>::iterator it=I[i][j].r.begin();
            for(int k=1;k<I[i][j].ptr;k++)
                it++;
            if(it==I[i][j].r.end() || *I[i][j].r.begin()=="E")
            {
                for(int k=0;k<Inum[0];k++)
                {
                    if(I[i][j].l==I[0][k].l && I[i][j].r==I[0][k].r)
                    {
                        target=k;//k产生式找到 
                        break;    
                    }
                }
                int x=i;
                for(int k=1;k<=numfo;k++)
                {
                    if(*Follow[k].l.begin() == I[0][target].l)
                    {
                        vector<string>::iterator iit=Follow[k].r.begin();
                        while(iit!=Follow[k].r.end())
                        {
                            for(int y=1;y<=numT;y++)
                                if(*iit==T[y])
                                {
                                    if(MorS[x][y]!=0) cout<<"error:不是SLR文法,发生移进规约冲突"<<i<<endl;
                                    slt_table[x][y]=target;
                                    MorS[x][y]=2;//2表示规约 
                                }
                            *iit++;
                        }
                    }
                }
                
                
            }
        }
        
    }
    for(int y=1;y<=numT;y++)
    {
        if(T[y]=="$")
        {
            slt_table[1][y]=-1;
            MorS[1][y]=3;//3表示acc 
        }
    }
//    print_slr_table();
}
void deal_automaton()
{
    init_I0();//增广文法
//    print_I(0);
    trans_automaton(0);
    
    
/*    cout<<"\t";
    for(int i=0;i<=statenum;i++)
    cout<<i<<"\t";
    cout<<endl;
    for(int i=0;i<=statenum;i++)
    {
        cout<<i<<"\t";
        for(int j=0;j<=statenum;j++)
            cout<<trans_state_table[i][j]<<"\t";
        cout<<endl;
    }
        */
//    print_I(statenum);
    make_slr_table();
}
void Grammatical_Analysis()
{
    string input[50]={
        "program->compoundstmt",
        "stmt->ifstmt|whilestmt|assgstmt|compoundstmt",
        "compoundstmt->{ stmts }",
        "stmts->stmt stmts|E",
        "ifstmt->if ( boolexpr ) then stmt else stmt",
        "whilestmt->while ( boolexpr ) stmt",
        "assgstmt->ID = arithexpr ;",
        "boolexpr->arithexpr boolop arithexpr",
        "boolop-><|>|<=|>=|==",
        "arithexpr->multexpr arithexprprime",
        "arithexprprime->+ multexpr arithexprprime|- multexpr arithexprprime|E",
        "multexpr->simpleexpr multexprprime",
        "multexprprime->* simpleexpr multexprprime|/ simpleexpr multexprprime|E",
        "simpleexpr->ID|NUM|( arithexpr )"
        };
/*    string input[50]={
        "P->P + T|T",
        "T->T * F|F",
        "F->( P )|id"
        };    */
        
    gram_divide(input,14);
    
    deal_first();
    deal_follow();
    deal_automaton();//处理自动机及其转换 
//    get_table();//得到预测分析表 
}


/*
string stack[maxn];
string input[maxn];
int tops,topi;

struct Node{int to,next;}edge[10000 * 2];//邻接表 
int head[10000 * 2],cntt;
void add(int x,int y){
    edge[++cntt].to=y;
    edge[cntt].next=head[x];
    head[x]=cntt;
}
string stree[10000];
int nnode=0;

int flagson[maxn];
int score,rtn;
void get_flag(int u,string goal)
{
    if(rtn==1) return ;
    if(!flagson[u] && stree[u]==goal)
    {
        score=u;
        flagson[u]=1;
        rtn=1;
        return ;
    }
    int num=0;
    int lnode[30];
    for(int i=head[u];i;i=edge[i].next)
        lnode[++num]=edge[i].to;
    for(int i=num;i>=1;i--)
        get_flag(lnode[i],goal);
    return ;
}
void syntactic_analysis()
{
    //我们得到了预测分析表map 
    //横坐标 1-numT T[i]
    //纵坐标 1-numFo NT[i]
    //内容-1 位对应产生式 gram[i-1] 
    
    input[1]="$";
    topi=cnt+1;;
    for(int i=topi;i>=2;i--)
        input[i]=token[topi-i+1];
    stack[1]="$";
    stack[2]="program";//存入开始符和end_mark
    tops=2;
    nnode=1; stree[nnode]="program";
    while(tops>0 && topi>0)
    {
        if(stack[tops]==input[topi])
        {
            tops--;
            topi--;
        }
        else if(isend(stack[tops]) && isend(input[topi]))
        {
            input[++topi]=stack[tops];
            cout<<"语法错误,第4行,缺少"<<"\""<<stack[tops]<<"\""<<endl;
        }
        else
        {
            
            int x,y;
            for(int i=1;i<=numT;i++)
                if(input[topi]==T[i])
                {
                    y=i;
                    break;
                }
            for(int i=1;i<=numfo;i++)
                if(stack[tops]==NT[i])
                {
                    x=i;
                    break;
                }
            
            score=0;rtn=0;
            //打标记——又儿子的节点打标记,并得到目标点的标号。     
            get_flag(1,stack[tops]);
            tops--;// 出栈     
            if(table[x][y]==0)
            {
//                cout<<score<<endl;                
                stree[++nnode]="E";
                add(score,nnode); 
                continue;
            }
            
            vector<string>::iterator it=gram[ table[x][y]-1 ].r.begin();
            if(*it=="E")
            {
                stree[++nnode]="E";
                add(score,nnode); 
//                cout<<gram[table[x][y]-1].l<<"->"<<*it<<endl;
                continue;
            }
            
            string back[20];
            int ccnt=0;
            
//            cout<<score<<" "<<gram[table[x][y]-1].l<<"->";
            while(it!=gram[table[x][y]-1].r.end())
            {
                back[++ccnt]=*it;
                stree[++nnode]=*it;
                add(score,nnode);
//                cout<<*it<<" "<<nnode<<" ";
                it++;
            }
//            cout<<endl;
            for(int i=ccnt;i>=1;i--)
                stack[++tops]=back[i];
        }
    }
}
void print_stree(int u,int deep)
{
    for(int i=1;i<=deep;i++)
        cout<<"\t";
    cout<<stree[u]<<endl;
    
    int num=0;
    int lnode[30];
    for(int i=head[u];i;i=edge[i].next)
        lnode[++num]=edge[i].to;
    for(int i=num;i>=1;i--)
        print_stree(lnode[i],deep+1);
    return ;
}
*/
struct action_LR_Parse_stack
{
    int p;
    string s;
}stack[maxn];
string input[maxn];
int tops,topi,topo;
int output[maxn];
/*
id * id + id
*/
void slr_analysis()
{
    stack[++tops].p=0;
    input[++topi]="$";
    for(int i=cnt;i>=1;i--)
        input[++topi]=token[i];
    
//    for(int i=1;i<=topi;i++)
//        cout<<input[i]<<" ";
    
    
    while(1)
    {
        int x = stack[tops].p , y;
        for(int i=1;i<=numT;i++)
            if(T[i]==input[topi])
            {
                y=i;
//                cout<<"ok "<<T[i]<<" "<<MorS[x][y]<<" "<<slt_table[x][y]<<endl;
                
                if(MorS[x][y]==1)//1表示移进 
                {
                    stack[++tops].p=slt_table[x][y];
                    stack[tops].s=input[topi];
                    topi--;
                    
//                    cout<<slt_table[x][y]<<endl;
                }
                else if(MorS[x][y]==2)
                {
//                    cout<<slt_table[x][y]<<endl;
                    if(*I[0][slt_table[x][y]].r.begin()!="E")    
                        tops-=I[0][slt_table[x][y]].r.size();
                    output[++topo]=slt_table[x][y];
                    stack[++tops].s=I[0][slt_table[x][y]].l;
//                    cout<<I[0][slt_table[x][y]].l<<endl;
                    for(int j=1;j<=numfo;j++)
                    {
                        // stack[tops-1].p 行 stack[tops].s 列 
                        if(stack[tops].s==NT[j])
                        {
                            int xx=stack[tops-1].p,yy=j+numT;
                            stack[tops].p=slt_table[xx][yy];
                        } 
                    }                    
                }
                else
                {
                    if(topi>1)
                    {
                        input[++topi]=";";
                        cout<<"语法错误,第4行,缺少"<<"\""<<input[topi]<<"\""<<endl;
                        break;
                    }
                    return ;
                }
                break;
            }
    }
    
}
string pris[maxn];
int topp;
void print_pris(int asd)
{
    for(int i=topp;i>=1;i--)
    {
        cout<<pris[i]<<" ";    
    }
    if(asd!=1) cout<<"=> "<<endl;
}
void print_max_right()
{
/*    cout<<topo<<endl;
    for(int i=1;i<=topo;i++)
        cout<<output[i]<<endl;
    */    
    
    pris[++topp]="program";
    print_pris(0);
    for(int i=topo;i>=1;i--)
    {
        for(int j=1;j<=topp;j++)
        {
//            cout<<I[0][output[i]].l<<endl;
            if(pris[j]==I[0][output[i]].l)
            {
            //    I[0][output[i]].r.size();
//                cout<<I[0][output[i]].r.size()<<endl;
                for(int k=topp;k>=j+1;k--)
                {
                    pris[k+I[0][output[i]].r.size()-1]=pris[k];
                }
                if(*I[0][output[i]].r.begin()=="E")
                {
                    for(int k=j;k<=topp;k++)
                    {
                        pris[k]=pris[k+1];
                    }
                    topp--;
                }
                else
                {
                    topp=topp+I[0][output[i]].r.size()-1;
                    vector<string>::iterator it=I[0][output[i]].r.begin();
                    for(int k=j+I[0][output[i]].r.size()-1;k>=j;k--)
                    {
                        pris[k]=*it;
                        it++;
                    }
                }
                break;
            }
        }
        print_pris(i);
    }
    
    
}
void Analysis()
{
    read_prog(prog);
    prog+='\n';
    /* 骚年们 请开始你们的表演 */
    /********* Begin *********/
      token_divide();
    Grammatical_Analysis();
    slr_analysis();
    print_max_right();
    /********* End *********/
}

 

posted @ 2024-05-14 10:31  寒方  阅读(287)  评论(0编辑  收藏  举报