cfl_symboltable.cpp
Go to the documentation of this file.
1 /** @file cfl_symboltable.cpp @brief Class SymbolTable */
2 
3 /* FAU Discrete Event Systems Library (libfaudes)
4 
5  Copyright (C) 2006 Bernd Opitz
6  Copyright (C) 2007 Thomas Moor
7  Exclusive copyright is granted to Klaus Schmidt
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public
20  License along with this library; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22 
23 
24 #include "cfl_symboltable.h"
25 #include <iostream>
26 
27 namespace faudes {
28 
29 // static symbol table (used for events, should be in Generator)
31 
32 // constructor
34  mMyName("SymbolTable"),
35  mMaxIndex(std::numeric_limits<Idx>::max()),
36  mNextIndex(1) {
37 }
38 
39 // constructor
41  DoAssign(rSrc);
42 }
43 
44 // asignment
46  mMyName=rSrc.mMyName;
47  mIndexMap=rSrc.mIndexMap;
48  mNameMap=rSrc.mNameMap;
49  mMaxIndex=rSrc.mMaxIndex;
51 }
52 
53 
54 // Name()
55 const std::string& SymbolTable::Name(void) const {
56  return mMyName;
57 }
58 
59 //Name(name)
60 void SymbolTable::Name(const std::string& rName) {
61  mMyName = rName;
62 }
63 
64 // Clear()
65 void SymbolTable::Clear(void) {
66  mMaxIndex=std::numeric_limits<Idx>::max();
67  mNextIndex=1;
68  mIndexMap.clear();
69  mNameMap.clear();
70 }
71 
72 // Size()
73 Idx SymbolTable::Size(void) const {
74  return mIndexMap.size();
75 }
76 
77 // MaxIndex()
79  return mMaxIndex;
80 }
81 
82 // MaxIndex(index)
84  if(index <= std::numeric_limits<Idx>::max()) {
85  mMaxIndex = index;
86  return;
87  }
88  std::stringstream errstr;
89  errstr << "symboltable overflow in \"" << mMyName << "\"";
90  throw Exception("SymbolTable::MaxIndex(inde))", errstr.str(), 40);
91 }
92 
93 // LastIndex()
95  return mNextIndex - 1;
96 }
97 
98 // ValidSymbol(rName)
99 bool SymbolTable::ValidSymbol(const std::string& rName) {
100  if(rName=="") return false;
101  for(std::size_t cp=0;cp<rName.size();cp++) {
102  char ch = rName[cp];
103  if(iscntrl(ch)) return false;
104  if(isspace(ch)) return false;
105  if(ch=='"') return false;
106  if(ch=='#') return false;
107  if(isdigit(ch)) continue;
108  if(isalpha(ch)) continue;
109  if(isprint(ch)) continue;
110  return false;
111  }
112  return true;
113 }
114 
115 // UniqueSymbol(rName)
116 std::string SymbolTable::UniqueSymbol(const std::string& rName) const {
117  if(!Exists(rName)) return (rName);
118  long int count=0;
119  std::string name=rName;
120  std::string bname=rName;
121  // if the name ends with extension "_123", remove the extension
122  std::size_t up = bname.find_last_of("_");
123  if(up != std::string::npos) {
124  bool ad=true;
125  for(std::size_t dp=up+1;dp<bname.size();dp++)
126  if(!isdigit(bname[dp])) ad=false;
127  if(ad)
128  bname.erase(up);
129  }
130  // try append extension "_123" until name is unique
131  do {
132  count++;
133  name=bname + "_" + ToStringInteger(count);
134  } while(Exists(name));
135  return name;
136 }
137 
138 
139 // InsEntry(index, rName)
140 Idx SymbolTable::InsEntry(Idx index, const std::string& rName) {
141  if( ! (index <= mMaxIndex)) {
142  std::stringstream errstr;
143  errstr << "symboltable overflow in \"" << mMyName << "\"";
144  throw Exception("SymbolTable::InsEntry(index,name))", errstr.str(), 40);
145  }
146  Idx nidx=Index(rName);
147  if((nidx!=0) && (nidx!=index)) {
148  std::stringstream errstr;
149  errstr << "Name " << rName << " allready exists in \"" << mMyName << "\"";
150  throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 41);
151  }
152  std::string idxname=Symbol(index);
153  if((idxname != "") && (idxname != rName)) {
154  std::stringstream errstr;
155  errstr << "Index " << index << " allready exists in \"" << mMyName << "\"";
156  throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 42);
157  }
158  if(!ValidSymbol(rName)) {
159  std::stringstream errstr;
160  errstr << "Name " << rName << " is not a valid symbol";
161  throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 43);
162  }
163 
164  mIndexMap[rName] = index;
165  mNameMap[index] = rName;
166 
167  if(mNextIndex<=index) mNextIndex=index+1;
168  return index;
169 }
170 
171 // InsEntry(rName)
172 Idx SymbolTable::InsEntry(const std::string& rName) {
173  Idx index=Index(rName);
174  if( index != 0) return index;
175  return InsEntry(mNextIndex,rName);
176 }
177 
178 
179 // SetEntry(index, rName)
180 void SymbolTable::SetEntry(Idx index, const std::string& rName) {
181  if(rName=="") {
182  ClrEntry(index);
183  return;
184  }
185  Idx nidx=Index(rName);
186  if((nidx!=0) && (nidx!=index)) {
187  std::stringstream errstr;
188  errstr << "Name " << rName << " allready exists in \"" << mMyName << "\"";
189  throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 41);
190  }
191  if(!ValidSymbol(rName)) {
192  std::stringstream errstr;
193  errstr << "Name " << rName << " is not a valid symbol";
194  throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 43);
195  }
196  // remove old entry from reverse map
197  std::map<Idx,std::string>::iterator nit = mNameMap.find(index);
198  if(nit != mNameMap.end()) mIndexMap.erase(nit->second);
199  // insert new name/index to maps
200  mIndexMap[rName] = index;
201  mNameMap[index] = rName;
202 }
203 
204 // SetDefaultSymbol(index)
206  ClrEntry(index);
207  std::string dname;
208  dname = UniqueSymbol(ToStringInteger(index));
209  InsEntry(index,dname);
210 }
211 
212 
213 // ClrEntry(index)
215  std::map<Idx,std::string>::iterator it = mNameMap.find(index);
216  if (it == mNameMap.end()) return;
217  mIndexMap.erase(it->second);
218  mNameMap.erase(it);
219 }
220 
221 // ClrEntry(rName)
222 void SymbolTable::ClrEntry(const std::string& rName) {
223  std::map<std::string,Idx>::iterator it = mIndexMap.find(rName);
224  if (it == mIndexMap.end()) return;
225  mNameMap.erase(it->second);
226  mIndexMap.erase(it);
227 }
228 
229 // RestrictDomain(set)
230 void SymbolTable::RestrictDomain(const IndexSet& rDomain) {
231  // trivial cases
232  if(rDomain.Empty()) { Clear(); return;}
233  if(Size()==0) return;
234  // lazy loop (todo: sorted iterate)
235  std::map<Idx,std::string>::iterator it, oit;
236  it = mNameMap.begin();
237  while(it!=mNameMap.end()) {
238  oit=it;
239  it++;
240  if(!rDomain.Exists(oit->first)) mNameMap.erase(oit);
241  }
242 }
243 
244 // Index(rName)
245 Idx SymbolTable::Index(const std::string& rName) const {
246  std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName);
247  if (it == mIndexMap.end())
248  return 0;
249  else
250  return it->second;
251 }
252 
253 // Symbol(index)
254 std::string SymbolTable::Symbol(Idx index) const {
255  std::map<Idx,std::string>::const_iterator it = mNameMap.find(index);
256  if (it == mNameMap.end())
257  return "";
258  else
259  return it->second;
260 }
261 
262 
263 
264 // Exists(index)
265 bool SymbolTable::Exists(Idx index) const {
266  std::map<Idx,std::string>::const_iterator it = mNameMap.find(index);
267  return (it != mNameMap.end());
268 }
269 
270 // Exists(rName)
271 bool SymbolTable::Exists(const std::string& rName) const {
272  std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName);
273  return ( it != mIndexMap.end());
274 }
275 
276 
277 // GlobalEventSymbolTablep
279  return &msEventSymbolTable;
280 }
281 
282 
283 //DoWrite(rTr,rLabel,pContext)
284 void SymbolTable::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const
285 {
286  // default label
287  std::string label=rLabel;
288  if(label=="") label="SymbolTable";
289 
290  // write section
291  rTw.WriteBegin(label);
292 
293  // have two columns
294  int ocol= rTw.Columns();
295  rTw.Columns(2);
296 
297  // iterate over indices
298  std::map< std::string, Idx >::const_iterator sit = mIndexMap.begin();
299  for(; sit != mIndexMap.end();++sit) {
300  rTw.WriteInteger(sit->second);
301  rTw.WriteString(sit->first);
302  }
303 
304  // restore columns
305  rTw.Columns(ocol);
306 
307  // end section
308  rTw.WriteEnd(label);
309 }
310 
311 
312 //DoRead(rTr,rLabel,pContext)
313 void SymbolTable::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
314 
315  // default label
316  std::string label=rLabel;
317  if(label=="") label="SymbolTable";
318 
319  // read section
320  rTr.ReadBegin(label);
321 
322  // iterate section
323  while(!rTr.Eos(label)) {
324  Idx idx = rTr.ReadInteger();
325  std::string sym= rTr.ReadString();
326  InsEntry(idx,sym);
327  }
328 
329  // done
330  rTr.ReadEnd(label);
331 }
332 
333 
334 
335 
336 } // namespace

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen