编译原理实习(应用预测分析法LL(1)实现语法分析)

编译原理实习(应用预测分析法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

 

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