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

📄 实验2.cpp

📁 1 掌握手工生成词法分析器的方法
💻 CPP
📖 第 1 页 / 共 3 页
字号:

              while(tmpChar != '#') {                //求出产生式的个数

                     if(tmpChar == ';') 

                            tmpIndex++;

                     fscanf(pFile,"%c",&tmpChar);

              }

              proNum = tmpIndex;

              rewind(pFile);

              for(int i = 0;i < proNum;i++) {     //读出各产生式并置于已定义的数据结构ProNode中,

                     //同时可将非终结符置于非终结符号表

                     fscanf(pFile,"%c %c %c",&proNode[i].leftSym,&proNode[i].midSym[0],\

                            &proNode[i].midSym[1]);

                     proNode[i].midSym[2] = '\0';

                     fscanf(pFile,"%c",&tmpChar);

                     int j = 0;

                     while(tmpChar != ';') {

                            proNode[i].rightSym[j] = tmpChar;

                            fscanf(pFile,"%c",&tmpChar);

                            j++;

                     }

                     proNode[i].rightSym[j] = '\0';

                     proNode[i].length = j;

                     

              }

              return true;

       }

       

       void PrintPro(ProNode proNode[],int proNum) { //显示产生式

              for(int i = 0 ; i < proNum ; i++) {

                     cout<<proNode[i].leftSym<<proNode[i].midSym[0]<<proNode[i].midSym[1];

                     for(int j = 0; j < proNode[i].length;j++)

                            cout<<proNode[i].rightSym[j];

                     cout<<endl;

              }

       }

       

       void SetUnTerminate(char UnTerminate[],ProNode proNode[],int proNum) {   

              //获得非终结符,存储于非终结符表

              for(int i = 0; i < proNum; i++) {   //从第一个产生式开始

                     bool flag = true;

                     int tmpLength = strlen(UnTerminate);

                     for(int j = 0; j <= tmpLength; j++) {

                            if(UnTerminate[j] == proNode[i].leftSym) { //若已存在,则进入下个产生式

                                   flag = false;                  

                                   break;

                            }

                     }

                     if(flag) {

                            UnTerminate[tmpLength] = proNode[i].leftSym;  //将非终结符加入到非终结符表

                            UnTerminate[tmpLength + 1] = '\0';                          

                     }

              }

       }

       

       void SetTerminate(char Terminate[],ProNode proNode[],int proNum) {    

              //获得终结符,存储于终结符表

              int tmpLength;

              bool flag ;

              for(int i = 0; i < proNum; i++) {   //从第一个产生式开始

                     

                     for(int k = 0 ; k < proNode[i].length; k++) {

                            flag = true;

                            tmpLength = strlen(Terminate);

                            if(isupper(proNode[i].rightSym[k]))    //若为非终结符号,则进入下一个字符

                                   flag = false;

                            else if ( proNode[i].rightSym[k] == '^') {

                                   int tmpLength = strlen(ProNull);

                                   flag = false;

                                   ProNull[tmpLength] = proNode[i].leftSym;         //记录能产生空字符的产生式

                                   ProNull[tmpLength + 1] = '\0';

                            }

                            else if(flag)

                                   for(int j = 0; j <= tmpLength; j++) {

                                          if(Terminate[j] == proNode[i].rightSym[k]) {

                                                 //若已存在,则进入下一个字符

                                                 flag = false;                  

                                                 break;

                                          }

                                   }

                                   if(flag) {                                                                        //将终结符加入到终结符表

                                          Terminate[tmpLength] = proNode[i].rightSym[k];

                                          Terminate[tmpLength + 1] = '\0';

                                   }        

                     }

              }

       }

       

       int GetNumofUT(char UnTerminate[]) {      //获得非终结符个数

              return strlen(UnTerminate);

       }

       

       int GetNumofT(char Terminate[]) { //获得终结符个数

              return strlen(Terminate);

       }

       

       bool IsNull(char c) {     //非终结符能否产生空字符

              int len = strlen(ProNull);

              for(int i = 0;i < len;i++) {

                     if(ProNull[i] == c) 

                            return true;

              }

              return false;

       }

       

       bool IsTerminate(char c) { //判断是否为终结符号

              int num = GetNumofT(Terminate);

              bool flag = false;

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

                     if(Terminate[i] == c) {

                            flag = true;

                            break;

                     }

              }

              return flag;

       }

       

       int GetUTLoaction(char UnTerminate[],char c) { //获得非终结符在非终结符表中的位置

              for(int i = 0 ; i < GetNumofUT(UnTerminate);i++)

                     if(UnTerminate[i] == c) 

                            return i;

                     return -1;

       }

       

       int GetTLocaction(char Terminate[],char c) {     //获得终结符在终结符表中的位置

              for(int i = 0 ; i < GetNumofT(Terminate);i++)

                     if(Terminate[i] == c) 

                            return i;

                     return -1;

       }

       

       void AddChar(char chArray[],char c) {                            //将非终结符的所有first值加入First集

              bool flag = true;

              int tmpLength = strlen(chArray);

              for(int i = 0; i <= tmpLength; i++) {

                     if(chArray[i] == c) {     //若已存在,则不加入

                            flag = false;                  

                            break;

                     }

              }

              if(flag) {

                     chArray[tmpLength] = c;      //将first值加入First集

                     chArray[tmpLength + 1] = '\0';

              }

       }

       

       void AddCharToChar(char chArray[],char otherArray[]) {

              int otherLength = strlen(otherArray);

              for(int j = 0 ; j < otherLength; j++) {

                     bool flag = true;

                     int tmpLength = strlen(chArray);

                     for(int i = 0; i <= tmpLength; i++) {

                            

                            if(chArray[i] == otherArray[j]) {   //若已存在,则不加入

                                   flag = false;                  

                                   break;

                            }

                     }

                     if(flag) {

                            chArray[tmpLength] = otherArray[j];   //将first值加入First集

                            chArray[tmpLength + 1] = '\0';

                     }

              }

       }

       

       void First(ProNode proNode[],UnTInfo unTInfo[]) {         //求出First集合

              for(int i = proNum -1 ; i >= 0 ; i--) {    //从最后一个产生式开始进行分析

                     char leftSym = proNode[i].leftSym;

                     char c = proNode[i].rightSym[0];

                     int leftSymLoc = GetUTLoaction(UnTerminate,leftSym);

                     if(IsNull(leftSym))   //如果产生式推出空字符,则把空字符加入First集合

                            AddChar(unTInfo[leftSymLoc].first,c);

                     else {

                            if(IsTerminate(c)) { //如果产生式右边第一个符号为终结符号

                                   AddChar(unTInfo[leftSymLoc].first,c); //将符号加入First集合

                            }

                            else {

                                   for(int k = 0; k < proNode[i].length; k++) {

                                          if(!IsNull(proNode[i].rightSym[k])) {  

                                                 //判断能否产生空字符,直到找到不为空的停止

                                                 break;

                                          }

                                   }

                                   if(k ==  proNode[i].length)  

                                          //若对于产生式右边的一切非终结符,均可推出ε,则将ε加进FIRST集

                                          AddChar(unTInfo[leftSymLoc].first,'^');

                                   else {

                                          for(int l = 0 ; l <k;l++) { 

                                                 /*将产生式右边能推出空字符的非终结符的Frist集中不含ε的终结符加入到该非终结符的Fisrt集*/

                                                 char rightChar = proNode[i].rightSym[l];

                                                 int rightSymLoc = GetUTLoaction(UnTerminate,rightChar);

                                                 int firstLen = strlen(unTInfo[rightSymLoc].first);

                                                 for (int m = 0 ; m < firstLen; m++) {

                                                        if(unTInfo[rightSymLoc].first[m] != '^')

                                                               AddChar(unTInfo[leftSymLoc].first,unTInfo[rightSymLoc].first[m]);

                                                 }

                                          }

                                          /*将产生式右边不能推出空字符的非终结符的Frist集加入到该非终结符的Fisrt集*/

                                          int rightSymLoc = GetUTLoaction(UnTerminate,proNode[i].rightSym[k]); 

                                          AddCharToChar(unTInfo[leftSymLoc].first,unTInfo[rightSymLoc].first); 

                                          

                                   }

                            }

                     }

              }

       }

       

       void Follow(ProNode proNode[],UnTInfo unTInfo[]) {     //计算各非终结符的Follow集

              

              AddChar(unTInfo[0].follow,'#');   //开始符号,则把“#”加入FOLLOW中;

              int numOfUnT = GetNumofUT(UnTerminate);

              for(int i = 0; i < numOfUnT ; i++) {     

                     for(int j = 0 ;j < proNum; j++) {   //从第一个产生式开始进行分析,逐个进行扫描

                            bool flag = false ;   

                            for(int k = 0 ; k < proNode[j].length; k++) {

                                   flag = false;

                                   if(UnTerminate[i] == proNode[j].rightSym[k]) //判断非终结符是否在产生式右边

                                          flag = true;

                                   if(flag) {

                                          if((k == proNode[j].length - 1) || IsNull(proNode[j].rightSym[k+1])) {

                                                 //若B→αA 或B→αAβ,且β=>ε,则把FOLLOW(B)加入FOLLOW(A) 中

                                                 if(proNode[j].leftSym != UnTerminate[i]) {

                                                        int leftSymLoc = GetUTLoaction(UnTerminate,proNode[j].leftSym); 

                                                        AddCharToChar(unTInfo[i].follow,unTInfo[leftSymLoc].follow);

                                                 }

                                          }

                                          if(proNode[j].rightSym[k+1] != '\0'){   

⌨️ 快捷键说明

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