zoukankan      html  css  js  c++  java
  • 编译原理算符优先分析

    程序代码如下:

    #include <cstdio>
    #include <set>
    #include <cstdlib>
    #include <cctype>
    #include <functional>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <stack>
    #include <iostream>
    #include <vector>
    #include <map>
    #include <algorithm>
    #define esp 1e-6
    using namespace std;
    const int maxn = 1e5 + 7, mod = 1e9 + 7;
    
    int prio_table[300][300];
    vector<char>VN;
    vector<char>VT;
    bool vis_VN[30];
    bool vis_VT[300];
    bool LL_flag=true;
    void init_visit()
    {
        for(int i=0;i<26;i++)
            vis_VN[i]=true;
        for(int i=0;i<300;i++)
            vis_VT[i]=true; 
            
        for(int i=0;i<300;i++)
            for(int j=0;j<300;j++)
            {
                prio_table[i][j]=-2;
            }  
    }
    
    map<char,vector<string> >mp;//用来存文法 
    
    bool is_VN(char x)//判断是否是非终结符 
    {
        if(x>='A'&&x<='Z')
            return true;
        else
            return false;
    }
    
    bool is_VT(char x)
    {
        return !is_VN(x);
    }
    
    set<char> FIRSTVT(char vnch)
    {
        set<char>ans;
        for(int i=0;i<mp[vnch].size();i++)
        {
            string s=mp[vnch][i];
            if(!is_VN(s[0]))
                ans.insert(s[0]);
            else
            {
                if(s.length()>1)
                    ans.insert(s[1]);
                if(s[0]!=vnch)
                {
                    set<char>ss=FIRSTVT(s[0]);
                    set<char>::iterator it;
                    for(it=ss.begin();it!=ss.end();it++)
                    {
                        ans.insert(*it);
                    }
                }
            }
        }
        return ans;    
    }
    
    set<char> LASTVT(char vnch)
    {
        set<char>ans;
        for(int i=0;i<mp[vnch].size();i++)
        {
            string s=mp[vnch][i];
            int s_end=s.length()-1;
            if(!is_VN(s[s_end]))
            {
                ans.insert(s[s_end]);
            }
            else
            {
                if(s_end>0)
                    ans.insert(s[s_end-1]);
                if(s[s_end]!=vnch)
                {
                    set<char>ss=LASTVT(s[s_end]);
                    set<char>::iterator it;
                    for(it=ss.begin();it!=ss.end();it++)
                    {
                        ans.insert(*it);
                    }
                }
            }
        }
        return ans;    
    }
    
    void show_FIRSTVT()
    {
        for(int i=0;i<VN.size();i++)
        {
            cout<<VN[i]<<" : ";
            set<char>::iterator it;
            set<char>ss=FIRSTVT(VN[i]);
            for(it=ss.begin();it!=ss.end();it++)
            {
                cout<<(*it)<<"  ";
            }
            cout<<endl;    
        }
       
    }
    
    void show_LASTVT()
    {
        cout<<"LASTVT:"<<endl;
        for(int i=0;i<VN.size();i++)
        {
            cout<<VN[i]<<" : ";
            set<char>::iterator it;
            set<char>ss=LASTVT(VN[i]);
            for(it=ss.begin();it!=ss.end();it++)
            {
                cout<<(*it)<<"  ";
            }
            cout<<endl;    
        }
        
    }
    
    void build_prio_table()
    {
        char chf='#';
        set<char>::iterator itf;
        set<char>ss1=FIRSTVT(VN[0]);
        for(itf=ss1.begin();itf!=ss1.end();itf++)
        {
            prio_table[(int)chf][(*itf)]=-1;
        }
        set<char>ss2=LASTVT(VN[0]);
        for(itf=ss2.begin();itf!=ss2.end();itf++)
        {
            
            prio_table[(*itf)][(int)chf]=1;
        }
        prio_table[(int)chf][(int)chf]=0;
        
        
        for(int i=0;i<VN.size();i++)
        {
            for(int j=0;j<mp[VN[i]].size();j++)
            {
                string s=mp[VN[i]][j];
                for(int k=0;k<s.length();k++)
                {
                    if(is_VT(s[k])&&k+1<s.length()&&is_VT(s[k+1]))//...ab...
                        prio_table[s[k]][s[k+1]]=0;
                    if(is_VT(s[k])&&k+2<s.length()&&is_VN(s[k+1])&&is_VT(s[k+2]))//...aNb...
                        prio_table[s[k]][s[k+2]]=0;                    
                    if(is_VT(s[k])&&k+1<s.length()&&is_VN(s[k+1]))//...aN...
                    {
                        set<char>first=FIRSTVT(s[k+1]);
                        set<char>::iterator it;
                        for(it=first.begin();it!=first.end();it++)
                        {
                            prio_table[s[k]][(*it)]=-1;
                        }
                    }
                    if(is_VN(s[k])&&k+1<s.length()&&is_VT(s[k+1]))//...Na...
                    {
                        set<char>last=LASTVT(s[k]);
                        set<char>::iterator it;
                        for(it=last.begin();it!=last.end();it++)
                        {
                            prio_table[(*it)][s[k+1]]=1;
                        }
                    }
                }
            }
        }
        
    }
    
    void show_prio_table()
    {
        cout<<"优先表如下:"<<endl; 
        cout<<" ";
        for(int i=0;i<VT.size();i++)
        printf("%10c",VT[i]);
        cout<<endl;
        for(int i=0;i<VT.size();i++)
        {
            cout<<VT[i];
            for(int j=0;j<VT.size();j++)
            {
                cout<<"         ";
                if(prio_table[VT[i]][VT[j]]==1)
                    cout<<">";
                else if(prio_table[VT[i]][VT[j]]==0)
                    cout<<"=";
                else if(prio_table[VT[i]][VT[j]]==-1) 
                    cout<<"<";
                else
                    cout<<" ";
            }
            cout<<endl;
        } 
    }
    
    set<string>scome;
     
    int main() {
        init_visit(); 
        int k=1;
        char vn;
        string str;
        while(cin>>vn&&vn!='#'&&cin>>str)
        {
            if(vis_VN[vn-'A']==true)//不重复存vn 
            {
                VN.push_back(vn);
                vis_VN[vn-'A']=false;
            }        
            mp[vn].push_back(str);//代表vn可以推导出str
            for(int i=0;i<str.size();i++)
            {
                if(!is_VN(str[i])&&vis_VT[(int)str[i]]==true&&str[i]!='0')
                {
                    VT.push_back(str[i]);
                    vis_VT[(int)str[i]]=false;
                }
            }
            string sf=str;
            for(int i=0;i<sf.length();i++)
            {
                if(is_VN(sf[i]))
                    sf[i]='N';
            }
            scome.insert(sf);  
        }
        VT.push_back('#');
        
        show_FIRSTVT();
        show_LASTVT();
        build_prio_table();
        show_prio_table();
        
        cout<<"input a string"<<endl;
        string checkstr;
        while(cin>>checkstr)
        {
            string stackstr="#";
            checkstr+='#';
            while(stackstr!="#N#")
            {
                cout<<stackstr;
                for(int i=1;i<30-stackstr.length()-checkstr.length();i++)
                    cout<<" ";
                cout<<checkstr<<endl;
                char ch=checkstr[0];
                //无优先关系,error 
                if((is_VN(stackstr[stackstr.length()-1])&&prio_table[stackstr[stackstr.length()-2]][ch]==-2)||(is_VT(stackstr[stackstr.length()-1])&&prio_table[stackstr[stackstr.length()-1]][ch]==-2))
                {
                    cout<<"error"<<endl;
                    break;
                }
                //移入 
                if((is_VT(stackstr[stackstr.length()-1])&&prio_table[stackstr[stackstr.length()-1]][ch]<=0)||(is_VN(stackstr[stackstr.length()-1])&&prio_table[stackstr[stackstr.length()-2]][ch]<=0))
                {
                    stackstr+=ch;
                    checkstr.erase(checkstr.begin());
                }
                else
                {
                    string test="";
                    int strend=stackstr.length()-1;
                    if(is_VN(stackstr[strend]))
                    {
                        strend--;
                    }
                    int j;
                    for(j=strend-1;j>=0;j--)
                    {
                        if(is_VN(stackstr[j]))
                        {
                            j--;
                               if(prio_table[stackstr[j]][stackstr[j+2]]==-1)
                               {
                                   break;
                               }
                        }
                        else
                        {
                            if(prio_table[stackstr[j]][stackstr[j+1]]==-1)
                               {
                                   break;
                               }
                        }
                            
                    }
                    for(int k=j+1;k<stackstr.length();k++)
                        test+=stackstr[k];
                    if(scome.count(test)==0)
                    {
                        cout<<"error"<<endl;
                        break;
                    }
                    stackstr.erase(stackstr.begin()+j+1,stackstr.end());
                    stackstr+='N'; 
                        
                }
            }
            if(stackstr=="#N#")
                cout<<"OK"<<endl;
            cout<<"input a string"<<endl;
        }
        
        return 0;
    }

    样例:

    E E+T
    E E-T
    E T
    T T*F
    T T/F
    T F
    F (E)
    F i
    #
    
    E E+T
    E T
    T T*F
    T F
    F P!F
    F P
    P i
    P (E)
    #
  • 相关阅读:
    jvm2-垃圾回收
    Elasticsearch脑裂问题详细分析以及解决方案
    ThreadLocal原理(基于jdk1.8)
    seata-分布式事务-学习笔记
    Java中的数组
    HAProxy 详细配置说明
    (基础)--- 约数
    (基础)--- Trie树
    Oracle 数据类型对比 不同数据类型对数据空间占用及查询效率影响
    python F score打分
  • 原文地址:https://www.cnblogs.com/eastblue/p/9016954.html
Copyright © 2011-2022 走看看