pd_alg_nb_sub_a.cppGo to the documentation of this file.00001 /** @file pd_alg_nb_sub_a.cpp Nonblock subfunctions, part A */ 00002 00003 00004 /* Pushdown plugin for FAU Discrete Event Systems Library (libfaudes) 00005 00006 Copyright (C) 2013 Stefan Jacobi, Sven Schneider, Anne-Kathrin Hess 00007 00008 */ 00009 00010 #include "pd_alg_nb_sub_a.h" 00011 00012 namespace faudes { 00013 00014 00015 /* ************************* 00016 * Filter 00017 * *************************/ 00018 std::set<Nonterminal> Filter(const std::set<Nonterminal>& symbolSet, const GrammarSymbolVector& w){ 00019 00020 //resulting set 00021 std::set<Nonterminal> rSet; 00022 00023 GrammarSymbolVector::const_iterator wit; 00024 std::set<Nonterminal>::const_iterator ntit; 00025 //iterate over all symbols of the word 00026 for(wit = w.begin(); wit != w.end(); wit++){ 00027 //test if current symbol is a nonterminal 00028 ConstNonterminalPtr nt = std::tr1::dynamic_pointer_cast<const Nonterminal>(*wit); 00029 if(nt != NULL){ 00030 00031 //look for the symbol in the nonterminal set 00032 ntit = symbolSet.find(*nt); 00033 00034 //if the symbol was found, insert it into resulting set 00035 if(ntit != symbolSet.end()){ 00036 rSet.insert(*ntit); 00037 } 00038 } 00039 } 00040 return rSet; 00041 } 00042 00043 00044 /* ************************* 00045 * Rnpp1 00046 * *************************/ 00047 std::set<Nonterminal> Rnpp1(const Grammar& gr, const std::set<Nonterminal>& ntSet){ 00048 00049 00050 std::set<Nonterminal> rSet, filterSet; 00051 //copy resulting set from set of already eliminated nonterminals 00052 rSet = ntSet; 00053 00054 std::set<GrammarProduction>::const_iterator pit; 00055 //iterate over all productions 00056 00057 for(pit = gr.GrammarProductions().begin(); pit != gr.GrammarProductions().end(); pit++){ 00058 00059 filterSet = Filter(gr.Nonterminals(),pit->Rhs()); 00060 00061 //test if the nonterminals on the right hand side of the production are all in 00062 //the set of eliminable nonterminals (i. e., they are eliminable) 00063 //if so, then the nonterminal on the left hand side is eliminable as well 00064 if(std::includes(ntSet.begin(), ntSet.end(), filterSet.begin(), filterSet.end())){ 00065 //insert left hand side into set of eliminable terminals 00066 rSet.insert(pit->Lhs()); 00067 } 00068 } 00069 return rSet; 00070 } 00071 00072 /* ************************* 00073 * Rnppl 00074 * *************************/ 00075 std::set<Nonterminal> Rnppl(const Grammar& gr, const std::set<Nonterminal>& ntSet){ 00076 00077 //get nonterminals that are eliminable in one step 00078 std::set<Nonterminal> rSet = Rnpp1(gr,ntSet); 00079 //look if that changed anything 00080 if(ntSet != rSet){ 00081 //if any changes were detected, go on 00082 rSet = Rnppl(gr,rSet); 00083 } 00084 return rSet; 00085 } 00086 00087 /* ************************* 00088 * Rnpp 00089 * *************************/ 00090 Grammar Rnpp(const Grammar& gr){ 00091 00092 //the grammar to be returned. keep the start symbol 00093 Grammar rGr(gr.StartSymbol()); 00094 00095 //compute removable nonterminals 00096 std::set<Nonterminal> removableNts = Rnppl(gr,std::set<Nonterminal>()); 00097 00098 std::set<GrammarProduction> productions; 00099 //if the start symbol is a removable nonterminal 00100 00101 if(removableNts.find(gr.StartSymbol()) != removableNts.end()){ 00102 00103 std::set<GrammarProduction>::const_iterator gpit; 00104 //iterate over grammar productions A -> w 00105 for(gpit = gr.GrammarProductionsBegin(); gpit != gr.GrammarProductionsEnd(); gpit++){ 00106 00107 //convert A to GrammarSymbolPtr and put it togther with w into a vector 00108 Nonterminal* a = new Nonterminal(gpit->Lhs()); 00109 NonterminalPtr aPtr(a); 00110 GrammarSymbolVector symbols(gpit->Rhs()); 00111 symbols.push_back(aPtr); 00112 00113 std::set<Nonterminal> filteredSet; 00114 //filter all nonterminals that are in A and w 00115 filteredSet = Filter(gr.Nonterminals(), symbols); 00116 00117 //test if filteredSet is a subset of the removable nonterminals 00118 if(std::includes(removableNts.begin(), removableNts.end(), filteredSet.begin(), filteredSet.end())){ 00119 productions.insert(*gpit); 00120 } 00121 } 00122 } 00123 00124 //keep the terminals 00125 rGr.InsTerminals(gr.Terminals()); 00126 00127 //keep only removable nonterminals 00128 rGr.InsNonterminals(removableNts); 00129 00130 //keep only the productions from above 00131 rGr.InsGrammarProductions(productions); 00132 00133 return rGr; 00134 } 00135 00136 /* ************************* 00137 * Sp2Lr 00138 * *************************/ 00139 Grammar Sp2Lr(const PushdownGenerator& pd){ 00140 00141 Grammar rGr; 00142 00143 StateSet::Iterator stateit1, stateit2; 00144 EventSet::Iterator eventit; 00145 TransSet::Iterator transit; 00146 StackSymbolSet::Iterator ssit; 00147 PopPushSet::const_iterator ppit; 00148 std::vector<Idx> ssVector, pop, push; 00149 std::vector<Idx>::const_iterator popit, pushit; 00150 GrammarSymbolVector rhs; 00151 00152 //Terminals 00153 00154 //terminals equal the generator's events 00155 for(eventit = pd.AlphabetBegin(); eventit != pd.AlphabetEnd(); eventit++){ 00156 rGr.InsTerminal(Terminal(*eventit)); 00157 } 00158 00159 //Nonterminals 00160 00161 //for every state 00162 for(stateit1 = pd.StatesBegin(); stateit1 != pd.StatesEnd(); stateit1++){ 00163 00164 //insert end nonterminal for every stack symbol 00165 for(ssit = pd.StackSymbolsBegin(); ssit != pd.StackSymbolsEnd(); ssit++){ 00166 if(!pd.IsStackSymbolLambda(*ssit)){ 00167 ssVector.clear(); 00168 ssVector.push_back(*ssit); 00169 rGr.InsNonterminal(Nonterminal(*stateit1,ssVector)); 00170 } 00171 } 00172 00173 //insert mid nonterminal for every state and every stack symbol 00174 for(stateit2 = pd.StatesBegin(); stateit2 != pd.StatesEnd(); stateit2++){ 00175 for(ssit = pd.StackSymbolsBegin(); ssit != pd.StackSymbolsEnd(); ssit++){ 00176 if(!pd.IsStackSymbolLambda(*ssit)){ 00177 ssVector.clear(); 00178 ssVector.push_back(*ssit); 00179 rGr.InsNonterminal(Nonterminal(*stateit1,ssVector,*stateit2)); 00180 } 00181 } 00182 } 00183 } 00184 //Start Symbol 00185 ssVector.clear(); 00186 ssVector.push_back(pd.StackBottom()); 00187 rGr.SetStartSymbol(Nonterminal(pd.InitState(),ssVector)); 00188 00189 //Grammar Productions 00190 //for every transition 00191 for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){ 00192 for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){ 00193 00194 pop = ppit->first; 00195 std::vector<Idx> b = pop; 00196 push = ppit->second; 00197 Idx qi = transit->X1; 00198 Idx qj = transit->X2; 00199 Idx a = transit->Ev; 00200 00201 //read transition (qi,a,b,b,qj) 00202 if(!pd.IsEventLambda(transit->Ev)){ 00203 00204 //insert production (qi,b) --> a(qj,b) 00205 Nonterminal ntLhs(qi,b); 00206 Nonterminal* ntRhs = new Nonterminal(qj,b); 00207 GrammarSymbolPtr ntRhsPtr(ntRhs); 00208 Terminal* t = new Terminal(a); 00209 GrammarSymbolPtr tPtr(t); 00210 rhs.clear(); 00211 rhs.push_back(tPtr); 00212 rhs.push_back(ntRhsPtr); 00213 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00214 00215 //for every state qt 00216 for(stateit1 = pd.StatesBegin(); stateit1 != pd.StatesEnd(); stateit1++){ 00217 00218 Idx qt = *stateit1; 00219 00220 //insert production (qi,b,qt) --> a (qj,b,qt) 00221 Nonterminal ntLhs(qi,b,qt); 00222 Nonterminal* ntRhs = new Nonterminal(qj,b,qt); 00223 GrammarSymbolPtr ntRhsPtr(ntRhs); 00224 rhs.clear(); 00225 rhs.push_back(tPtr); 00226 rhs.push_back(ntRhsPtr); 00227 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00228 } 00229 } 00230 else{ 00231 00232 //pop transition (qi,lambda,b,lambda,qj) 00233 if(pd.IsStackSymbolLambda(push.front())){ 00234 00235 //insert production (qi,b,qj) --> lambda 00236 Nonterminal ntLhs(qi,b,qj); 00237 Terminal* t = new Terminal(transit->Ev); 00238 GrammarSymbolPtr tPtr(t); 00239 rhs.clear(); 00240 rhs.push_back(tPtr); 00241 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00242 } 00243 00244 //push transition (qi,lambda,b,cb,qj) 00245 else if(push.size() == 2){ 00246 00247 std::vector<Idx> c; 00248 c.push_back(push.front()); 00249 00250 //insert production (qi,b) --> (qj,c) 00251 Nonterminal ntLhs(qi,b); 00252 Nonterminal* ntRhs = new Nonterminal(qj,c); 00253 GrammarSymbolPtr ntRhsPtr(ntRhs); 00254 rhs.clear(); 00255 rhs.push_back(ntRhsPtr); 00256 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00257 00258 //for every state qs 00259 for(stateit1 = pd.StatesBegin(); stateit1 != pd.StatesEnd(); stateit1++){ 00260 00261 Idx qs = *stateit1; 00262 00263 //insert production (qi,b) --> (qj,c,qs)(qs,b) 00264 Nonterminal ntLhs(qi,b); 00265 Nonterminal* ntRhs1 = new Nonterminal(qj,c,qs); 00266 GrammarSymbolPtr ntRhs1Ptr(ntRhs1); 00267 Nonterminal* ntRhs2 = new Nonterminal(qs,b); 00268 GrammarSymbolPtr ntRhs2Ptr(ntRhs2); 00269 rhs.clear(); 00270 rhs.push_back(ntRhs1Ptr); 00271 rhs.push_back(ntRhs2Ptr); 00272 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00273 00274 //for every state qt 00275 for(stateit2 = pd.StatesBegin(); stateit2 != pd.StatesEnd(); stateit2++){ 00276 00277 Idx qt = *stateit2; 00278 00279 //insert production (qi,b,qt) --> (qj,c,qs)(qs,b,qt) 00280 Nonterminal ntLhs(qi,b,qt); 00281 Nonterminal* ntRhs1 = new Nonterminal(qj,c,qs); 00282 GrammarSymbolPtr ntRhs1Ptr(ntRhs1); 00283 Nonterminal* ntRhs2 = new Nonterminal(qs,b,qt); 00284 GrammarSymbolPtr ntRhs2Ptr(ntRhs2); 00285 rhs.clear(); 00286 rhs.push_back(ntRhs1Ptr); 00287 rhs.push_back(ntRhs2Ptr); 00288 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00289 } 00290 } 00291 } 00292 } 00293 } 00294 } 00295 00296 //for every final state q and every stack symbol b 00297 for(stateit1 = pd.MarkedStatesBegin(); stateit1 != pd.MarkedStatesEnd(); stateit1++){ 00298 for(ssit = pd.StackSymbolsBegin(); ssit != pd.StackSymbolsEnd(); ssit++){ 00299 if(!pd.IsStackSymbolLambda(*ssit)){ 00300 00301 00302 //insert a production ((q,b) --> lambda) 00303 ssVector.clear(); 00304 ssVector.push_back(*ssit); 00305 Nonterminal nt(*stateit1,ssVector); 00306 Terminal* t = new Terminal(pd.EventIndex(FAUDES_PD_LAMBDA)); 00307 GrammarSymbolPtr tPtr(t); 00308 GrammarSymbolVector v; 00309 v.push_back(tPtr); 00310 GrammarProduction gp(nt,v); 00311 rGr.InsGrammarProduction(gp); 00312 } 00313 } 00314 } 00315 return rGr; 00316 } 00317 00318 /* ************************* 00319 * Sp2Lr2 00320 * *************************/ 00321 Grammar Sp2Lr2(const PushdownGenerator& pd){ 00322 00323 Grammar rGr; 00324 00325 StateSet::Iterator stateit1, stateit2; 00326 EventSet::Iterator eventit; 00327 TransSet::Iterator transit; 00328 StackSymbolSet::Iterator ssit; 00329 PopPushSet::const_iterator ppit; 00330 std::vector<Idx> ssVector, pop, push; 00331 std::vector<Idx>::const_iterator popit, pushit; 00332 GrammarSymbolVector rhs; 00333 00334 //Terminals 00335 00336 //terminals equal the generator's events 00337 for(eventit = pd.AlphabetBegin(); eventit != pd.AlphabetEnd(); eventit++){ 00338 rGr.InsTerminal(Terminal(*eventit)); 00339 } 00340 //Start Symbol 00341 ssVector.clear(); 00342 ssVector.push_back(pd.StackBottom()); 00343 rGr.SetStartSymbol(Nonterminal(pd.InitState(),ssVector)); 00344 00345 //Grammar Productions 00346 00347 //for every final state q and every stack symbol b 00348 for(stateit1 = pd.MarkedStatesBegin(); stateit1 != pd.MarkedStatesEnd(); stateit1++){ 00349 for(ssit = pd.StackSymbolsBegin(); ssit != pd.StackSymbolsEnd(); ssit++){ 00350 if(!pd.IsStackSymbolLambda(*ssit)){ 00351 00352 //save used nonterminal 00353 ssVector.clear(); 00354 ssVector.push_back(*ssit); 00355 Nonterminal nt(*stateit1,ssVector); 00356 rGr.InsNonterminal(nt); 00357 00358 //insert a production ((q,b) --> lambda) 00359 Terminal* t = new Terminal(pd.EventIndex(FAUDES_PD_LAMBDA)); 00360 GrammarSymbolPtr tPtr(t); 00361 GrammarSymbolVector v; 00362 v.push_back(tPtr); 00363 GrammarProduction gp(nt,v); 00364 rGr.InsGrammarProduction(gp); 00365 //std::cout << "inserting " << gp.Str() << std::endl; 00366 } 00367 } 00368 } 00369 00370 00371 //generate reducible productions until no more productions can be generated 00372 uint oldSize = 0; 00373 00374 while(rGr.GrammarProductions().size() != oldSize){ 00375 00376 //save old number of grammar productions 00377 oldSize = rGr.GrammarProductions().size(); 00378 00379 //try to generate new grammar productions for each transition 00380 for(transit = pd.TransRelBegin(); transit != pd.TransRelEnd(); transit++){ 00381 for(ppit = pd.PopPushBegin(*transit); ppit != pd.PopPushEnd(*transit); ppit++){ 00382 00383 pop = ppit->first; 00384 std::vector<Idx> b = pop; 00385 push = ppit->second; 00386 Idx qi = transit->X1; 00387 Idx qj = transit->X2; 00388 Idx a = transit->Ev; 00389 00390 //read transition (qi,a,b,b,qj) 00391 if(!pd.IsEventLambda(transit->Ev)){ 00392 00393 //insert production (qi,b) --> a(qj,b) 00394 Nonterminal ntLhs(qi,b); 00395 Terminal* t = new Terminal(a); 00396 GrammarSymbolPtr tPtr(t); 00397 Nonterminal* ntRhs = new Nonterminal(qj,b); 00398 GrammarSymbolPtr ntRhsPtr(ntRhs); 00399 //... but only if (qj,b) is reducible 00400 if(rGr.Nonterminals().find(*ntRhs) != rGr.NonterminalsEnd()){ 00401 00402 //save lhs nonterminal as reducible 00403 rGr.InsNonterminal(ntLhs); 00404 00405 //insert production 00406 rhs.clear(); 00407 rhs.push_back(tPtr); 00408 rhs.push_back(ntRhsPtr); 00409 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00410 //std::cout << "inserting " << GrammarProduction(ntLhs,rhs).Str() << std::endl; 00411 } 00412 00413 //for every state qt 00414 for(stateit1 = pd.StatesBegin(); stateit1 != pd.StatesEnd(); stateit1++){ 00415 00416 Idx qt = *stateit1; 00417 00418 //insert production (qi,b,qt) --> a (qj,b,qt) 00419 Nonterminal ntLhs(qi,b,qt); 00420 Nonterminal* ntRhs = new Nonterminal(qj,b,qt); 00421 //... but only if (qj,b,qt) is reducible 00422 if(rGr.Nonterminals().find(*ntRhs) != rGr.NonterminalsEnd()){ 00423 00424 //save lhs nonterminal as reducible 00425 rGr.InsNonterminal(ntLhs); 00426 00427 //insert production 00428 GrammarSymbolPtr ntRhsPtr(ntRhs); 00429 rhs.clear(); 00430 rhs.push_back(tPtr); 00431 rhs.push_back(ntRhsPtr); 00432 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00433 //std::cout << "inserting " << GrammarProduction(ntLhs,rhs).Str() << std::endl; 00434 } 00435 } 00436 } 00437 else{ 00438 00439 //pop transition (qi,lambda,b,lambda,qj) 00440 if(pd.IsStackSymbolLambda(push.front())){ 00441 00442 //save lhs nonterminal as reducible 00443 Nonterminal ntLhs(qi,b,qj); 00444 rGr.InsNonterminal(ntLhs); 00445 00446 //insert production (qi,b,qj) --> lambda 00447 Terminal* t = new Terminal(transit->Ev); 00448 GrammarSymbolPtr tPtr(t); 00449 rhs.clear(); 00450 rhs.push_back(tPtr); 00451 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00452 //std::cout << " inserting " << GrammarProduction(ntLhs,rhs).Str() << std::endl; 00453 } 00454 00455 //push transition (qi,lambda,b,cb,qj) 00456 else if(push.size() == 2){ 00457 00458 std::vector<Idx> c; 00459 c.push_back(push.front()); 00460 00461 //insert production (qi,b) --> (qj,c) 00462 Nonterminal ntLhs(qi,b); 00463 Nonterminal* ntRhs = new Nonterminal(qj,c); 00464 GrammarSymbolPtr ntRhsPtr(ntRhs); 00465 //... but only if (qj,c) is reducible 00466 if(rGr.Nonterminals().find(*ntRhs) != rGr.NonterminalsEnd()){ 00467 00468 //save lhs nonterminal as reducible 00469 rGr.InsNonterminal(ntLhs); 00470 00471 //insert production 00472 rhs.clear(); 00473 rhs.push_back(ntRhsPtr); 00474 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00475 //std::cout << "inserting " << GrammarProduction(ntLhs,rhs).Str() << std::endl; 00476 } 00477 00478 //for every state qs 00479 for(stateit1 = pd.StatesBegin(); stateit1 != pd.StatesEnd(); stateit1++){ 00480 00481 Idx qs = *stateit1; 00482 00483 //insert production (qi,b) --> (qj,c,qs)(qs,b) 00484 Nonterminal ntLhs(qi,b); 00485 Nonterminal* ntRhs1 = new Nonterminal(qj,c,qs); 00486 GrammarSymbolPtr ntRhs1Ptr(ntRhs1); 00487 Nonterminal* ntRhs2 = new Nonterminal(qs,b); 00488 GrammarSymbolPtr ntRhs2Ptr(ntRhs2); 00489 //... but only if (qj,c,qs) and (qs,b) are reducible 00490 if(rGr.Nonterminals().find(*ntRhs1) != rGr.NonterminalsEnd() && 00491 rGr.Nonterminals().find(*ntRhs2) != rGr.NonterminalsEnd()){ 00492 00493 //save lhs nonterminal as reducible 00494 rGr.InsNonterminal(ntLhs); 00495 00496 //insert production 00497 rhs.clear(); 00498 rhs.push_back(ntRhs1Ptr); 00499 rhs.push_back(ntRhs2Ptr); 00500 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00501 //std::cout << "inserting " << GrammarProduction(ntLhs,rhs).Str() << std::endl; 00502 } 00503 00504 //for every state qt 00505 for(stateit2 = pd.StatesBegin(); stateit2 != pd.StatesEnd(); stateit2++){ 00506 00507 Idx qt = *stateit2; 00508 00509 //insert production (qi,b,qt) --> (qj,c,qs)(qs,b,qt) 00510 Nonterminal ntLhs(qi,b,qt); 00511 Nonterminal* ntRhs1 = new Nonterminal(qj,c,qs); 00512 GrammarSymbolPtr ntRhs1Ptr(ntRhs1); 00513 Nonterminal* ntRhs2 = new Nonterminal(qs,b,qt); 00514 GrammarSymbolPtr ntRhs2Ptr(ntRhs2); 00515 //... but only if (qj,c,qs) and (qs,b,qt) are reducible 00516 if(rGr.Nonterminals().find(*ntRhs1) != rGr.NonterminalsEnd() && 00517 rGr.Nonterminals().find(*ntRhs2) != rGr.NonterminalsEnd()){ 00518 00519 //save lhs nonterminal as reducible 00520 rGr.InsNonterminal(ntLhs); 00521 00522 //insert production 00523 rhs.clear(); 00524 rhs.push_back(ntRhs1Ptr); 00525 rhs.push_back(ntRhs2Ptr); 00526 rGr.InsGrammarProduction(GrammarProduction(ntLhs,rhs)); 00527 //std::cout << "inserting " << GrammarProduction(ntLhs,rhs).Str() << std::endl; 00528 } 00529 } 00530 } 00531 } 00532 } 00533 } 00534 } 00535 00536 00537 } 00538 return rGr; 00539 } 00540 00541 /* ************************* 00542 * Rup 00543 * *************************/ 00544 Grammar Rup(const Grammar& gr){ 00545 Grammar rGr; 00546 00547 //copy terminals and start symbol from the old grammar 00548 rGr.InsTerminals(gr.Terminals()); 00549 rGr.SetStartSymbol(gr.StartSymbol()); 00550 00551 std::set<GrammarProduction> todoProductions, reachableProductions; 00552 std::set<GrammarProduction>::const_iterator gpit; 00553 std::set<Nonterminal> usedNonterminals; 00554 00555 //start with the start symbol, which is always used in a grammar 00556 usedNonterminals.insert(gr.StartSymbol()); 00557 00558 //get productions with start symbol as righthand side 00559 for(gpit = gr.GrammarProductionsBegin(); gpit != gr.GrammarProductionsEnd(); gpit++){ 00560 if(gpit->Lhs() == gr.StartSymbol()){ 00561 todoProductions.insert(*gpit); 00562 } 00563 } 00564 00565 //look at all todo productions 00566 while(!todoProductions.empty()){ 00567 00568 //get the current todo production 00569 GrammarProduction currentGp(*todoProductions.begin()); 00570 todoProductions.erase(currentGp); 00571 00572 //since this production was reached, it is a reachable production 00573 reachableProductions.insert(currentGp); 00574 00575 //insert all nonterminals of the current production into set of used nonterminals 00576 std::set<Nonterminal> filtered = Filter(gr.Nonterminals(),currentGp.Rhs()); 00577 usedNonterminals.insert(filtered.begin(), filtered.end()); 00578 00579 //look at all productions 00580 for(gpit = gr.GrammarProductionsBegin(); gpit != gr.GrammarProductionsEnd(); gpit++){ 00581 //if they have any of the used nonterminals on their lefthand side, insert them 00582 //into the todo productions 00583 if(usedNonterminals.find(gpit->Lhs()) != usedNonterminals.end()){ 00584 todoProductions.insert(*gpit); 00585 } 00586 } 00587 00588 //do not look at already reachable productions twice 00589 //this avoids infinite loops 00590 for(gpit = reachableProductions.begin(); gpit != reachableProductions.end(); gpit++){ 00591 todoProductions.erase(*gpit); 00592 } 00593 } 00594 00595 //insert all used nonterminals and all reachable productions 00596 rGr.InsNonterminals(usedNonterminals); 00597 rGr.InsGrammarProductions(reachableProductions); 00598 00599 return rGr; 00600 } 00601 00602 00603 } // namespace faudes 00604 libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |