编译原理实验——预测分析器详解及代码(2)

实验代码

详解见

https://blog.csdn.net/qq_41735944/article/details/105810232
代码写的有点臃肿,请大家多多包涵

#include
using namespace std;
int n;//输入产生式数
int m1=0;//产生式打开
int m2=0;//集合长度
int m3=0;
int r=0;//jj长度
char zg[100][3];//存直接的左产生式
char zy[100][100];//存直接的右产生式
int jy[100][100];//中间
char fz[100][3];//非终结的集合
char fy[100];//终结集合
char sg[100][3];//存间接的左产生式
char sy[100][100];

char fir[100][100];
char fol[100][100];
char sec[100][100];
int tr[100][100];
char Tr[100][100];
//消直接
int DELz(char g[100][3],char y[100][100],int m)
{
    char flag='3';
    int M=m;
    int ys=0;
    char fl[100][3];
	for(int i=0;i<M;i++)
	{
	    char f[3];
		char *p=strpbrk(y[i],g[i]);
		int zsl=0;
		for(int z=0;z<strlen(y[i]);z++)//排除A->A+a*A
        {
            if(y[i][z]==g[i][0]&&strlen(g[i])==1)//比对E
                zsl++;
            else if(y[i][z]==g[i][0]&&strlen(g[i])==2&&y[i][z+1]=='`')//比对E`
                zsl++;
        }
		if(zsl==1&&p&&strcmp(f,g[i])!=0)//Aa直接左递归
		{
		    fl[ys][0]=g[i][0];
		    fl[ys++][1]='`';
		    strcpy(f,g[i]);
		    for(int z=0;z<M;z++)//对所有A操作
            {
                //g==A
                if(strcmp(g[z],f)==0)//A->Aa===》A'->aA'
                {
                    char *p2=strpbrk(y[z],g[z]);
                    if(p2)
                    {
                        int e=p2-&y[z][0];
                        //新的产生式A1
                        g[m][0]=g[z][0];
                        g[m][1]='`';
                        int q1=0;
                        for(int j=0;j<strlen(y[z]);j++)
                        {
                            if(j!=e)
                            {
                                y[m][q1++]=y[z][j];
                            }
                        }
                        //加上A1
                        y[m][q1++]=g[z][0];
                        y[m][q1++]='`';
                        m++;
                        //删除原式
                        y[z][0]='\0';
                        g[z][0]='\0';
                    }
                    else//A->b==>A->bA'
                    {
                        int w=strlen(y[z]);
                        y[z][w++]=g[z][0];
                        y[z][w++]='`';
                    }
                }
            }
        }
	}
	int m3=m;
	char f[3];
	for(int i=0;i<ys;i++)
    {
        //新的产生式A1->ε
        g[m][0]=fl[i][0];
        g[m][1]='`';
        y[m][0]='$';

        f[0]=fl[i][0];
        f[1]='\0';
        m2++;
        //E'优先级仅此E
        for(int j=0;j<m2;j++)
        {
            if(strcmp(fz[j],f)==0)//找E插入E`
            {
                for(int w=m2;w>j;w--)
                {//全部后移
                    strcpy(fz[w+1],fz[w]);
                }
                strcpy(fz[j+1],g[m]);
            }
        }m++;
    }
    printf("直接——-------\n");
    for(int i=0;i<m;i++)
	{
		if(g[i][0]!='\0')
        {
            printf("%s->%s\n",g[i],y[i]);
            strcpy(sy[i],y[i]);
        }
	}
//    for(int i=0;i
//    {
//        printf("fz=%s\n",fz[i]);
//    }
	return m;
}
//消间接
void BECj()
{
    //临时数组

	for(int j=0;j<m2;j++)
	{
		int r=1;//jy内循环
		jy[j][0]=0;
		for(int i=0;i<m1;i++)
		{
    		if(strcmp(zg[i],fz[j])==0)
    		{
    		    jy[j][0]++;
    			jy[j][r++]=i+1;
			}
		}
	 }
	 int zs=1;
	 for(int i=0;i<m2;i++)
	{
	    zs*=jy[i][0];
	 }
    for(int i=m2-1;i>=0;i--)
    {
        int zs=jy[i][0];
        for(int j=1;j<=zs;j++)
        {//防止死循环
            char k[100];
            strcpy(k,zy[jy[i][j]-1]);
        	int q=i+1;
        	{
        	    char *p=strpbrk(k,fz[q]);
        	    int e=p-&k[0];
                if(p)
                {
                    int u=strlen(zy[jy[i][j]-1]);
                    for(int w=1;w<=jy[q][0];w++)
                    {
                        if(jy[i][j]!=0&&jy[q][w]!=0)
                        {
                            int t=0;
                            //拼装
                            for(int z=0;z<e;z++)
                            {
                                zy[m1][t++]=zy[jy[i][j]-1][z];
                            }
                            for(int z=0;z<strlen(zy[jy[q][w]-1]);z++)
                            {
                                zy[m1][t++]=zy[jy[q][w]-1][z];
                            }
                            for(int z=e+1;z<u;z++)
                            {
                                zy[m1][t++]=zy[jy[i][j]-1][z];
                            }
                            //链接
                            jy[i][0]++;
                            jy[i][jy[i][0]]=m1+1;
                            m1++;
                        }
					}
					jy[i][j]=0;
				}
			}
		}
    }
    //间接
    for(int i=0;i<m2;i++)
    {
        for(int j=1;j<=jy[i][0];j++)
        {
            if(jy[i][j]!=0)
            {
                strcpy(sg[m3],fz[i]);
                strcpy(sy[m3],zy[jy[i][j]-1]);
                m3++;
            }
		}
    }
    printf("间接-------------\n");
    for(int i=0;i<m3;i++)
    {
        printf("%s->%s\n",sg[i],sy[i]);
    }
    m3=DELz(sg,sy,m3);
}

void Fir(char g[100][3],char y[100][100],int m)
{
    //first集
    set<char> st;
    set<char>::iterator ji;
    int uy=0;
    for(int z=0;z<m2;z++)
    {
        st.clear();
        for(int i=0;i<m;i++)
        {
            char fl[2];
            fl[0]=y[i][0];
            fl[1]=y[i][1];
            if(strcmp(g[i],fz[z])==0)
            {
                if(y[i][0]>=65&&y[i][0]<=95)//终结符
                {

                    for(int j=0;j<m2;j++)
                    {
                        if((y[i][0]==fz[j][0])&&(y[i][1]!='`')&&(strlen(fz[j])==1))//E E
                        {
                            char a=j+48;
                            st.insert(a);
                            uy++;
                        }
                        else if((y[i][0]==fz[j][0])&&(y[i][1]=='`')&&(strlen(fz[j])==2)){//E` E`
                            char a=j+48;
                            st.insert(a);
                            uy++;
                        }
                    }
                }
                else{
                    st.insert(y[i][0]);
                }
            }
            if(i==m-1)
            {
                int tz=0;
                for(ji=st.begin();ji!=st.end();++ji)
                {
                    fir[z][tz++]=*ji;
                }
            }
        }
    }
    for(int hy=0;hy<uy;hy++)
    {
        for(int i=0;i<m2;i++)
        {
            st.clear();
            int rl=strlen(fir[i]);
            for(int j=0;j<rl;j++)
            {
                if(fir[i][j]<=57&&fir[i][j]>=48)
                {
                    for(int z=0;z<rl;z++)
                    {
                        if(z!=j)
                        st.insert(fir[i][z]);
                    }
                    for(int z=0;z<strlen(fir[fir[i][j]-48]);z++)
                    {
                        st.insert(fir[fir[i][j]-48][z]);
                    }
                }
            }
            int zj=0;
            for(ji = st.begin() ; ji != st.end() ; ++ji)
                fir[i][zj++]=*ji;
        }
    }
    printf("first---------\n");
    for(int i=0;i<m2;i++)
    {
        printf("%s\t",fz[i]);
        for(int j=0;j<strlen(fir[i]);j++)
            printf("%c ",fir[i][j]);
        printf("\n");
    }
}

void Fol(char g[100][3],char y[100][100],int m)
{
    set<char> st;
    set<char>::iterator ij;
    st.insert('#');
    for(int i=0;i<m2;i++)
    {
        for(int j=0;j<m;j++)
        {
            char *p=strpbrk(y[j],fz[i]);
            int e=p-&y[j][0];
            if(p)
            {
                int b=0;
                for(int w=0;w<m2;w++)
                {
                    if(strcmp(fz[w],g[j])==0)
                    {
                        b=w;
                        break;
                    }
                }
                for(int q=e+1;q<strlen(y[j]);q++)
                {
                    if(strlen(fz[i])==1&&y[j][e+1]!='`')//EE
                    {
                        char a1=b+48;
                       if(i!=0&&i!=b)
                        st.insert(a1);
                        if(e+1==strlen(y[j]))
                        {
                            st.insert('#');
                            break;
                        }
                        if((y[j][q]>90||y[j][q]<65)&&y[j][q]!='`')//->Aa
                        {
                            st.insert(y[j][q]);
                        }
                        else if(y[j][q]<=90&&y[j][q]>=65&&y[j][q+1]!='`')//->AB
                        {
                            for(int w=0;w<m2;w++)
                            {
                                if(fz[w][0]==y[j][q])
                                {
                                    for(int er=0;er<strlen(fir[w]);er++)
                                    {
                                        if(fir[w][er]!='$')
                                        st.insert(fir[w][er]);
                                    }
                                    break;
                                }
                            }
                        }
                        else if(y[j][q]<=90&&y[j][q]>=65&&y[j][q+1]=='`')//->AB`
                        {
                            for(int w=0;w<m2;w++)
                            {
                                if(fz[w][0]==y[j][q]&&fz[w][1]=='`')
                                {
                                    for(int er=0;er<strlen(fir[w]);er++)
                                    {
                                        if(fir[w][er]!='$')
                                        st.insert(fir[w][er]);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    else if(strlen(fz[i])==2&&y[j][e+1]=='`')//E1E1
                    {
                        char a1=b+48;
                        if(i!=0&&i!=b)
                        st.insert(a1);
                        if(e+2==strlen(y[j]))
                        {
                            st.insert('#');
                            break;
                        }
                        if((y[j][q+1]>90||y[j][q+1]<65)&&y[j][q+1]!='`')//->Aa
                        {
                            st.insert(y[j][q+1]);
                        }
                        else if(y[j][q+1]<=90&&y[j][q+1]>=65&&y[j][q+2]!='`')//->A`B
                        {
                            for(int w=0;w<m2;w++)
                            {
                                if(fz[w][0]==y[j][q+1])
                                {
                                    //链接到first[w]
                                    for(int er=0;er<strlen(fir[w]);er++)
                                    {
                                        if(fir[w][er]!='$')
                                        st.insert(fir[w][er]);
                                    }
                                    break;
                                }
                            }
                        }
                        else if(y[j][q+1]<=90&&y[j][q+1]>=65&&y[j][q+2]=='`')//->A`B`
                        {
                            for(int w=0;w<m2;w++)
                            {
                                if(fz[w][0]==y[j][q+1]&&fz[w][1]=='`')
                                {
                                    for(int er=0;er<strlen(fir[w]);er++)
                                    {
                                        if(fir[w][er]!='$')
                                        st.insert(fir[w][er]);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        int zj=0;

        for(ij = st.begin(); ij != st.end(); ij++)
        {
            fol[i][zj++]=*ij;
        }
        st.clear();
    }
        for(int i=0;i<m2;i++)
        {
            for(int j=0;j<strlen(fol[i]);j++)
            {
                st.clear();
                if(fol[i][j]<=57&&fol[i][j]>=48)
                {
                    for(int z=0;z<strlen(fol[i]);z++)
                    {
                        if(z!=j)
                            st.insert(fol[i][z]);
                    }
                    for(int z=0;z<strlen(fol[fol[i][j]-48]);z++)
                    {
                        st.insert(fol[fol[i][j]-48][z]);
                    }
                }
                else{
                    for(int z=0;z<strlen(fol[i]);z++)
                    {
                        st.insert(fol[i][z]);
                    }
                }
                int zj=0;
                for(ij = st.begin() ; ij != st.end() ; ++ij)
                    fol[i][zj++]=*ij;
                fol[i][st.size()]='\0';
            }

        }
//    }
    printf("follow--------\n");
    for(int i=0;i<m2;i++)
    {
        printf("%s\t",fz[i]);
        for(int j=0;j<strlen(fol[i]);j++)
            printf("%c ",fol[i][j]);
        printf("\n");
    }

}

void Sec(char g[100][3],char y[100][100],int m)
{
    set<char> st;
    set<char>::iterator ij;
    for(int i=0;i<m;i++)
    {
        if(y[i][0]=='$')
        {
            int dg=0;
            for(int j=0;j<m2;j++)
            {//哪一个非终结符
                if(g[i][1]!='`'&&g[i][0]==fz[j][0]&&strlen(fz[j])==1)
                {
                    dg=j;break;
                }
                else if(g[i][1]=='`'&&g[i][0]==fz[j][0]&&strlen(fz[j])==2){
                    dg=j;break;
                }
            }
            for(int j=0;j<strlen(fol[dg]);j++)
            {
                sec[i][j]=fol[dg][j];
            }
        }
        else if(y[i][0]>90||y[i][0]<65)//终结符
        {
            sec[i][0]=y[i][0];
        }
        else{//非终结符
            int df=0;
            for(int j=0;j<m2;j++)
            {//哪一个非终结符
                if(y[i][1]!='`'&&y[i][0]==fz[j][0]&&strlen(fz[j])==1)
                {
                    df=j;break;
                }
                else if(y[i][1]=='`'&&y[i][0]==fz[j][0]&&strlen(fz[j])==2){
                    df=j;break;
                }
            }
            char fg[3];
            fg[0]='#';
            char *p=strpbrk(fir[df],fg);
            if(p)
            {
                st.clear();
                int dg=0;
                for(int j=0;j<m2;j++)
                {//哪一个非终结符
                    if(g[i][1]!='`'&&g[i][0]==fz[j][0]&&strlen(fz[j])==1)
                    {
                        dg=j;break;
                    }
                    else if(g[i][1]=='`'&&g[i][0]==fz[j][0]&&strlen(fz[j])==2){
                        dg=j;break;
                    }
                }
                for(int j=0;j<strlen(fir[df]);j++)
                {
                    st.insert(fir[df][j]);
                }
                for(int j=0;j<strlen(fol[dg]);j++)
                {
                    st.insert(fol[dg][j]);
                }
                int zj=0;
                for(ij = st.begin() ; ij != st.end() ; ++ij)
                    sec[i][zj++]=*ij;
            }
            else{
                for(int j=0;j<strlen(fir[df]);j++)
                {
                    sec[i][j]=fir[df][j];
                }
            }
        }
    }
//    输出select集
//    printf("select--------\n");
//    for(int i=0;i
//    {
//        if(g[i][0]!='\0')
//        printf("%s\t->%s\t\t\t%s\n",g[i],y[i],sec[i]);
//    }
}

int LL(char g[100][3],char y[100][100],int m)
{
    printf("文法判断-----------\n");
    int a[200];
    for(int i=0;i<m2;i++)
    {
        memset(a,0,sizeof(a));
//        for(int j=0;j<200;j++)
//            printf("%d   %d\n",j,a[j]);
        for(int j=0;j<m;j++)
        {
            if(strcmp(fz[i],g[j])==0)
            {
                for(int z=0;z<strlen(sec[j]);z++)
                {
                    a[sec[j][z]]++;
                    if(a[sec[j][z]]>=2) return 2;
                }
            }
        }
    }
    return 0;
}
void table(char g[100][3],char y[100][100],int m)
{
    set<char> st;
    set<char>::iterator ji;
    for(int i=0;i<m2;i++)//终结符集合
    {
        for(int j=0;j<strlen(fol[i]);j++)
            st.insert(fol[i][j]);
        for(int j=0;j<strlen(fir[i]);j++)
            if(fir[i][j]!='$') st.insert(fir[i][j]);
    }
    printf("预测分析表---------\n\t");
    int zl=0;
    for(ji=st.begin();ji!=st.end();++ji)
    {
       cout << * ji << "\t";
       fy[zl++]=*ji;
    }
    printf("\n");
    for(int i=0;i<strlen(fy);i++)
    {
        for(int j=0;j<m;j++)
        {
            char ft[3];     ft[0]=fy[i];
            char *p=strpbrk(sec[j],ft);
            if(p)
            {
                for(int z=0;z<m2;z++)
                if(strcmp(g[j],fz[z])==0)
                {
                    tr[z][i]=j+1;
                }
            }
        }
    }
    for(int i=0;i<m2;i++)
    {
        printf("%s\t",fz[i]);
        for(int j=0;j<strlen(fy);j++)
        {
            printf("%s\t",y[tr[i][j]-1]);
        }
    printf("\n");
    }
}

void print_process1(stack<int> ss)
{
    while(!ss.empty())
   {
         cout << fy[ss.top()];
         ss.pop();
   }
}
void print_process2(stack<char> ss)
{
    while(!ss.empty())
   {
          cout << ss.top();
         ss.pop();
   }
}

void analysis(char g[100][3],char y[100][100],int m)
{
    char ad[100];
    printf("输入串:\n");
    gets(ad);
    stack<int>  se;
    stack<char>  st;
    int sl;
    int pr[100];
    for(int i=strlen(ad)-1;i>=0;i--)
    {
        for(int j=0;j<strlen(fy);j++)
        {
            if(ad[i]==fy[j])
                se.push(j);
            else if(fy[j]=='#')
                sl=j;
        }
    }
    st.push('#');
    st.push(fz[0][0]);
    int ry=0;
    for(int we=0;we<12;we++)
    {
        char er;
        for(int i=0;i<m2;i++)
        {
            if(st.top()=='#')
                break;
            if(st.top()==fy[se.top()])
            {

                st.pop(); se.pop();
                print_process1(se);
                printf("\t");
                print_process2(st);
                printf("\n");
            }
            else if(st.top()=='$')
            {
                st.pop();
                print_process1(se);
                printf("\t");
                print_process2(st);
                printf("\n");
            }
            if(st.top()==fz[i][0])
            {
                er=st.top();
                st.pop();
                if(st.top()=='`'&&strlen(fz[i])==2)
                {
                    st.pop();
                    if(tr[i][se.top()]>=1)
                    {
                        for(int j=strlen(y[tr[i][se.top()]-1])-1;j>=0;j--)
                        {
                            char sd=y[tr[i][se.top()]-1][j];
                            st.push(sd);
                        }
                        pr[ry++]=tr[i][se.top()]-1;
                        print_process1(se);
                        printf("\t");
                        print_process2(st);
                        printf("\n");
                    }
                    else if(tr[i][se.top()]==0){
                        st.pop();
                        for(int j=strlen(y[tr[i][sl]-1])-1;j>=0;j--)
                        {
                            char sd=y[tr[i][sl]-1][j];
                            st.push(sd);
                        }
                        pr[ry++]=tr[i][sl]-1;
                        print_process1(se);
                        printf("\t");
                        print_process2(st);
                        printf("\n");
                    }
                }
                else if(st.top()!='`'&&strlen(fz[i])==1)
                {
                    if(tr[i][se.top()]>=1)
                    {
                        for(int j=strlen(y[tr[i][se.top()]-1])-1;j>=0;j--)
                        {
                            char sd=y[tr[i][se.top()]-1][j];
                            st.push(sd);
                        }
                        pr[ry++]=tr[i][se.top()]-1;
                        print_process1(se);
                        printf("\t");
                        print_process2(st);
                        printf("\n");
                    }
                    else if(tr[i][se.top()]==0){
                        st.pop();
                        for(int j=strlen(y[tr[i][sl]-1])-1;j>=0;j--)
                        {
                            char sd=y[tr[i][sl]-1][j];
                            st.push(sd);
                        }
                        pr[ry++]=tr[i][sl]-1;
                        print_process1(se);
                        printf("\t");
                        print_process2(st);
                        printf("\n");
                    }
                }
                else
                    st.push(er);
            }
        }
    }
}

int judBD(int b,int step,char f,char z)
{
	int er;
	if(step==0)
		return 1;
    for(int i=b%m1;i<4*m1;i++)
    {
     	if(zg[i][0]==z)
		{
			for(int j=0;j<m2;j++)
			{
				if(zy[i][0]==fz[j][0]&&fz[j][0]!=z)
				{
					z=fz[j][0];
					if(z==f)
						return 8;
					return judBD(++b,--step,f,z);
				}
			}	return judBD(++b,--step,f,z);
		}
    }
    return 0;
}


int main()
{
	printf("请输入产生式个数:\n");
	scanf("%d",&n);
	getchar();

	for(int i=0;i<n;i++)
	{
		char a[100];
		gets(a);
//		printf("%s\n",a);
		zg[m1][0]=a[0];//左
		fz[m2++][0]=a[0];
		//右
		int q=0;
		for(int j=3;j<=strlen(a);j++)
		{
			if(a[j]!='|')
			{
				zy[m1][q]=a[j];
				q++;
			}
			else{
				m1++;
				q=0;
				zg[m1][0]=a[0];
			}
		}
		m1++;
	}
	printf("------------\n");
	for(int i=0;i<m1;i++)
	{
		printf("%s=>%s\n",zg[i],zy[i]);
	}
	int o=6,zv=0;
	for(int i=0;i<m2;i++)
	{
		o=judBD(0,10,fz[i][0],fz[i][0]);//i,j,step,goal,now
		if(o==8)
            zv=1;
	}
    if(zv==1)
    {
        BECj();
        Fir(sg,sy,m3);
        Fol(sg,sy,m3);
        Sec(sg,sy,m3);
        if(LL(sg,sy,m3)==2) printf("该文法不是为LL(1)文法\n");
        else{
        printf("该文法是为LL(1)文法\n");
        table(sg,sy,m3);
        analysis(sg,sy,m3);
        }
    }

    else
    {
        m1=DELz(zg,zy,m1);
        Fir(zg,zy,m1);
        Fol(zg,zy,m1);
        Sec(zg,zy,m1);
        if(LL(zg,zy,m1)==2) printf("该文法不是为LL(1)文法\n");
        else    {
        printf("该文法是为LL(1)文法\n");
        table(zg,zy,m1);
        analysis(zg,zy,m1);
        }
    }

	system("pause");
}

你可能感兴趣的:(编译原理)