编译原理项集规范族(初步)

本文介绍了一个使用C++实现的LR语法分析器程序,该程序能够接收用户输入的文法并构建LR项集规范族。通过对输入文法的处理,程序能够识别文法中的终结符和非终结符,并通过闭包运算生成相应的项集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<bits/stdc++.h>
using namespace std;
int Norterminal(char c)
{
    if(c>='A'&&c<='Z') 
        return 1;
    else if(c!=':'&&c!='='&&c!='<'&&c!='>'&&c!=' '&&c!='|') 
        return 0; 

} 
struct LR
{
    string  nape;//项
    vector<string> str;
    string later;//后继关系 
};
int main()
{
    cout<<"请输入文法(以#结束)"<<endl;
    vector<string> strN; //保存文法 
    LR Lr[100]; 
    //输入文法 
    string grammer;
    cin>>grammer;
    string nonterm="";
    strN.push_back(grammer);  
    for(int i=0;grammer!="#";i++)
    {
        cin>>grammer;
        strN.push_back(grammer); 

    }
    //变为增广文法 
    string s="Z::=";
    s+=strN[0][0];
    s+='#';
    strN.insert(strN.begin(),s);
    for(int i=0;i<strN.size();i++)
    {
        if(Norterminal(strN[i][0]))
            nonterm+=strN[i][0];
        string ustr(nonterm);
        sort(ustr.begin(), ustr.end());
        ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
        nonterm=ustr;

    } 
    nonterm.erase(nonterm.end() - 1);
//  cout<<nonterm<<endl; 
    //求解初始项集的闭包 
//  cout<<"初始项集"<<endl; 
    Lr[0].str.push_back(strN[0]);  
    char non; 
    //找第一个终结符   
    if(Norterminal(strN[0][4]))
    {
        Lr[0].nape=s[0];
        non=strN[0][4]; 
        Lr[0].str[0][3]='.';
        Lr[0].str[0][2]='>';
        Lr[0].str[0][1]='-'; 
    }
    for(int j=1;j<strN.size();j++)
    {
            if(non==strN[j][0])
            {
                Lr[0].str.push_back(strN[j]);  
                int h=Lr[0].str.size(); 
                Lr[0].str[h-1][3]='.';
                Lr[0].str[h-1][2]='>';
                Lr[0].str[h-1][1]='-'; 
                if(Norterminal(strN[j][4])&&strN[j][4]!=non)
                {

                    for(int g=1;g<strN.size();g++) 
                    {

                        if(strN[g][4]==non&&j!=g)
                        {
                            Lr[0].str.push_back(strN[g]);  
                            int h1=Lr[0].str.size(); 
                            Lr[0].str[h1-1][3]='.';
                            Lr[0].str[h1-1][2]='>';
                            Lr[0].str[h1-1][1]='-';
                        } 


                     }
                     non=strN[j][4];
                }

            } 

    } 
/*  for(int i=0;i<Lr[0].str.size();i++)
    {
        for(int j=0;j<Lr[0].str.size();j++)
        {
            if(Lr[0].str[i].compare(Lr[0].str[j])==0&&i!=j)
                Lr[0].str.erase(Lr[0].str.begin()+j);
        }
        cout<<Lr[0].str[i]<<endl; 
    }  */
    /*求解项集规范族 */
    //求解当前项集中的终结符与非终结符以便于后续的存放。 
    string nont;//存放当前闭包$后边遇到的字母 
    int totalnum=1;
   //偶数遍历 
    for(int r=0;r<totalnum;r++)
    {
            nont="";
            for(int i=0;i<Lr[r].str.size();i++)
            {
                for(int j=0;j<Lr[r].str[i].length();j++)
                {
                    if(Lr[r].str[i][j]=='.'&&j+1!=Lr[r].str[i].length())
                    {
                        nont+=Lr[r].str[i][j+1];
                    }
                }
                string ustr(nont);
                sort(ustr.begin(), ustr.end());
                ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
                nont=ustr;
                //Lr[r].later=nont;
            }   
        //  now=r;
            //cout<<nont<<":"<<r<<endl;
            for(int i=0;i<nont.length();i++)
            {
                Lr[totalnum+i].nape=nont[i];

             } 

             //将.后移 
            for(int i=0;i<Lr[r].str.size();i++)
            {
                for(int j=0;j<Lr[r].str[i].length();j++)
                {
                    if(Lr[r].str[i][j]=='.')
                    {
                        for(int l=0;l<nont.length();l++)
                        {
                            if(Lr[r].str[i][j+1]==Lr[totalnum+l].nape[0])
                            {
                                Lr[r].str[i].erase(Lr[r].str[i].begin()+j);
                                Lr[r].str[i].insert(Lr[r].str[i].begin()+j+1,'.');
                                Lr[totalnum+l].str.push_back(Lr[r].str[i]);
                                Lr[r].str[i].erase(Lr[r].str[i].begin()+j+1);
                                Lr[r].str[i].insert(Lr[r].str[i].begin()+j,'.');
                            }
                         } 

                    }
                }
            }
           //若遇到终结符进行闭包运算 
            for(int i=0;i<nont.length();i++)
           {

                for(int k=0;k<Lr[totalnum+i].str.size();k++)
                {

                    for(int g=0;g<Lr[totalnum+i].str[k].length();g++)
                    {
                        if(Lr[totalnum+i].str[k][g]=='.'&&g+1!=Lr[totalnum+i].str[k].length())
                        {

                            if(Norterminal(Lr[totalnum+i].str[k][g+1]))
                            {
                                non=Lr[totalnum+i].str[k][g+1];
                                for(int j1=1;j1<strN.size();j1++)
                                { 
                                    if(non==strN[j1][0])
                                    {
                                        Lr[totalnum+i].str.push_back(strN[j1]);  
                                        int h=Lr[totalnum+i].str.size(); 
                                        Lr[totalnum+i].str[h-1][3]='.';
                                        Lr[totalnum+i].str[h-1][2]='>';
                                        Lr[totalnum+i].str[h-1][1]='-'; 
                                        if(Norterminal(strN[j1][4]))
                                        {

                                            for(int g1=1;g1<strN.size();g1++) 
                                            {

                                                if(strN[g1][4]==non&&j1!=g1&&strN[g][0]==strN[g1][4])
                                                {
                                                    Lr[totalnum+i].str.push_back(strN[g1]);  
                                                    int h1=Lr[totalnum+i].str.size(); 
                                                    Lr[totalnum+i].str[h1-1][3]='.';
                                                    Lr[totalnum+i].str[h1-1][2]='>';
                                                    Lr[totalnum+i].str[h1-1][1]='-';
                                                } 


                                             }
                                             non=strN[j1][4];
                                        }

                                    } 

                                }
                                break;
                           }
                       }

                    }
                    break;

                }
           }
          r+=1;
          if(nont.length()!=0)
            totalnum+=nont.length();

    }  
    //奇数遍历 
    for(int r=1;r<totalnum;r++)
    {
            nont="";
            for(int i=0;i<Lr[r].str.size();i++)
            {
                for(int j=0;j<Lr[r].str[i].length();j++)
                {
                    if(Lr[r].str[i][j]=='.'&&j+1!=Lr[r].str[i].length())
                    {
                        nont+=Lr[r].str[i][j+1];
                    }
                }
                string ustr(nont);
                sort(ustr.begin(), ustr.end());
                ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
                nont=ustr;
            //  Lr[r].later=nont;
            }   
        //  now=r;
            //cout<<nont<<":"<<r<<endl;
            for(int i=0;i<nont.length();i++)
            {
                Lr[totalnum+i].nape=nont[i];

             } 

             //将.后移 
            for(int i=0;i<Lr[r].str.size();i++)
            {
                for(int j=0;j<Lr[r].str[i].length();j++)
                {
                    if(Lr[r].str[i][j]=='.')
                    {
                        for(int l=0;l<nont.length();l++)
                        {
                            if(Lr[r].str[i][j+1]==Lr[totalnum+l].nape[0])
                            {
                                Lr[r].str[i].erase(Lr[r].str[i].begin()+j);
                                Lr[r].str[i].insert(Lr[r].str[i].begin()+j+1,'.');
                                Lr[totalnum+l].str.push_back(Lr[r].str[i]);
                                Lr[r].str[i].erase(Lr[r].str[i].begin()+j+1);
                                Lr[r].str[i].insert(Lr[r].str[i].begin()+j,'.');
                            }
                         } 

                    }
                }
            }
    //若遇到终结符进行闭包运算 
            for(int i=0;i<nont.length();i++)
           {

                for(int k=0;k<Lr[totalnum+i].str.size();k++)
                {

                    for(int g=0;g<Lr[totalnum+i].str[k].length();g++)
                    {
                        if(Lr[totalnum+i].str[k][g]=='.'&&g+1!=Lr[totalnum+i].str[k].length())
                        {

                            if(Norterminal(Lr[totalnum+i].str[k][g+1]))
                            {
                                non=Lr[totalnum+i].str[k][g+1];
                                for(int j1=1;j1<strN.size();j1++)
                                { 
                                    if(non==strN[j1][0])
                                    {
                                        Lr[totalnum+i].str.push_back(strN[j1]);  
                                        int h=Lr[totalnum+i].str.size(); 
                                        Lr[totalnum+i].str[h-1][3]='.';
                                        Lr[totalnum+i].str[h-1][2]='>';
                                        Lr[totalnum+i].str[h-1][1]='-'; 
                                        if(Norterminal(strN[j1][4]))
                                        {

                                            for(int g1=1;g1<strN.size();g1++) 
                                            {

                                                if(strN[g1][4]==non&&j1!=g1&&strN[g][0]==strN[g1][4])
                                                {
                                                    Lr[totalnum+i].str.push_back(strN[g1]);  
                                                    int h1=Lr[totalnum+i].str.size(); 
                                                    Lr[totalnum+i].str[h1-1][3]='.';
                                                    Lr[totalnum+i].str[h1-1][2]='>';
                                                    Lr[totalnum+i].str[h1-1][1]='-';
                                                } 


                                             }
                                             non=strN[j1][4];
                                        }

                                    } 

                                }
                                break;
                           }
                       }

                    }
                    break;

                }
           }
          r+=1;
          if(nont.length()!=0)
            totalnum+=nont.length();

    }
   cout<<totalnum<<endl;
   for(int i=0;i<totalnum;i++)
   {
        if(Lr[i].str.size()>0)
        { 
            cout<<Lr[i].nape<<"后继项集"<<i<<Lr[i].later<<endl; 
            for(int p=0;p<Lr[i].str.size();p++)
            {
             sort(Lr[i].str.begin(),Lr[i].str.end());
             Lr[i].str.erase(unique(Lr[i].str.begin(), Lr[i].str.end()), Lr[i].str.end());
             cout<<Lr[i].str[p]<<endl;

            }
        }       
    }
    /*清除相同的项*/
    //cout<<"相同的vector"<<endl;
    for(int i=0;i<totalnum;i++)
    {
        for(int j=0;j!=i,j<totalnum;j++)
        {
            if(j!=i&&Lr[i].str==Lr[j].str)
            {
            /*  cout<<Lr[j].nape<<"后继项集"<<j+1<<endl; 
                //打印相同的项 
            /*  for(int p=0;p<Lr[j].str.size();p++)
                {

                 cout<<Lr[j].str[p]<<endl;

                }*/
                Lr[j].str.clear();
                //totalnum--;
                break;
            }

        }
    } 
    int termnum=0;
    for(int i=0;i<totalnum;i++)
   {
        if(Lr[i].str.size()>0)
        { 
            termnum++;
        }
    }
//  cout<<"项的个数为"<<termnum<<endl;
   /* cout<<"清除相同的vector后的结果:"<<endl; */ 
    //cout<<totalnum<<endl;

    cout<<"项集规范族为:"<<endl; 
    int termID=0;//项的编号
    for(int i=0;i<totalnum;i++)
   {
        bool flag=false;
        if(Lr[i].str.size()>0)
        { 

            //求解后继项 
            nont="";
            for(int l=0;l<Lr[i].str.size();l++)
            {
                for(int j=0;j<Lr[i].str[l].length();j++)
                {
                    if(Lr[i].str[l][j]=='.'&&j+1!=Lr[i].str[l].length())
                    {
                        nont+=Lr[i].str[l][j+1];
                    }
                }
                string ustr(nont);
                sort(ustr.begin(), ustr.end());
                ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
                nont=ustr;
                Lr[i].later=nont;
            }

            if(Lr[i].nape[0]=='#')
            {
                flag=true;
                cout<<termnum-1<<"\t"<<Lr[i].nape<<"后继项集"<<endl;
            }

            if(flag==false)
            {
                cout<<termID++<<"\t";
                cout<<Lr[i].nape<<"后继项集"<<endl;//<<"具体为:"<<Lr[i].later<<endl; 
            }

            for(int p=0;p<Lr[i].str.size();p++)
            {

             cout<<"\t"<<Lr[i].str[p]<<endl;

            }
        }       
    }
}

输入文法:
E::=aA
E::=bB
A::=d
A::=cA
B::=cB
B::=d
#
运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值