• 正规文法转正规式(Devc++)代码实现


    就是按照转换规则对string的操作!左线性,右线性通吃!

    参考资料:https://wenku.baidu.com/view/6f1b9e935f0e7cd18425368a.html

    转换规则:

    1.A-xB B->y           A->xy

    2.A->xA   A->y       A->x*y

    3.A->x    A->y         A->x|y

    代码:

    #include<iostream>
    #include<string>
    using namespace std;
    struct WF{
        string left;
        string right;
    };
    void transform(WF *p,int n){
        int i,j,m,flag;
        //合并产生式
        for(i=0;i<n;i++){
            for(int j=i+1;j<n;j++){
                //合并s->aA s->bA ------s->aA|bA
                if(p[i].left==p[j].left&&p[i].right[1]==p[j].right[1]){
                    p[i].right=p[i].right+"|"+p[j].right;
                    p[j].right="";
                    p[j].left="";
                }
                //合并 s->a s->b--------s->a|b
                if(p[i].right.length()==1&&p[j].right.length()==1&&p[i].left==p[j].left){
                    p[i].right=p[i].right+"|"+p[j].right;
                    p[j].right="";
                    p[j].left="";
                }
            }
        }
        //提取公因式 S->aA|bA--------------S->(a|b)A     前面是把right【1】相等的才合并到了一起
        for(i=0;i<n;i++){
            flag=p[i].right.length();
            if(p[i].right.length()>2&&'A'<=p[i].right[1]&&p[i].right[1]<='Z'&&p[i].right[2]=='|'){
                for(j=1;j<flag-1;j=j+3){
                    p[i].right[j]=' ';
                }
                if(j==flag-1){
                    p[i].right="("+p[i].right.substr(0,p[i].right.length()-1)+")"+p[i].right.substr(p[i].right.length()-1);
                }
            }        
        }
        //A->xA|y------------A->x*y
        for(i=0;i<n;i++){
            if(p[i].left[0]==p[i].right[p[i].right.length()-1]&&p[i].right.length()>1){
                for(j=0;j<n;j++){
                if(p[i].left==p[j].left&&j!=i){
                    for(m=0;m<p[j].right.length();m++){
                        if('A'<=p[j].right[m]&&p[j].right[m]<='Z'){
                            break;
                        }
                    }
                    if(m==p[j].right.length()){
                        p[i].right=p[i].right.substr(0,p[i].right.length()-1)+"*"+"("+p[j].right+")";
                        p[j].right="";
                        p[j].left="";
                    }
                }
            }
            }
        }
        //s->zA A->aA ---------s->za*A
        for(i=0;i<n;i++){
            if(p[i].right.length()>1&&p[i].left[0]!=p[i].right[p[i].right.length()-1]){
                for(j=0;j<n;j++){
                    if(p[j].right.length()>1&&p[i].right[p[i].right.length()-1]==p[j].left[0]&&p[j].left[0]==p[j].right[p[j].right.length()-1]){
                        p[i].right=p[i].right.substr(0,p[i].right.length()-1)+p[j].right.substr(0,p[j].right.length()-1)+"*"+p[j].right[p[j].right.length()-1];
                        p[j].right="";
                        p[j].left="";
                    }
                }
            }
        }
        //将表达式右部所有非终结符替换
        flag=n;
        while(flag>=0){
            for(i=0,flag=flag-1;i<n;i++){
                for(j=0;j<p[i].right.length();j++){
                    if('A'<=p[i].right[j]&&p[i].right[j]<='Z'){
                        for(m=0;m<n;m++){
                            if(p[m].left[0]==p[i].right[j]&&m!=i){
                                p[i].right=p[i].right.substr(0,j)+p[m].right+p[i].right.substr(j+1);
                                p[m].left="";
                                p[m].right="";
                                break;
                            }
                        }
                    }
                }
            }
            
        }
        //再次合并左部相等的产生式
        for(i=0;i<n;i++){
            for(j=0;j<n;j++){
                if(p[i].left[0]==p[j].left[0]&&i!=j){
                    if(p[j].right.length()>1){
                        p[i].right=p[i].right+"|"+"("+p[j].right+")";
                        p[j].left="";
                        p[j].right="";
                    }
                    else{
                        p[i].right=p[i].right+"|"+p[j].right;
                        p[j].left="";
                        p[j].right="";
                    }
                }
            }
        }
    }
    int main(){
        int i,j,n;
        string input;
        cout<<"请输入文法产生式个数N"<<endl<<"N=";
        cin>>n;
        WF *p=new WF[n];
        for(int i=0;i<n;i++){
            input.erase();
            cin>>input;
            for(j=0;j<input.length();j++){
                if(input[j]=='-'){
                    p[i].left=input.substr(0,j);
                    p[i].right=input.substr(j+2,input.length());
                }
            }
        }
        transform(p,n);
        for(i=0;i<n;i++)    {
            if(p[i].left[0]!=NULL){
                cout<<p[i].left<<"=";
                for(j=0;j<p[i].right.length();j++){
                    if(p[i].right[j]!=' ')
                    cout<<p[i].right[j];
                }
            }
        }
        cout<<endl;
    }

  • 相关阅读:
    linux centos 8 为.net core 添加进程守护 Supervisor
    vue-quill-editor安装及使用:自定义工具栏和自定义中文字体,把字体写在html的style中
    nginx参数
    k8s pod 挂载glusterfs报错
    Vue跨域问题解决
    CSS导航菜单(二级菜单)
    CSS导航菜单(一级菜单)
    微信小程序开发正常,真机预览模式错误
    uniapp获取用户OpenId及用户详情
    uniapp 获取用户手机号
  • 原文地址:https://www.cnblogs.com/wtx2333/p/12506759.html
Copyright © 2020-2023  润新知