pd_alg_nb_sub_a.cpp

Go 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