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

📄 lr(1).cpp

📁 LR(1)分析器文法分析程序
💻 CPP
字号:
/*
  Name: LR(1)分析器的构造 
  Author: wangrui 
  Date: 07-06-07
  Description: 输入文法,构造出相应的LR(1)分析器 
*/
#include"iostream"
using namespace std;


char G[20][20];     //use a matrix to store grammar G
int  length[20];    //length use to store each formula's length
int  number = 0;
bool tempofinput[150];  //buffer of input
char str_vn[20];        //put all vn into it
int  size_vn = 0;       
char str_vt[150];       //put all vt into it
int  size_vt = 0;
bool first_vn[30][150];
char buffer[50];            //用来存放生成LR(1) 项目集时需要的first_set 
int  bsize = 0;
struct thri{
    int beg;
    int nex;
    char ch;
};
thri trans[200];
int  size_trans = 0;

/*
定义项目集的形式 
*/
struct proj{
    int formula_numb;
    int part;
    char expc;
};

proj    items[100][100];
int     Ccount = 0;
int     size_item[100];

void Read_G()
{
	int i;
    cin >> number;   //user should give the number of formula first
    for(i = 1; i <= number; i++){
        char temp;
        int j = 0;
        cin >> temp;
        while(temp != '$'){
            tempofinput[temp] = true;
            G[i][j++] = temp;
            cin >> temp;
        }
        length[i] = j;
    }
    
    G[0][0] = 'S';
    G[0][1] = G[1][0];
    length[0] = 2;
    
    for( i = 0; i < 64; i++)
        if(tempofinput[i])
           str_vt[size_vt++] = i;
    for( i = 91; i < 128; i++)
        if(tempofinput[i])
           str_vt[size_vt++] = i;
    for( i = 65; i < 91; i++)
        if(tempofinput[i])
           str_vn[size_vn++] = i;
    /*for(int i = 0; i < size_vn; i++)
        cout << str_vn[i] << ";";
    cout << endl << endl;
    cout << "size:" << size_vt << endl;
    for(int i = 0; i < size_vt; i++)
        cout << str_vt[i] << ";";
    cout << endl;
    */
    
}

void get_first(){
	int k;
    bool flag1;
    do{ 
        flag1 = false;
        for(int i = 1; i <= number; i++){
           int t = 1;
           bool flag2 = false;
           do{
               flag2 = false;
               if (G[i][t] >= 'A' && G[i][t] <= 'Z'){
                      for( k = 0; k < 64; k++)
                          if(first_vn[G[i][t]-'A'][k] == true && !first_vn[G[i][0]-'A'][k]){
                             first_vn[G[i][0]-'A'][k] = true;
                             flag1 = true;
                          }
                      for(k = 91; k < 128; k++)
                          if(first_vn[G[i][t]-'A'][k] == true && !first_vn[G[i][0]-'A'][k]){
                             first_vn[G[i][0]-'A'][k] = true;
                             flag1 = true;
                          }
                      if(first_vn[G[i][t]-'A'][64] == true){
                          t++;
                          flag2 = true;
                      }
                }
                else if(!first_vn[G[i][0]-'A'][ G[i][t] ]){
                      first_vn[G[i][0]-'A'][ G[i][t] ] = true;
                      flag1 = true;
                }
           }while(flag2 && t < length[i]);
           if(t == length[i])
                first_vn[G[i][0]-'A'][26] = true;
        }
        
    }while(flag1);
}
/*j判断项目数否在项目集里*/
bool is_in(proj temp,int T){
    for(int i = 0; i < size_item[T]; i++)
        if(temp.formula_numb == items[T][i].formula_numb && temp.part == items[T][i].part && temp.expc == items[T][i].expc)
                return true;
    return false;
}

void  gete_expc(proj temp){
	int i;
    bsize = 0;    
    bool flag;
    int tt = temp.part;
    do{
        flag = false;
        if(tt+1 >= length[temp.formula_numb]){
                buffer[bsize++] = temp.expc;
                return;
        }
        else if(G[temp.formula_numb][tt+1] < 'A' || G[temp.formula_numb][tt+1] > 'Z'){
                buffer[bsize++] = G[temp.formula_numb][tt+1];
                return;
        }    
        else if(G[temp.formula_numb][tt+1] >= 'A' && G[temp.formula_numb][tt+1] <= 'Z'){
                for( i = 0; i < 64; i++){
                   if(first_vn[ G[temp.formula_numb][tt+1]-'A' ][i])
                      buffer[bsize++] = i;
                }
                for( i = 91; i < 128; i++){
                   if(first_vn[ G[temp.formula_numb][tt+1]-'A' ][i])
                      buffer[bsize++] = i;
                }
                if(first_vn[ G[temp.formula_numb][tt+1]-'A' ][64]){
                   tt++;
                   flag = true;
                }
        }
        
    }while(flag);
}



void e_closure(int T){
    //cout << "T: " << T << "," << size_item[T] << endl;
    
     for(int i = 0; i < size_item[T]; i++){  
       proj temp;
       if(G[items[T][i].formula_numb][items[T][i].part] >= 'A' && G[items[T][i].formula_numb][items[T][i].part] <= 'Z'){
           for(int j = 0; j < 20; j++)
               if(G[j][0] == G[items[T][i].formula_numb][items[T][i].part]){
                 gete_expc(items[T][i]);
                 for(int k = 0; k < bsize; k++){
                         temp.formula_numb = j;
                         temp.part = 1;
                         temp.expc = buffer[k];
                         if(!is_in(temp,T))
                           items[T][size_item[T]++] = temp;
                 }
                 bsize = 0;
               }
       }
     }
/*     for(int i = 0; i < size_item[T]; i++)
          printf("%d , %d , %c\n",items[T][i].formula_numb,items[T][i].part,items[T][i].expc);
     cout << "***************************************" << endl;
*/
     
     return ;
}

int is_contained()
{
    for(int i = 0; i < Ccount; i++){
       int s = 0;        //记录有多少是匹配的 
       if(size_item[i] == size_item[Ccount])
                for(int j = 0; j < size_item[Ccount]; j++){
                   for(int k = 0; k < size_item[i]; k++)
                       if((items[Ccount][j].formula_numb == items[i][k].formula_numb) && (items[Ccount][j].part == items[i][k].part) && (items[Ccount][j].expc == items[i][k].expc)){
                                              s++;
                                              break;
                       }
                }
       if(s == size_item[Ccount])
                return i;
    }   
    return 0;
                
    
}

void go(){
	int j;
    proj init;
    init.expc = '#';
    init.formula_numb = 0;
    init.part = 1;
    items[0][0] = init;
    size_item[0]++;
    
    e_closure(0);
    
    cout << "I0:" << endl;
    for(int i = 0; i < size_item[0]; i++)
          printf("%d , %d , %c\n",items[0][i].formula_numb,items[0][i].part,items[0][i].expc);
     cout << "***************************************" << endl;
     
    bool beginflag = true;
    
    for(int index = 0; (index < Ccount) || beginflag ; index++){
        beginflag = false;
        for( j = 0; j < size_vt; j++){
                proj    buf[50];
                int     buf_size = 0;
                proj    tp;
                
                int ccc = 0;
                for(int p = 0; p < size_item[index]; p++){
                        if((items[index][p].part < length[ items[index][p].formula_numb ]) && ( G[ items[index][p].formula_numb ][ items[index][p].part ] == str_vt[j]) ){
                           tp.formula_numb = items[index][p].formula_numb;
                           tp.expc = items[index][p].expc;
                           tp.part = items[index][p].part+1;
                           buf[buf_size++] = tp;
                           //ccc++;
                           
                        }
                }
                printf("//I%d ----- %c:\n",index,str_vt[j]);

                if(buf_size  != 0){
                   Ccount++;
                   for(int t = 0; t < buf_size; t++){
                       items[Ccount][ size_item[Ccount]++ ] = buf[t];
                   }
                
                   e_closure(Ccount);
                   
                   int  next_state = is_contained();                       //看生成的项目集是否已经在项目集族中了 
                   
                   if(next_state != 0){
                       size_item[Ccount] = 0;
                       Ccount--;
                       trans[size_trans].beg = index;
                       trans[size_trans].nex = next_state;
                       trans[size_trans].ch = str_vt[j];
                       size_trans++;
                   }
                   else{
                       cout << "I" << Ccount << ":" << endl;
                       for(int i = 0; i < size_item[Ccount]; i++)
                           printf("%d , %d , %c\n",items[Ccount][i].formula_numb,items[Ccount][i].part,items[Ccount][i].expc);
                       cout << "***************************************" << endl;
                       trans[size_trans].beg = index;
                       trans[size_trans].nex = Ccount;
                       trans[size_trans].ch = str_vt[j];
                       size_trans++;           
                   }
                   
                }
                
                
        }                //对文法的每一个终结符 
        
        
        for( j = 0; j < size_vn; j++){
                proj    buf[50];
                int     buf_size = 0;
                proj    tp;
                
                int ccc = 0;
                for(int p = 0; p < size_item[index]; p++){
                        if((items[index][p].part < length[ items[index][p].formula_numb ]) && ( G[ items[index][p].formula_numb ][ items[index][p].part ] == str_vn[j]) ){
                           tp.formula_numb = items[index][p].formula_numb;
                           tp.expc = items[index][p].expc;
                           tp.part = items[index][p].part+1;
                           buf[buf_size++] = tp;
                           //ccc++;
                           
                        }
                }
                printf("//I%d ----- %c:\n",index,str_vn[j]);
                
                
                if(buf_size  != 0){
                   Ccount++;
                   for(int t = 0; t < buf_size; t++){
                       items[Ccount][ size_item[Ccount]++ ] = buf[t];
                   }
                
                   e_closure(Ccount);
                   
                   int  next_state = is_contained();                       //看生成的项目集是否已经在项目集族中了 
                   
                   if(next_state != 0){
                       size_item[Ccount] = 0;
                       Ccount--;
                       trans[size_trans].beg = index;
                       trans[size_trans].nex = next_state;
                       trans[size_trans].ch = str_vn[j];
                       size_trans++;
                   }
                   else{
                       cout << "I" << Ccount << ":" << endl;
                       for(int i = 0; i < size_item[Ccount]; i++)
                           printf("%d , %d , %c\n",items[Ccount][i].formula_numb,items[Ccount][i].part,items[Ccount][i].expc);
                       cout << "***************************************" << endl;
                       trans[size_trans].beg = index;
                       trans[size_trans].nex = Ccount;
                       trans[size_trans].ch = str_vn[j];
                       size_trans++;           
                   }
                   
                }
                
                
        }                //对文法的每一个非终结符 
    }
    
}



int main()
{
	int i;
   for( i = 0; i< 150; i++)
        tempofinput[i] = false;
    for( i= 0; i < 100; i++)
        size_item[i] = 0;
    for( i = 0; i < 30; i++)
        for(int j = 0; j < 150; j++)
                first_vn[i][j] = false;

    Read_G();        //read G and put the number of formula into count
   // cout << "***************************" << endl;
 
    get_first();     //each vn's first_set
    /*for(int i = 0; i < 128; i++)
        if(first_vn[1][i])
         printf("(B,%c)\n",i);*/
    
    go();
    for( i = 0; i < size_trans; i++){
        printf("(%d %c %d)\n",trans[i].beg,trans[i].ch,trans[i].nex);
    }
    /*cout << "$$$$$$$$$$$$$$$$$$$$$$$$$" <<endl;
    for(int i = 1; i <= number; i++){
        cout << length[i]  << " ";
        for(int j = 0; j < length[i]; j++){
                cout << G[i][j]<<" ";
        }
        cout << endl;
    }
    cout << "$$$$$$$$$$$$$$$$$$$$$$$$$" <<endl;*/
    cout << Ccount << endl;
    system("pause");
    return 0;
}

⌨️ 快捷键说明

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