pd_attributes.cpp
Go to the documentation of this file.
1 /** @file pd_attributes.cpp Attributes for pushdown automata */
2 
3 
4 /* Pushdown plugin for FAU Discrete Event Systems Library (libfaudes)
5 
6  Copyright (C) 2013 Stefan Jacobi, Sven Schneider, Anne-Kathrin Hess
7 
8 */
9 
10 #include "pd_attributes.h"
11 namespace faudes {
12 
13 /*******************************
14  *
15  * Implementation of AttributePushdownState
16  *
17  */
18 
19 // faudes type std
20 FAUDES_TYPE_IMPLEMENTATION(Void,AttributePushdownState,AttributeFlags)
21 
22 
24  if(mpMerge != NULL){
25  delete mpMerge;
26  }
27 }
28 
30 
31  if(mpMerge != NULL){
32  delete mpMerge;
33  mpMerge = NULL;
34  }
35 
36  //test subtype of pMerge and allocate memory according to subtype
37  //MergeStates
38  const MergeStates* ms = dynamic_cast<const MergeStates*>(pMerge);
39  if(ms != NULL){
40  try{
41  mpMerge = new MergeStates(ms->States());
42  }
43  catch (std::bad_alloc& ba){
44  std::cerr << "bad_alloc caught in AttributePushdownState::SetMerge at new MergeStates(ms->States()): " << ba.what() << std::endl;
45  }
46  return;
47  }
48 
49  //MergeStateAnnotation
50  const MergeStateAnnotation* msa = dynamic_cast<const MergeStateAnnotation*>(pMerge);
51  if(msa != NULL){
52  try{
53  mpMerge = new MergeStateAnnotation(msa->State(), msa->Annotation());
54  }
55  catch (std::bad_alloc& ba){
56  std::cerr << "bad_alloc caught in AttributePushdownState::SetMerge at new MergeStateAnnotation(msa->State(), msa->Annotation()): " << ba.what() << std::endl;
57  }
58  return;
59  }
60 
61  //MergeStateSplit
62  const MergeStateSplit* mss = dynamic_cast<const MergeStateSplit*>(pMerge);
63  if(mss != NULL){
64  try{
65  if(mss->IsHead()){
66  mpMerge = new MergeStateSplit(mss->State());
67  }
68  else{
69  mpMerge = new MergeStateSplit(mss->State(), mss->Symbol());
70  }
71  }
72  catch (std::bad_alloc& ba){
73  std::cerr << "bad_alloc caught in AttributePushdownState::SetMerge at new MergeStateSplit(mss->Annotation(), mss->State(), mss->Symbol()): " << ba.what() << std::endl;
74  }
75  return;
76  }
77 
78  //MergeTransition
79  const MergeTransition* mt = dynamic_cast<const MergeTransition*>(pMerge);
80  if(mt != NULL){
81  try{
82  mpMerge = new MergeTransition(mt->X1(), mt->Ev(), mt->X2(), mt->Pop(), mt->Push());
83  }
84  catch (std::bad_alloc& ba){
85  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;
86  }
87  return;
88  }
89 
90  //MergeStateEvent
91  const MergeStateEvent* mse = dynamic_cast<const MergeStateEvent*>(pMerge);
92  if(mse != NULL){
93  try{
94  mpMerge = new MergeStateEvent(mse->State(), mse->Event());
95  }
96  catch (std::bad_alloc& ba){
97  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;
98  }
99  return;
100  }
101 
102  //invalid reference - do nothing
103  if(pMerge == NULL){
104  return;
105  }
106  //should never get here
107  std::stringstream errstr;
108  errstr << "tried to set MergeAbstract with non-existent subtype " << typeid(*pMerge).name() << std::endl;
109  throw Exception("AttributePushdownState::SetMerge()", errstr.str(), 1002);
110  return;
111 }
112 
113 // Assign my members
115  // call base (incl. virtual clear)
116  AttributeFlags::DoAssign(rSrcAttr);
117  // my additional members
118  this->SetMerge(rSrcAttr.mpMerge);
119  this->DfaState(rSrcAttr.DfaState());
120  //*(mpMerge)=*(rSrcAttr.mpMerge);
121 }
122 
123 // Equality
125  // base
126  if(!AttributeFlags::DoEqual(rOther)) return false;
127  // my members
128  if(mpMerge!=rOther.mpMerge) return false;
129  // pass
130  return true;
131 }
132 
133 
134 //DoWrite(rTw,rLabel,pContext);
135 void AttributePushdownState::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
136  (void) pContext;
137  if(IsDefault()) return;
138  AttributeFlags::DoWrite(rTw,"",pContext);
139  std::string label=rLabel;
140  if(label=="") label="State";
141  FD_DC("AttributePushdownState(" << this << ")::DoWrite(tr): to section " << label);
142  if(mpMerge != NULL)
143  mpMerge->Write(rTw,"");//TODO only compile this for debugging
144 }
145 
146 
147 //DoRead(rTr,rLabel,pContext)
148 void AttributePushdownState::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
149  // call base first
150  AttributeFlags::DoRead(rTr,"",pContext);
151  // figure my section
152  std::string label=rLabel;
153  if(label=="") label="State";
154  FD_DC("AttributePushdownState(" << this << ")::DoRead(tr): from section " << label);
155  // clear my data
156  mpMerge = NULL;
157  // test my section
158  Token token;
159  rTr.Peek(token);
160  if(!token.IsBegin()) return;
161  if(token.StringValue()!=label) return;
162  // read my section (can throw exceptions now)
163  //mInvariant.Read(rTr,label); //TODO read of mpMerge may be not needed since its only intended for debugging
164 }
165 
166 /*******************************
167  *
168  * Implementation of AttributePushdownTransition
169  *
170  */
171 
172 // faudes type std
174 
175 
176 bool AttributePushdownTransition::ClrPopPush(const std::vector<Idx>& rPop, const std::vector<Idx>& rPush){
177 
178  std::pair<std::vector<Idx>,std::vector<Idx> > popPushPair;
179  popPushPair.first = rPop;
180  popPushPair.second = rPush;
181 
182  int i = mPopPush.erase(popPushPair);
183  if(i != 0){
184  return true;
185  }
186  return false;
187 }
188 
189 // Assign my members
191  // call base (incl. virtual clear)
192  AttributeVoid::DoAssign(rSrcAttr);
193  // my additional members
194  mPopPush=rSrcAttr.mPopPush;
195 }
196 
197 // Equality
199  // my members
200  if(mPopPush!=rOther.mPopPush) return false;
201  // pass
202  return true;
203 }
204 
205 
206 //DoWrite(rTw,rLabel,pContext);
207 void AttributePushdownTransition::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
208  if(IsDefault()) return;
209  std::string label=rLabel;
210  FD_DC("AttributePushdownTransition(" << this << ")::DoWrite(tr): to section " << label);
211  if(label=="") label="PopPushes";
212 
213  Token token;
214  int oldcolumns = rTw.Columns();
215  rTw.Columns(8);
216 
217  // begin section commands
218  token.SetBegin(label);
219  rTw << token;
220 
221  //iterate over all PopPushPairs
222  PopPushSet::const_iterator setit;
223  std::vector<Idx>::const_iterator popit, pushit;
224  std::vector<Idx> pop, push;
225  for(setit = mPopPush.begin(); setit != mPopPush.end(); setit++){
226 
227  token.SetBegin("PopPush");
228  rTw << token;
229 
230  //write pop
231  pop = setit->first;
232  for(popit=pop.begin();popit != pop.end();popit++){
233 
234  token.SetBegin("Pop");
235  token.InsAttributeString("name", StackSymbolSet::StaticSymbolTablep()->Symbol(*popit));
236  rTw << token;
237 
238  token.SetEnd("Pop");
239  rTw << token;
240  }
241 
242  //write push
243  push = setit->second;
244  for(pushit=push.begin();pushit != push.end();pushit++){
245 
246  token.SetBegin("Push");
247  token.InsAttributeString("name", StackSymbolSet::StaticSymbolTablep()->Symbol(*pushit));
248  rTw << token;
249 
250  token.SetEnd("Push");
251  rTw << token;
252  }
253 
254  token.SetEnd("PopPush");
255  rTw << token;
256  }
257 
258  // commands
259  token.SetEnd(label);
260  rTw << token;
261 
262  rTw.Columns(oldcolumns);
263 }
264 
265 
266 //DoRead(rTr,rLabel,pContext)
267 void AttributePushdownTransition::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
268  // find my section
269  std::string label=rLabel;
270  if(label=="") label="PopPushes";
271  FD_DC("AttributePushdownTransition(" << this << ")::DoRead(tr): from section " << label);
272  // initialise my data
273  mPopPush.clear();
274  // test for my data
275  Token token;
276  rTr.Peek(token);
277  if(!token.IsBegin(label)) return;
278 
279  std::string symbol;
280  std::vector<Idx> pop, push;
281  // read my section
282  rTr.ReadBegin(label);
283  while(!rTr.Eos(label)) {
284  // read token
285  rTr.Peek(token);
286  // skip other than command
287  if(!token.IsBegin("PopPush")) {
288  rTr.Get(token);
289  continue;
290  }
291 
292  // ok, its a command section
293  rTr.ReadBegin("PopPush");
294 
295  pop.clear();
296  push.clear();
297 
298  StackSymbolSet ssSet;
299  while(rTr.Peek(token)){
300 
301  //read pop
302  if(token.IsBegin("Pop")){
303 
304  rTr.ReadBegin("Pop");
305  symbol = token.AttributeStringValue("name");
306  ssSet.Insert(symbol); //for generating stack symbol indices
307  pop.push_back(StackSymbolSet::StaticSymbolTablep()->Index(symbol));
308  rTr.ReadEnd("Pop");
309  }
310 
311  //read push
312  else if(token.IsBegin("Push")){
313 
314  rTr.ReadBegin("Push");
315  symbol = token.AttributeStringValue("name");
316  ssSet.Insert(symbol); ssSet.Insert(symbol); //for generating stack symbol indices
317  push.push_back(StackSymbolSet::StaticSymbolTablep()->Index(symbol));
318  rTr.ReadEnd("Push");
319  }
320 
321  //stop if end of section
322  else if(token.IsEnd("PopPush")){
323 
324  //insert
325  mPopPush.insert(std::make_pair(pop,push));
326  break;
327  }
328  }
329 
330 // // end section command
331  rTr.ReadEnd("PopPush");
332  // 3:
333 // std::stringstream errstr;
334 // errstr << "invalid transition timing" << rTr.FileLine();
335 // throw Exception("AttributeTimedTrans::Read", errstr.str(), 52);
336  }
337  rTr.ReadEnd(label);
338 }
339 
340 
341  /*******************************
342  *
343  * Implementation of AttributePushdownGlobal
344  *
345  */
346 
347  // faudes type std
349 
350  // Assign my members
351  void AttributePushdownGlobal::DoAssign(const AttributePushdownGlobal& rSrcAttr) {
352  FD_DG("AttributePushdownGlobal::DoAssign("<<this<<"): src " << &rSrcAttr << " type " << typeid(rSrcAttr).name());
353  // call base (incl. virtual clear)
354  AttributeVoid::DoAssign(rSrcAttr);
355  // my additional members
356  mStackSymbols=rSrcAttr.mStackSymbols;
357  mpStackSymbolTable=rSrcAttr.mpStackSymbolTable;
358  mStackBottom = rSrcAttr.mStackBottom;
359  }
360 
361  // Equality
363  // my members
364  if(mStackSymbols!=rOther.mStackSymbols) return false;
365  // pass
366  return true;
367  }
368 
369  //DoWrite(rTw,rLabel,pContext);
370  void AttributePushdownGlobal::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
371  (void) pContext;
372  if(IsDefault()) return;
373  std::string label=rLabel;
374  if(label=="") label="StackSymbols";
375  FD_DC("AttributePushdownGlobal(" << this << ")::DoWrite(tr): to section " << label);
376  mStackSymbols.XWrite(rTw,label);
377 
378  Token token;
379  token.SetBegin("StackBottom");
381  rTw << token;
382 
383  token.SetEnd("StackBottom");
384  rTw << token;
385  }
386 
387  //DoRead(rTr,rLabel,pContext)
388  void AttributePushdownGlobal::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
389  std::string label=rLabel;
390  if(label=="") label="StackSymbols";
391  FD_DC("AttributePushdownGlobal(" << this << ")::DoRead(tr): from section " << label);
392  (void) pContext;
394  Token token;
395  rTr.Peek(token);
396  if(!token.IsBegin()) return;
397  if(token.StringValue() == label){
398  mStackSymbols.Read(rTr,label);
399  }
400 
401 
402  rTr.Peek(token);
403  if(token.StringValue() == "StackBottom"){
404  rTr.ReadBegin("StackBottom");
405  std::string symbol = token.AttributeStringValue("name");
406  StackSymbolSet ssSet;
407  ssSet.Insert(symbol);
409  rTr.ReadEnd("StackBottom");
410  }
411  }
412 
413 
414 
415 } // namespace faudes
416 

libFAUDES 2.28c --- 2016.09.30 --- c++ api documentaion by doxygen