pd_attributes.cpp

Go to the documentation of this file.
00001 /** @file pd_attributes.cpp  Attributes for pushdown automata */
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_attributes.h"
00011 namespace faudes {
00012   
00013 /*******************************
00014  * 
00015  * Implementation of AttributePushdownState
00016  *
00017  */
00018 
00019 // faudes type std
00020 FAUDES_TYPE_IMPLEMENTATION(Void,AttributePushdownState,AttributeFlags)
00021 
00022 
00023 AttributePushdownState::~AttributePushdownState(){
00024   if(mpMerge != NULL){
00025     delete mpMerge;
00026   }
00027 }
00028 
00029 void AttributePushdownState::SetMerge(const MergeAbstract& rMerge){
00030   
00031   if(mpMerge != NULL){
00032     delete mpMerge;
00033   }
00034   
00035   //test subtype of pMerge and allocate memory according to subtype
00036   //MergeStates
00037   const MergeStates* ms = dynamic_cast<const MergeStates*>(&rMerge);
00038   if(ms != NULL){
00039     try{
00040       mpMerge = new MergeStates(ms->States());
00041     }
00042     catch (std::bad_alloc& ba){
00043       std::cerr << "bad_alloc caught in AttributePushdownState::SetMerge at new MergeStates(ms->States()): " << ba.what() << std::endl;
00044     }
00045     return;
00046   }
00047   
00048   //MergeStateAnnotation
00049   const MergeStateAnnotation* msa = dynamic_cast<const MergeStateAnnotation*>(&rMerge);
00050   if(msa != NULL){
00051     try{
00052       mpMerge = new MergeStateAnnotation(msa->State(), msa->Annotation());
00053     }
00054     catch (std::bad_alloc& ba){
00055       std::cerr << "bad_alloc caught in AttributePushdownState::SetMerge at new MergeStateAnnotation(msa->State(), msa->Annotation()): " << ba.what() << std::endl;
00056     }
00057     return;
00058   }
00059   
00060   //MergeStateSplit
00061   const MergeStateSplit* mss = dynamic_cast<const MergeStateSplit*>(&rMerge);
00062   if(mss != NULL){
00063     try{
00064       if(mss->IsHead()){
00065         mpMerge = new MergeStateSplit(mss->State());
00066       }
00067       else{
00068         mpMerge = new MergeStateSplit(mss->State(), mss->Symbol());
00069       }
00070     }
00071     catch (std::bad_alloc& ba){
00072       std::cerr << "bad_alloc caught in AttributePushdownState::SetMerge at new MergeStateSplit(mss->Annotation(), mss->State(), mss->Symbol()): " << ba.what() << std::endl;
00073     }
00074     return;
00075   }
00076   
00077   //MergeTransition
00078   const MergeTransition* mt = dynamic_cast<const MergeTransition*>(&rMerge);
00079   if(mt != NULL){
00080     try{
00081       mpMerge = new MergeTransition(mt->X1(), mt->Ev(), mt->X2(), mt->Pop(), mt->Push());
00082     }
00083     catch (std::bad_alloc& ba){
00084       std::cerr << "bad_alloc caught in AttributePushdownState::SetMerge at new MergeTransition(mt->X1(), mt->Ev(), mt->X2(), mt->Pop(), mt->Push()): " << ba.what() << std::endl;
00085     }
00086     return;
00087   }
00088   
00089   //MergeStateEvent
00090   const MergeStateEvent* mse = dynamic_cast<const MergeStateEvent*>(&rMerge);
00091   if(mse != NULL){
00092     try{
00093       mpMerge = new MergeStateEvent(mse->State(), mse->Event());
00094     }
00095     catch (std::bad_alloc& ba){
00096       std::cerr << "bad_alloc caught in AttributePushdownState::SetMerge at new MergeTransition(mt->X1(), mt->Ev(), mt->X2(), mt->Pop(), mt->Push()): " << ba.what() << std::endl;
00097     }
00098     return;
00099   }
00100   
00101   //invalid reference - do nothing
00102   if(&rMerge == NULL){
00103     return;
00104   }
00105   //should never get here
00106   std::stringstream errstr;
00107   errstr << "tried to set MergeAbstract with non-existent subtype " << typeid(rMerge).name() << std::endl;
00108   throw Exception("AttributePushdownState::SetMerge()", errstr.str(), 1002);
00109   return;
00110 }
00111 
00112 // Assign my members
00113 void AttributePushdownState::DoAssign(const AttributePushdownState& rSrcAttr) { 
00114   // call base (incl. virtual clear)
00115   AttributeFlags::DoAssign(rSrcAttr);
00116   // my additional members
00117   this->SetMerge(*(rSrcAttr.mpMerge));
00118   this->DfaState(rSrcAttr.DfaState());
00119   //*(mpMerge)=*(rSrcAttr.mpMerge);
00120 }
00121 
00122 // Equality
00123 bool AttributePushdownState::DoEqual(const AttributePushdownState& rOther) const {
00124   // base
00125   if(!AttributeFlags::DoEqual(rOther)) return false;
00126   // my members
00127   if(mpMerge!=rOther.mpMerge) return false;
00128   // pass
00129   return true;
00130 }
00131 
00132 
00133 //DoWrite(rTw,rLabel,pContext);
00134 void AttributePushdownState::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00135   (void) pContext;
00136   if(IsDefault()) return;
00137   AttributeFlags::DoWrite(rTw,"",pContext);
00138   std::string label=rLabel;
00139   if(label=="") label="State";
00140   FD_DC("AttributePushdownState(" << this << ")::DoWrite(tr): to section " << label);
00141   if(mpMerge != NULL)
00142     mpMerge->Write(rTw,"");//TODO only compile this for debugging
00143 }
00144 
00145 
00146 //DoRead(rTr,rLabel,pContext)
00147 void AttributePushdownState::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00148   // call base first
00149   AttributeFlags::DoRead(rTr,"",pContext);
00150   // figure my section
00151   std::string label=rLabel;
00152   if(label=="") label="State";
00153   FD_DC("AttributePushdownState(" << this << ")::DoRead(tr): from section " << label);
00154   // clear my data
00155   mpMerge = NULL;
00156   // test my section
00157   Token token;
00158   rTr.Peek(token);
00159   if(!token.IsBegin())  return;
00160   if(token.StringValue()!=label) return;
00161   // read my section (can throw exceptions now)
00162   //mInvariant.Read(rTr,label); //TODO read of mpMerge may be not needed since its only intended for debugging
00163 }
00164   
00165 /*******************************
00166  * 
00167  * Implementation of AttributePushdownTransition
00168  *
00169  */
00170 
00171 // faudes type std
00172 FAUDES_TYPE_IMPLEMENTATION(Void,AttributePushdownTransition,AttributeVoid)
00173 
00174 
00175 bool AttributePushdownTransition::ClrPopPush(const std::vector<Idx>& rPop, const std::vector<Idx>& rPush){
00176   
00177   std::pair<std::vector<Idx>,std::vector<Idx> > popPushPair;
00178   popPushPair.first = rPop;
00179   popPushPair.second = rPush;
00180   
00181   int i = mPopPush.erase(popPushPair);
00182   if(i != 0){
00183     return true;
00184   }
00185   return false;
00186 }
00187 
00188 // Assign my members
00189 void AttributePushdownTransition::DoAssign(const AttributePushdownTransition& rSrcAttr) { 
00190   // call base (incl. virtual clear)
00191   AttributeVoid::DoAssign(rSrcAttr);
00192   // my additional members
00193   mPopPush=rSrcAttr.mPopPush;
00194 }
00195 
00196 // Equality
00197 bool AttributePushdownTransition::DoEqual(const AttributePushdownTransition& rOther) const {
00198   // my members
00199   if(mPopPush!=rOther.mPopPush) return false;
00200   // pass
00201   return true;
00202 }
00203 
00204 
00205 //DoWrite(rTw,rLabel,pContext);
00206 void AttributePushdownTransition::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00207   if(IsDefault()) return;
00208   std::string label=rLabel;
00209   FD_DC("AttributePushdownTransition(" << this << ")::DoWrite(tr): to section " << label);
00210   if(label=="") label="PopPushes";
00211   
00212   Token token;
00213   int oldcolumns = rTw.Columns();
00214   rTw.Columns(8);
00215   
00216   // begin section commands
00217   token.SetBegin(label);
00218   rTw << token;
00219   
00220   //iterate over all PopPushPairs
00221   PopPushSet::const_iterator setit;
00222   std::vector<Idx>::const_iterator popit, pushit;
00223   std::vector<Idx> pop, push;
00224   for(setit = mPopPush.begin(); setit != mPopPush.end(); setit++){
00225     
00226     token.SetBegin("PopPush");
00227     rTw << token;
00228 
00229     //write pop
00230     pop = setit->first;
00231     for(popit=pop.begin();popit != pop.end();popit++){
00232       
00233       token.SetBegin("Pop");
00234       token.InsAttributeString("name", StackSymbolSet::StaticSymbolTablep()->Symbol(*popit));
00235       rTw << token;
00236       
00237       token.SetEnd("Pop");
00238       rTw << token;
00239     }
00240     
00241     //write push
00242     push = setit->second;
00243     for(pushit=push.begin();pushit != push.end();pushit++){
00244       
00245       token.SetBegin("Push");
00246       token.InsAttributeString("name", StackSymbolSet::StaticSymbolTablep()->Symbol(*pushit));
00247       rTw << token;
00248       
00249       token.SetEnd("Push");
00250       rTw << token;
00251     }
00252     
00253     token.SetEnd("PopPush");
00254     rTw << token;
00255   }
00256   
00257     // commands
00258   token.SetEnd(label);
00259   rTw << token;
00260  
00261   rTw.Columns(oldcolumns);
00262 }
00263 
00264 
00265 //DoRead(rTr,rLabel,pContext)
00266 void AttributePushdownTransition::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00267   // find my section
00268   std::string label=rLabel;
00269   if(label=="") label="PopPushes";
00270   FD_DC("AttributePushdownTransition(" << this << ")::DoRead(tr): from section " << label);
00271   // initialise my data
00272   mPopPush.clear();
00273   // test for  my data
00274   Token token;
00275   rTr.Peek(token);
00276   if(!token.IsBegin(label)) return;
00277   
00278   std::string symbol;
00279   std::vector<Idx> pop, push;
00280   // read my section
00281   rTr.ReadBegin(label);
00282   while(!rTr.Eos(label)) {
00283     // read token
00284     rTr.Peek(token);
00285     // skip other than command
00286     if(!token.IsBegin("PopPush")) {
00287        rTr.Get(token);
00288        continue;
00289     }
00290     
00291     // ok, its a command section
00292     rTr.ReadBegin("PopPush");
00293     
00294     pop.clear();
00295     push.clear();
00296     
00297     StackSymbolSet ssSet;
00298     while(rTr.Peek(token)){
00299       
00300       //read pop
00301       if(token.IsBegin("Pop")){
00302         
00303         rTr.ReadBegin("Pop");
00304         symbol = token.AttributeStringValue("name");
00305         ssSet.Insert(symbol); //for generating stack symbol indices
00306         pop.push_back(StackSymbolSet::StaticSymbolTablep()->Index(symbol));
00307         rTr.ReadEnd("Pop");
00308       }
00309       
00310       //read push
00311       else if(token.IsBegin("Push")){
00312         
00313         rTr.ReadBegin("Push");
00314         symbol = token.AttributeStringValue("name");
00315         ssSet.Insert(symbol); ssSet.Insert(symbol); //for generating stack symbol indices
00316         push.push_back(StackSymbolSet::StaticSymbolTablep()->Index(symbol));
00317         rTr.ReadEnd("Push");
00318       }
00319       
00320       //stop if end of section
00321       else if(token.IsEnd("PopPush")){
00322         
00323         //insert
00324         mPopPush.insert(std::make_pair(pop,push));
00325         break;
00326       }
00327     }
00328     
00329 //     // end section command 
00330     rTr.ReadEnd("PopPush");
00331     // 3:
00332 //     std::stringstream errstr;
00333 //     errstr << "invalid transition timing" << rTr.FileLine();
00334 //     throw Exception("AttributeTimedTrans::Read", errstr.str(), 52);
00335   }
00336   rTr.ReadEnd(label);
00337 }
00338 
00339   
00340   /*******************************
00341   * 
00342   * Implementation of AttributePushdownGlobal
00343   *
00344   */
00345 
00346   // faudes type std
00347   FAUDES_TYPE_IMPLEMENTATION(Void,AttributePushdownGlobal,AttributeVoid)
00348 
00349   // Assign my members
00350   void AttributePushdownGlobal::DoAssign(const AttributePushdownGlobal& rSrcAttr) { 
00351     // call base (incl. virtual clear)
00352     AttributeVoid::DoAssign(rSrcAttr);
00353     // my additional members
00354      mStackSymbols=rSrcAttr.mStackSymbols;
00355      mpStackSymbolTable=rSrcAttr.mpStackSymbolTable;
00356      mStackBottom = rSrcAttr.mStackBottom;
00357   }
00358 
00359   // Equality
00360   bool AttributePushdownGlobal::DoEqual(const AttributePushdownGlobal& rOther) const {
00361     // my members
00362      if(mStackSymbols!=rOther.mStackSymbols) return false;
00363     // pass
00364     return true;
00365   }
00366 
00367   //DoWrite(rTw,rLabel,pContext);
00368   void AttributePushdownGlobal::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00369     (void) pContext;
00370     if(IsDefault()) return;
00371     std::string label=rLabel;
00372     if(label=="") label="StackSymbols";
00373     FD_DC("AttributePushdownGlobal(" << this << ")::DoWrite(tr): to section " << label);
00374     mStackSymbols.XWrite(rTw,label);
00375     
00376     Token token;
00377     token.SetBegin("StackBottom");
00378     token.InsAttributeString("name", StackSymbolSet::StaticSymbolTablep()->Symbol(mStackBottom));
00379     rTw << token;
00380     
00381     token.SetEnd("StackBottom");
00382     rTw << token;
00383   }
00384 
00385   //DoRead(rTr,rLabel,pContext)
00386   void AttributePushdownGlobal::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00387     std::string label=rLabel;
00388     if(label=="") label="StackSymbols";
00389     FD_DC("AttributePushdownGlobal(" << this << ")::DoRead(tr): from section " << label);
00390     (void) pContext;
00391     mStackSymbols.Clear();
00392     Token token;
00393     rTr.Peek(token);
00394     if(!token.IsBegin())  return;
00395     if(token.StringValue() == label){ 
00396       mStackSymbols.Read(rTr,label);
00397     }
00398     
00399     
00400     rTr.Peek(token);
00401     if(token.StringValue() == "StackBottom"){ 
00402       rTr.ReadBegin("StackBottom");
00403       std::string symbol = token.AttributeStringValue("name");
00404       StackSymbolSet ssSet;
00405       ssSet.Insert(symbol);
00406       mStackBottom = StackSymbolSet::StaticSymbolTablep()->Index(symbol);
00407       rTr.ReadEnd("StackBottom");
00408     }
00409   }
00410 
00411 
00412 
00413 } // namespace faudes
00414 

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen