⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 编译原理-算符优先.c

📁 一个程序
💻 C
📖 第 1 页 / 共 2 页
字号:
                                #include <stdio.h>
                                
                                void find_firstvt();


                                struct expression
                                {   char vn;
                                    char vright[15];
                                }expr[15];
                                

                                
                                struct exp_first
                                {
                                char name;
                                char value[15] ;
                                } ;

                                int tablenum=0;
                                char vn[15];
                                char vt[10*15];
                                char rightvn[15];
                                char rightvnlast[15];
                                struct exp_first cando[15];
                                struct exp_first candolast[15];
                                int num;

                                struct exp_first vnname[15];
                                struct exp_first lastvt[15]; //
                                void last();
                                void table();
                                int mysign=0;
                                int sign2=0;
                                int sign3=0;
                                int mysign1=0;
                                int sign4=0;
                                int sign5=0;
                                char fuhaotable[15][15];
                                char newvt[15];
                                
                                main()
                                {
                                int k;
                                int i;
                                char a[10];
                                 int s;
                                int sign=0;
                                int biaoji=0;
                                int t=0;
                                int v=0;
                                int j;

                                printf("*******************************说明*******************************\n");
                                printf("注意!!!!本文法不支持一式含有多个产生式,例如:S->A|b|c\n请输入时将其分解成三个表达式:S->A ;   S->b;   S->c\n");
                                printf("同时,要求输入产生式时,先输入产生式左部,回车后再输入产生式右部 \n");
                                printf("*******************************************************************\n");
                                  printf("请输入你的产生式条数:" );
                                  scanf("%d",&num);

                                for(i=0;i<num;i++)
                                {
                                printf("请输入第%d个产生式的[左部],然后回车:\n",i+1);
                                scanf("%s",&expr[i].vn);
                                printf("  ->");
                                printf("[右部]",i+1);
                                scanf("%s",expr[i].vright);

                             }
                            
                            
                            //存非终结符
                            for(i=0;i<num;i++)
                            {
                            if(expr[i].vn>64&expr[i].vn<91)
                            vn[i]=expr[i].vn;
                            else {  printf("error");
                                    exit(0);}
                            }
                              for(i=0;i<num;i++)
                                    {for(j=0;j<num;j++)
                                    { if((vn[i] ==vn[j] )&&(i<j))
                                              vn[j]=0;
                                              }}
                            
                                //存终结符 以及右部非终结符
                             for(i=0;i<num;i++)
                             {
                             for(j=0;j<10;j++)
                             {
                             for(s=0;s<num;s++)
                             {
                             if((vn[s]==expr[i].vright[j])&&(vn[s]!=NULL)&&(expr[i].vright[j]!=NULL))
                             {biaoji=1;
                              //rightvn
                                rightvn[v]=expr[i].vright[j];
                                rightvnlast[v]=expr[i].vright[j];
                                v++;}
                             }
                            if(biaoji==0)
                             {

                             if(t==0)
                             {
                             vt[t]=expr[i].vright[j];
                             t++;
                              }
                             else
                             {
                             for(k=0;k<t;k++)
                             {
                             if((vt[k]==expr[i].vright[j]))
                              {sign=1; }
                             }
                               if(sign==0)
                                { vt[t]=expr[i].vright[j];
                                 t++;
                                 }
                                sign=0;
                                }
                              }
                                  biaoji=0;
                             }     }
                             

                            find_firstvt(); //输出文法的终结符集,非终结符集
                            xiaolian();     //求各非终结符的FIRSTVT集
                            last();         //求各非终结符的LASTVT集
                             table();        //判定文法是否为算符优先文法,如是,则输出构造出的算符优先关系表
                               }
                               
                               

                      void find_firstvt()    //输出文法的终结符集,非终结符集
                               {
                               int i,j;
                              printf(" *********************本文法中终结符为:***********************************\n");
                               for(i=0;i<15;i++)
                                  {
                                  if(vt[i]!=0)  {
                                  newvt[tablenum]=vt[i];
                                  tablenum+=1;
                                 printf(" %c,",vt[i]);
                                  }
                                 }
                                 printf(" \n");
                                      printf("********* ****************本文法中的非终结符为:**************************\n");
                                      for(i=0;i<15;i++)
                                  {
                                  if(vn[i]!=0)
                                    printf("  %c  ,",vn[i]);

                                 }
                                    printf(" \n");
                                  }//最后的括号



                                  xiaolian( )   //求各非终结符的FIRSTVT集
                                  {
                                  int i,j,k,sign=0,v,a,h,c=0;
                                  int r;
                                  //kaishi
                                  for(i=0;i<num;i++)
                                  {
                                    vnname[i].name=expr[i].vn;


                                  //求出第一个是终结符的表达式的
                                  for(k=0;k<15;k++)
                                  {
                                  if(expr[i].vright[0]==vt[k])
                                   {

                                     vnname[i].value[0] =vt[k];



                                  }           //     求出第一个是终结符的表达式的,结束

                                  if ((expr[i].vright[0]==vn[k])&&(expr[i].vright[1]!=0) )
                                        {
                                         vnname[i].value[0] =expr[i].vright[1];
                                        }   //qiu第二个是终结符的
                                        
                                        if((expr[i].vright[0]==vn[k])&&(expr[i].vright[1]==0))
                                        {
                                               vnname[i].value[0] =vn[k];
                                            } //  qiu 右部只有一个非终结符的
                                        } }    // for的括号
                                  



                                           k=1;

                                  for(i=0;i<num;i++)
                                  {

                                   for(j=0;j<num;j++)
                                   
                                   {
                                         if((vnname[i].name==vnname[j].name)&&(i!=j))
                                  {       vnname[i].value[k]=vnname[j].value[0];
                                         k++;

                                         }
                                    }
                                }

                                
                                //唯一化

                                    for(i=0;i<num;i++)
                                    {for(j=0;j<num;j++)
                                    { if((vnname[i].name==vnname[j].name)&&(i<j))
                                              vnname[j].name=0;
                                              }}
                                              
                                              //rightvn's
                                     for(i=0;i<num;i++)
                                    {for(j=0;j<num;j++)
                                    { if((rightvn[i]==rightvn[j] )&&(i<j))
                                              rightvn[j]=0;
                                              }}
                                    
                                    
                                  //将右部的非终结符转化为终结符
                                    
                                 AA:
                                 sign3=0;
                                     for(i=0;i<num;i++)  {
                                  for(j=0;j<num;j++)
                                    {
                                     if((vnname[i].name==rightvn[j])&&(rightvn[j]!=0))
                                       {
                                        for(k=0;k<15;k++){
                                       for(v=0;v<num;v++){
                                       if((vnname[i].value[k]==vn[v])&&(vn[v]!=0))
                                    {mysign=1; }  }  }

                                    if(mysign==0)
                                    {cando[c].name=vnname[i].name;
                                    for(a=0;a<num;a++)
                                    {if(vnname[i].value[a]!=0)
                                    {cando[c].value[a]=vnname[i].value[a];

                                     }}
                                    r=c;
                                    c++;}
                                         for(h=0;h<num;h++){
                                         if((rightvn[h]==cando[r].name)&&(rightvn[h]!=0))
                                         rightvn[h]=0;}
                                    mysign=0; }}
                                          }

                                    
                                    
                                    for(i=0;i<num;i++){
                                    for(j=0;j<15;j++)
                                    {  for(k=0;k<num;k++){
                                    if((vnname[i].value[j]==cando[k].name)&&(cando[k].name!=0))
                                    {   sign2=1;
                                        }

                                     if(sign2==1){
                                     for(a=0;a<15;a++){
                                     if  (cando[k].value[a]!=0) {
                                     for(h=0;h<15;h++)  {
                                      if((vnname[i].value[h]==cando[k].name)||(vnname[i].value[h]==0))
                                        {vnname[i].value[h]=cando[k].value[a];
                                        break;}}  } }
                                         }
                                         sign2=0;
                                    }}                    }

                                       for(h=0;h<num;h++){
                                       if(rightvn[h]!=0)
                                       sign3=1;}
                                         if(sign3==1)   goto AA;
                                         
                                         //将firstvt唯一化
                                            for(i=0;i<num;i++)
                                    {for(j=0;j<num;j++)
                                    for(k=0;k<15;k++){
                                    { if((vnname[i].value[j]==vnname[i].value[k])&&(j<k))
                                              vnname[i].value[k]=0;
                                              }}       }
                                    
                                    //output
                                    printf("**************************输出firstvt:********************\n");

                                   for(i=0;i<num;i++)
                                   {if(vnname[i].name!=0){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -