zoukankan      html  css  js  c++  java
  • 编译原理实习(应用预测分析法LL(1)实现语法分析)

      1 #include<iostream>
      2 #include<fstream>
      3 #include<iomanip>
      4 #include<cstdio>
      5 #include<cstring>
      6 #include<algorithm>
      7 #include<vector>
      8 #include<string>
      9 #include<set>
     10 #include<queue>
     11 #include<stack>
     12 #include<map>
     13 using namespace std;
     14 
     15 typedef pair<char, string>PP;
     16 typedef pair<char, pair<string, string> >PPP;
     17 
     18 
     19 //*代表弧
     20 //~代表空
     21 //输入:
     22 /*
     23 S*MH
     24 S*a
     25 H*LSo
     26 H*~
     27 K*dML
     28 K*~
     29 L*eHf
     30 M*K
     31 M*bLM
     32 */
     33 
     34 
     35 class Set{
     36 
     37 private:
     38     multimap<char, string >Grammars;//文法
     39     multimap<string, char >Re_Grammars; //反向映射
     40     vector<PP >FIRST;  //FIRST集
     41     vector<PP >FOLLOW; //FOLLOW集
     42     set<char >Ok; //能推出空的非终结符的集合
     43     set<char >Non_terminal; //非终结符集合
     44     vector<string >Right; //产生式右部
     45     vector<PPP >SELECT; //SELECT集
     46     vector<char >Sentence; //要识别的句子
     47 
     48 public:
     49     Set();
     50     ~Set();
     51     bool Judge_Ok(char);  //判断一个非终结符是否能推出空
     52     void Get_Ok();  //求出那些能推出空的非终结符集合
     53     void First_Solve();  //求解FIRST集
     54     void Show_First(); //输出FIRST集合
     55     void Get_First(char, set<char>&);     //求解某个非终结符的FIRST集
     56     void Follow_Solve(); //求解FOLLOW集
     57     void Show_Follow(); //输出FOLLOW集
     58     void Get_Follow(char, set<char>&);   //求解某个非终结符的FOLLOW集
     59     void Select_Solve(); //求解SELECT集
     60     void Show_Select();  //输出SELECT集
     61     void Analysis();   //预测分析程序
     62 
     63 };
     64 
     65 Set::Set()
     66 {
     67     ifstream infile;
     68     infile.open("data.txt");
     69     if (!infile){
     70         cout << "can't open the file" << endl;
     71         return;
     72     }
     73     string str;
     74     while (infile >> str){
     75         char ch = str[0];
     76         string ss = "";
     77         for (int i = 2; i < (int)str.size(); i++)ss += str[i];
     78         Grammars.insert(make_pair(ch, ss)); //所给文法
     79         Re_Grammars.insert(make_pair(ss, ch));  //反向映射集合
     80         Right.push_back(ss); //得到右部产生式
     81         for (int i = 0; i < (int)str.size(); i++){
     82             if (isupper(str[i]))Non_terminal.insert(str[i]); //求非终结符集合
     83         }
     84     }
     85     infile.close();
     86 }
     87 
     88 Set::~Set()
     89 {
     90     Grammars.clear();
     91     Re_Grammars.clear();
     92     Right.clear();
     93     Ok.clear();
     94     FIRST.clear();
     95     FOLLOW.clear();
     96     SELECT.clear();
     97     Non_terminal.clear();
     98 }
     99 
    100 //判断一个非终结符是否能推出空
    101 bool Set::Judge_Ok(char ch)
    102 {
    103     if (Grammars.find(ch) == Grammars.end())return false;//如果找不到这个非终结符所能推出的符号,则返回false.
    104 
    105     multimap<char, string>::iterator iter = Grammars.find(ch);
    106     int Count =(int)Grammars.count(iter->first);
    107     for (int i = 0; i < Count; i++){
    108         bool flag = true;
    109         for (int j = 0; j < (int)iter->second.size(); j++){
    110             //如果是大写字母,那么就继续递归
    111             if (isupper(iter->second[j])){
    112                 //避免重复递归
    113                 if (iter->second[j] == ch){
    114                     flag = false;
    115                     break;
    116                 }
    117                 else if (!Judge_Ok(iter->second[j])){
    118                     flag = false;
    119                     break;
    120                 }
    121             }
    122             //如果不是大写字母,就判断是否是空,如果不是,则也是直接break;
    123             else if (iter->second[j] != '~'){
    124                 flag = false;
    125                 break;
    126             }
    127         }
    128         if (flag)return true; //在某个非终结符的多重集合中,只要有某个能产生空,那么这个非终结符就能推出空,返回true;
    129         iter++;
    130     }
    131     //如果都不能推出空,那么就返回false;
    132     return false;
    133 
    134 }
    135 
    136 
    137 //求出那些能推出空的非终结符集合
    138 void Set::Get_Ok()
    139 {
    140     set<char>::iterator iter;
    141     for (iter = Non_terminal.begin(); iter != Non_terminal.end(); iter++){
    142         if(Judge_Ok((*iter))){
    143             Ok.insert(*iter);
    144         }
    145     }
    146 }
    147 
    148 //求某一个非终结符的FIRST集
    149 void Set::Get_First(char ch, set<char>&st)
    150 {
    151     if (Grammars.find(ch) == Grammars.end())return;   //如果没有找到非终结符可以转化的符号,则直接返回
    152 
    153     multimap<char, string>::iterator iter = Grammars.find(ch);
    154     int Count = (int)Grammars.count(iter->first);
    155     for (int i = 0; i < Count; i++){
    156         for (int j = 0; j < (int)(iter->second.size()); j++){
    157             //此时碰到的是终结符,找到后将其插入到set集合中,并且立马跳出循环,找下一个
    158             if (!isupper(iter->second[j])){
    159                 st.insert(iter->second[j]);
    160                 break;
    161             }
    162             else if (isupper(iter->second[j])){
    163                 //避免重复递归
    164                 if (iter->second[j] == ch){
    165                     break;
    166                 }
    167                 //如果不重复,那么就从这个非终结符继续找
    168                 Get_First(iter->second[j], st);
    169 
    170                 //如果这个非终结符不能推出空,那么就直接break寻找下一个映射
    171                 if (Ok.find(iter->second[j]) == Ok.end()){
    172                     break;
    173                 }
    174             }
    175         }
    176         iter++;
    177     }
    178 }
    179 
    180 
    181 //求所有非终结符的FIRST集
    182 void Set::First_Solve()
    183 {
    184     set<char >First;
    185     for (set<char >::iterator iter = Non_terminal.begin(); iter != Non_terminal.end(); iter++){
    186         First.clear();
    187         Get_First(*iter, First); //求某一个非终结符的FIRST集
    188         string str = "";
    189         for (set<char>::iterator it = First.begin(); it != First.end(); it++)str += (*it);
    190         FIRST.push_back(make_pair(*iter, str));
    191     }
    192 }
    193 
    194 //输出FIRST集
    195 void Set::Show_First()
    196 {
    197     cout << "  " << "FIRST集" << " " << endl << endl;
    198     for (int i = 0; i <(int) FIRST.size(); i++){
    199         cout << FIRST[i].first << "";
    200         for (int j = 0; j <(int) FIRST[i].second.size(); j++){
    201             cout << FIRST[i].second[j] << " ";
    202         }
    203         cout << endl;
    204     }
    205     cout << endl;
    206 }
    207 
    208 
    209 //求某一个非终结符的FOLLOW集
    210 void Set::Get_Follow(char ch, set<char>&st)
    211 {
    212     if (ch == 'S')st.insert('#');//如果是开始符;
    213     for (int i = 0; i < (int)Right.size(); i++){
    214         string str = Right[i];
    215         for (int j = 0; j < (int)Right[i].size(); j++){
    216             //如果不是当前产生式的最后一个
    217             if (Right[i][j] == ch&&j !=(int) Right[i].size() - 1){
    218                 //如果后面紧跟着的是终结符
    219                 if (!isupper(Right[i][j + 1])){
    220                     if (Right[i][j + 1] != '~'){
    221                         st.insert(Right[i][j + 1]);
    222                     }
    223                 }
    224                 else{
    225                     //后面紧跟着是非终结符,就把这个非终极符的FIRST集(除了空)加入到当前ch的FOLLOW集中
    226                     vector<PP>::iterator iter = FIRST.begin();
    227                     while (iter != FIRST.end()){
    228                         if (iter->first == Right[i][j+1]){
    229                             break;
    230                         }
    231                         iter++;
    232                     }
    233                     for (int k = 0; k < (int)iter->second.size(); k++){
    234                         if (iter->second[k] != '~')st.insert(iter->second[k]);
    235                     }
    236                     //如果对形如“…UP”(P是非终结符的组合)的组合;
    237                     //如果这些非终结符都能推出空,就么就要把左部(假设是S)的Follow(S)送入到Follow(U)中
    238                     bool flag = true;
    239                     for (int pos = j + 1; pos < (int)Right[i].size(); pos++){
    240                         if (isupper(Right[i][pos]) && Ok.find(Right[i][pos]) != Ok.end()){
    241                             vector<PP>::iterator ii = FIRST.begin();
    242                             while (ii != FIRST.end()){
    243                                 if (ii->first == Right[i][pos]){
    244                                     break;
    245                                 }
    246                                 ii++;
    247                             }
    248                             for (int k = 0; k < (int)ii->second.size(); k++){
    249                                 if (ii->second[k] != '~')st.insert(ii->second[k]);
    250                             }
    251                             continue;
    252                         }
    253                         flag = false;
    254                         break;
    255                     }
    256                     if (flag){
    257                         multimap<string, char>::iterator it = Re_Grammars.find(str);
    258                         int Count = Re_Grammars.count(it->first);
    259                         while (Count--){
    260                             if (it->second != ch){
    261                                 Get_Follow(it->second, st);
    262                             }
    263                         }
    264                     }
    265                 }
    266             }
    267             //如果刚好是当前产生式的最后一个字符
    268             else if (Right[i][j] == ch&&j == (int)Right[i].size() - 1){
    269                 //反向映射找到推出str这个产生式的左部字符
    270                 multimap<string, char>::iterator iter = Re_Grammars.find(str);
    271                 int Count = Re_Grammars.count(iter->first);
    272                 while (Count--){
    273                     if (iter->second != ch){
    274                         Get_Follow(iter->second, st);
    275                     }
    276                 }
    277             }
    278         }
    279     }
    280 }
    281 
    282 
    283 //求所有非终结符的FOLLOW集
    284 void Set::Follow_Solve()
    285 {
    286     set<char>Follow;
    287     for (set<char>::iterator iter = Non_terminal.begin(); iter != Non_terminal.end(); iter++){
    288         Follow.clear();
    289         if (*iter == 'S')Follow.insert('#'); //如果是开始符
    290         Get_Follow(*iter, Follow);
    291         string str = "";
    292         for (set<char>::iterator it = Follow.begin(); it != Follow.end(); it++)str += (*it);
    293         FOLLOW.push_back(make_pair(*iter, str));
    294     }
    295 }
    296 
    297 
    298 //输出所有非终结符的FOLLOW集
    299 void Set::Show_Follow()
    300 {
    301     cout << "  " << "FOLLOW集" << " " << endl << endl;
    302     for (int i = 0; i < (int) FOLLOW.size(); i++){
    303         cout << FOLLOW[i].first << "";
    304         for (int j = 0; j <(int) FOLLOW[i].second.size(); j++){
    305             cout << FOLLOW[i].second[j] << " ";
    306         }
    307         cout << endl;
    308     }
    309     cout << endl;
    310 }
    311 
    312 
    313 //求解SELECT集
    314 void Set::Select_Solve()
    315 {
    316     multimap<char, string>::iterator iter;
    317     vector<PP >::iterator it;
    318     set<char >st;
    319     for (iter = Grammars.begin(); iter != Grammars.end(); iter++){
    320         char ch = iter->first;
    321         string str = iter->second;
    322         bool flag = true;
    323         st.clear();
    324         for (int i = 0; i < (int)str.size(); i++){
    325             if (Ok.find(str[i]) == Ok.end()&& str[i] != '~'){
    326                 flag = false;
    327             }
    328         }
    329         //求FIRST(a)
    330         int pos = 0;
    331         while (pos < (int)str.size() && Ok.find(str[pos]) != Ok.end()){
    332             for (it = FIRST.begin(); it != FIRST.end(); it++){
    333                 if (str[pos] == it->first)break;
    334             }
    335             for (int j = 0; j < (int)it->second.size(); j++){
    336                 st.insert(it->second[j]);
    337             }
    338             pos++;
    339         }
    340         if (pos < (int)str.size()){
    341             if (isupper(str[pos])){
    342                 for (it = FIRST.begin(); it != FIRST.end(); it++){
    343                     if (str[pos] == it->first)break;
    344                 }
    345                 for (int j = 0; j < (int)it->second.size(); j++){
    346                     st.insert(it->second[j]);
    347                 }
    348             }else 
    349                 st.insert(str[pos]);
    350         }
    351         //如果产生式A->a并且a能推出空,则SELECT(A->a)=(FIRST(a)-{~})U(FOLLOW(A)
    352         if (flag){
    353             for (it = FOLLOW.begin(); it != FOLLOW.end(); it++){
    354                 if (ch == it->first)break;
    355             }
    356             for (int j = 0; j < (int)it->second.size(); j++){
    357                 st.insert(it->second[j]);
    358             }
    359             for (set<char>::iterator ii = st.begin(); ii != st.end(); ){
    360                 if ((*ii) == '~'){
    361                     ii = st.erase(ii);
    362                     break;
    363                 }
    364                 ii++;
    365             }
    366             string ss = "";
    367             for (set<char>::iterator ii = st.begin(); ii != st.end(); ii++)ss += (*ii);
    368             SELECT.push_back(make_pair(ch, make_pair(str,ss)));
    369         }
    370         //否则SELECT(A->a)=(FIRST(a)
    371         else {
    372             string ss = "";
    373             for (set<char>::iterator ii = st.begin(); ii != st.end(); ii++)ss += (*ii);
    374             SELECT.push_back(make_pair(ch, make_pair(str,ss)));
    375         }
    376     }
    377 }
    378 
    379 
    380 //输出SELECT集
    381 void Set::Show_Select()
    382 {
    383     cout << "  " << "SELECT集" << " " << endl << endl;
    384     for (int i = 0; i < (int) SELECT.size(); i++){
    385         cout << SELECT[i].first << " ->";
    386         cout << setw(4) << SELECT[i].second.first << " :   ";
    387         for (int j = 0; j < (int) SELECT[i].second.second.size(); j++){
    388             cout << SELECT[i].second.second[j] << " ";
    389         }
    390         cout << endl;
    391     }
    392     cout << endl;
    393 }
    394 
    395 
    396 //预测分析程序
    397 void Set::Analysis()
    398 {
    399     cout << "请输入要识别的串: " << endl;
    400     string str;
    401     cin >> str;
    402     for (int i = 0; i < (int)str.size(); i++){
    403         Sentence.push_back(str[i]);
    404     }
    405     Sentence.push_back('#');
    406     vector<char>::iterator iter = Sentence.begin(), ii;
    407     stack<char>S;
    408     vector<char>vet;
    409     S.push('#');
    410     S.push('S');
    411     vet.push_back('#');
    412     vet.push_back('S');
    413     cout << "分析栈" << "              " << "剩余输入串" << "              " << "推倒所用的产生式或匹配" << endl;
    414     int EMPTY = 7;
    415     while (!S.empty()){
    416         for (int i = 0; i < (int)vet.size(); i++){
    417             cout << vet[i] << " ";
    418         }
    419         for (int i = (int)vet.size(); i <= EMPTY+2; i++)cout << "  ";
    420         int count = 0;
    421         for (ii = iter; ii != Sentence.end(); ii++){
    422             cout << (*ii) << " ";
    423             count++;
    424         }
    425         for (; count <= EMPTY; count++)cout << "  ";
    426         char ch = S.top();
    427         if (ch == (*iter)){
    428             S.pop();
    429             vet.pop_back();
    430             iter++;
    431             for (int i = 0; i <= EMPTY; i++)cout << "  ";
    432             cout << "匹配" << endl;
    433         }
    434         else {
    435             vector<PPP >::iterator it;
    436             string ss = "";
    437             bool flag = false;
    438             for (it = SELECT.begin(); it != SELECT.end(); it++){
    439                 if (it->first == ch){
    440                     ss = it->second.first;
    441                     for (int i = 0; i < (int)it->second.second.size(); i++){
    442                         if (it->second.second[i] == (*iter)){
    443                             flag = true;
    444                             break;
    445                         }
    446                     }
    447                     if (flag)break;
    448                 }
    449             }
    450             for (int i = 0; i <= EMPTY; i++)cout << "  ";
    451             if (!flag){
    452                 cout << "ERROR!!!" << endl;
    453                 return;
    454             }
    455             cout << ch << "->" << ss << endl;
    456             reverse(ss.begin(), ss.end()); //反转
    457             if (ss == "~"){
    458                 S.pop();
    459                 vet.pop_back();
    460             }
    461             else {
    462                 S.pop();
    463                 vet.pop_back();
    464                 for (int i = 0; i < (int)ss.size(); i++){
    465                     S.push(ss[i]);
    466                     vet.push_back(ss[i]);
    467                 }
    468             }
    469         }
    470     }
    471     cout << "SUCCESS" << endl;
    472 }
    473 
    474 
    475 
    476 int main()
    477 {
    478     Set obj;
    479     obj.Get_Ok(); 
    480     obj.First_Solve();
    481     obj.Show_First();
    482     obj.Follow_Solve();
    483     obj.Show_Follow();
    484     obj.Select_Solve();
    485     obj.Show_Select();
    486     obj.Analysis();
    487     return 0;
    488 }
    View Code
  • 相关阅读:
    linux中tar命令用法
    CentOS 7安装 ifconfig 管理命令
    CentOS 7安装 ifconfig 管理命令
    VMware 创建设置虚拟网卡
    VMware 创建设置虚拟网卡
    C#MongoDB Driver $in
    C#MongoDB Driver $in
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车超声波避障实验(有舵机)
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车超声波避障实验(有舵机)
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车超声波避障实验(无舵机)
  • 原文地址:https://www.cnblogs.com/wally/p/3427866.html
Copyright © 2011-2022 走看看