pd_attributes.cppGo 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 |