编译原理预测分析法

预测分析法基本思路求解first集合和follow集合,之后构造预测分析表,用到的结构体为GRAM,其中包含该非终结符a以及其对应的first和follow,输入格式如下(以#结束输入)
E::=TE’
E’::=+TE’|ε
T::=FT’
T’::=*FT’|ε
F::=(E)|i
#

#include<bits/stdc++.h>
using namespace std;
//判断终结符和非终结符 返回1是非终结符 返回0是终结符 
int Norterminal(char c)
{
    if(c>='A'&&c<='Z') 
        return 1;
    else if(c!=':'&&c!='='&&c!='<'&&c!='>'&&c!=' '&&c!='|') 
        return 0; 
    else
        return -1; 
}  
struct GRAM
{
    //$代表空 
    string  a;
    string first;
    string follow;
};
struct LIST
{
    int num;
    string s;
};
int main()
{
    GRAM gram[50]; 
    string grammer; 
    cout<<"请输入文法(以#结束)"<<endl;
    std::vector<string> strN;
    cin>>grammer;//输入规则 
    strN.push_back(grammer); 
    int num=1; //文法个数 


    char str[10][80];  
    const char *ch = "|";  
    char *result;  
    vector<string> strN1;  //存处理过“|”规则的 

    for(int i=0;i<grammer.length();i++)
    {
        str[0][i]=grammer[i];
    } 
    for(int h=grammer.length();h<80;h++)
    {
            str[0][h]=NULL;
    }
    result = strtok(str[0],ch);  
    while(result!=NULL)  
    {  
        strN1.push_back(result);  
        result = strtok(NULL,ch);  
    }  
    for(int i=1;grammer!="#";i++)
    {
        cin>>grammer;
        strN.push_back(grammer); 
        num++; 
        /*处理转换的规则形式输入部分*/
        for(int h=0;h<grammer.length();h++)
        {
            str[i][h]=grammer[h];
        } 
        for(int h=grammer.length();h<80;h++)
        {
            str[i][h]=NULL;
        }
        result = strtok(str[i],ch);  
        while(result!=NULL)  
        {  
            strN1.push_back(result);  
            result = strtok(NULL,ch);  
        }  
    } 
    int count=0;

    /*
    获取first集合 
    */
    //直接获取first终结符 
    for(unsigned i=0;i<strN.size();i++)
    {
        gram[i].a=strN[i][0];
        gram[i].first="";
        if(!Norterminal(strN[i][4]))
        {
            gram[i].first=strN[i][4];
        }
        for(unsigned k=5;k<strN[i].length()&&k+1<strN[i].length();k++)
        {
            if(strN[i][k]=='|')
            {
                if(!Norterminal(strN[i][k+1]))
                {
                    gram[i].first+=strN[i][k+1];
                }
            }
        } 

    } 
    for(unsigned i=0;i<strN.size();i++)
    {
        if(gram[i].first!="")
            count++;

    } 
    //当第一个字符是非终结符时 
    while(count!=num)
    {
        for(unsigned i=0;i<strN.size();i++)
        {
            for(unsigned k=0;k<strN.size();k++)
            {
                    if(gram[k].a[0]==strN[i][4]&&gram[k].first!=""&&k!=i&&gram[i].first=="")
                   {
                        gram[i].first=gram[k].first; 
                        count++; 
                        break;
                    }        

            }

        } 
    }   
    //打印显示对应关系 
    cout<<"first集合为:"<<endl; 
    for(unsigned i=0;i<strN.size();i++)
    {

        cout<<gram[i].a<<" "<<gram[i].first<<endl;
    }
    /*
    获取follow集合 
    */
    gram[0].follow="#";
    for(unsigned i=1;i<strN.size();i++)
    {
        gram[i].follow=""; 
    }
    //求显而易见的follow 
    for(unsigned i=0;i<strN.size();i++)
    {
        for(unsigned k=0;k<strN.size();k++)
        {
            for(int j=4;j<strN[k].length();j++)
            {
                if(gram[i].a[0]==strN[k][j])
                {
                    if(!Norterminal(strN[k][j+1]))
                    {
                        gram[i].follow+=strN[k][j+1];
                    }
                    else
                    {
                        for(unsigned l=0;l<strN[k].size();l++)
                        {
                            if(strN[k][j+1]==gram[l].a[0])
                            {
                                gram[i].follow+=gram[l].first;

                            }
                        }

                    } 
                }
            }
        }
    }
    //删除first中的$ 
    for(unsigned i=0;i<strN.size();i++)
    {

        if(gram[i].follow!="")
        {
            for(int k=0;k<gram[i].follow.length();k++)
            {
                if(gram[i].follow[k]=='$')
                {
                    gram[i].follow[k]=NULL; 
                }
                if(gram[i].follow[k]==NULL)
                {
                    gram[i].follow.erase(gram[i].follow.begin()+k);
                }
            }
        }
    }
    //求该符号后边是非终结符且非终结符可以为空 
    for(unsigned i=0;i<strN.size();i++)
    {
        if(gram[i].a[0]==strN[i][0])
        {

            if(strN[i].find('|')==-1)
            {
                for(unsigned k=0;k<strN.size();k++)
                {
                    if(strN[i][strN[i].length()-1]==strN[k][0])
                    {
                        if(strN[k].find('$'))
                        {
                           for(unsigned l=0;l<strN.size();l++)
                           {
                               if(strN[i][strN[i].length()-2]==strN[l][0])
                               {
                                    gram[l].follow+=gram[i].follow;
                                    //去相同的符号 
                                    string ustr(gram[l].follow);
                                    sort(ustr.begin(), ustr.end());
                                    ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
                                    gram[l].follow=ustr;         
                                }
                           }

                        }
                    }


                }
            }
            else
            {
                for(int j=4;j<strN[i].length()&&j-1>=0;j++)
                {

                    if(strN[i][j]=='|')
                    {
                        if(Norterminal(strN[i][j-1]))
                        {
                            gram[j-1].follow+=gram[i].follow;
                            string ustr(gram[j-1].follow);
                            sort(ustr.begin(), ustr.end());
                            ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
                            gram[j-1].follow=ustr;  
                        }
                    }

                }
            }

        } 

    }
    for(unsigned i=0;i<strN.size();i++)
    {
        if(gram[i].a[0]==strN[i][0])
        {
            if(strN[i].find('|')==-1)
            {
                if(Norterminal(strN[i][strN[i].length()-1]))
                {
                     for(unsigned l=0;l<strN.size();l++)
                     {
                        if(strN[i][strN[i].length()-1]==strN[l][0])
                        {
                            gram[l].follow+=gram[i].follow;
                            //去相同的符号 
                            string ustr(gram[l].follow);
                            sort(ustr.begin(), ustr.end());
                            ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
                            gram[l].follow=ustr;         
                        }
                    }
                }
            } 
        }
    }

    cout<<"follow集合为:"<<endl; 
    for(unsigned i=0;i<strN.size();i++)
    {
        cout<<gram[i].a<<" "<<gram[i].follow<<endl;
    }
    string term="";
    string nonterm="";
    cout<<"终结符和#为:"<<endl;
    for(unsigned i=0;i<strN.size();i++)
    {
        for(int j=0;j<strN[i].length();j++)
        {
            if(!Norterminal(strN[i][j])&&strN[i][j]!='$')
               term+=strN[i][j];
        }
        string ustr(term);
        //sort(ustr.begin(), ustr.end());
        ustr.erase(unique(ustr.begin(), ustr.end()), ustr.end() );
        term=ustr;
    }
    cout<<term<<endl;
    cout<<"非终结符为:"<<endl;
    for(unsigned i=0;i<strN.size();i++)
    {
        if(strN[i][0]!='#')
            nonterm+=strN[i][0];
    }
    cout<<nonterm<<endl;
    /*转换规则形式*/
    cout<<"转换后的规则形式为:"<<endl; 
    LIST listgram[strN1.size()];
    int listnumber =0; 
    for(unsigned i=0;i<strN1.size()&&i-1>=0;i++)
    {

        if(strN1[i].find("::")==-1)
        {
            string add="";
            add=add+strN1[i-1][0]+"::="+strN1[i];
            strN1[i]=add;

        }   
        cout<<strN1[i]<<endl;
        listgram[i].s=strN1[i];
        listgram[i].num=i;
        listnumber++; 
    }

    /*构造预测分析表*/
    int list[nonterm.length()][term.length()];
    for(int i=0;i<nonterm.length();i++)
    {
        for(int j=0;j<term.length();j++)
        {
             list[i][j]=-1; 
        }   
    } 
    for(unsigned i=0;i<strN1.size()-1;i++)
    {
        if(strN1[i][4]!='$')
        {
            if(Norterminal(strN1[i][4]))
            {
                for(unsigned k=0;k<strN.size();k++)
                {
                    for(unsigned f=0;f<strN.size();f++) 
                        if(strN1[i][0]==gram[f].a[0]) 
                        { 
                            if(strN1[i][4]==gram[k].a[0])//比较E::=TG  比较T的 
                            {
                                for(int l=0;l<gram[k].first.length();l++)
                                {
                                    for(int h=0;h<term.length();h++)
                                    {
                                        if(gram[k].first[l]==term[h])
                                        {
                                            list[f][h]=i;
                                        }
                                    }
                                }
                            }
                    } 
                }
            }
            else    
            {

                for(unsigned k=0;k<strN.size()&&k-1>=0;k++)
                {
                    for(unsigned f=0;f<strN.size();f++) 
                        if(strN1[i][0]==gram[f].a[0]) 
                        { 
                            if(strN1[i][0]==gram[k].a[0])
                            {
                                for(int h=0;h<term.length();h++)
                                {
                                    if(strN1[i][4]==term[h])
                                    {
                                        list[f][h]=i;
                                    }
                                }
                            }
                        } 
                }
            }
        }
        else
        {
             for(unsigned k=0;k<strN.size()&&k-1>=0;k++)
             { 
                    if(strN1[i][0]==gram[k].a[0]) 
                    {
                        for(int l=0;l<gram[k].follow.length();l++)
                        {
                            for(int h=0;h<term.length();h++)
                            {
                                if(gram[k].follow[l]==term[h])
                                {
                                    list[k][h]=i;
                                }
                            }
                        }   
                    } 
             }

        } 
    }
    cout<<"预测分析表为:"<<endl;
    for(int i=0;i<nonterm.length();i++)
    {
        for(int j=0;j<term.length();j++)
        {
              cout<<list[i][j]<<" "; 
        }   
        cout<<endl; 
    } 
    int k1; 
        //cout<<listgram[i].s<<endl; 
    cout<<"    |";
    for(int i=0;i<term.length();i++)
    {
        //cout<<"  "<<term[i]<<" " ; 
    //  printf("%5c",term[i]);
    cout<<setw(10)<<term[i];
        cout<<"|";
    }
    cout<<endl; 
     cout<<"____________________________________________________________________________"<<endl;

    //cout<<" "<<nonterm[0]<<" ";

    for(int i=0;i<nonterm.length();i++)
    {
        printf("%2c",nonterm[i]);
        cout<<"  "<<"|";
            for(int j=0;j<term.length();j++)
            {
                 //cout<<" "<<nonterm[h]<<" ";
                for(k1=0;k1<listnumber-1;k1++)
                {
                    if(list[i][j]==listgram[k1].num) 
                    {
                        cout<<setw(10)<<listgram[k1].s<<"|"; 
                    //  printf("%7s  ",listgram[k1].s);
                        break; 
                    }

                }
                if((listnumber-1)==k1) 
                     cout<<setw(11)<<"|"; 


           }   
            cout<<endl; 
          cout<<"____________________________________________________________________________"<<endl;
    } 

} 

其中G代表E’ H代表T’ J代表F’。运行结果如下:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/yangyangcome/article/details/80313192