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 
30 // constructor
32  mMyName("SymbolTable"),
33  mMaxIndex(std::numeric_limits<Idx>::max()),
34  mNextIndex(1) {
35 }
36 
37 // constructor
39  DoAssign(rSrc);
40 }
41 
42 // asignment
44  mMyName=rSrc.mMyName;
45  mIndexMap=rSrc.mIndexMap;
46  mNameMap=rSrc.mNameMap;
47  mMaxIndex=rSrc.mMaxIndex;
49 }
50 
51 
52 // Name()
53 const std::string& SymbolTable::Name(void) const {
54  return mMyName;
55 }
56 
57 //Name(name)
58 void SymbolTable::Name(const std::string& rName) {
59  mMyName = rName;
60 }
61 
62 // Clear()
63 void SymbolTable::Clear(void) {
64  mMaxIndex=std::numeric_limits<Idx>::max();
65  mNextIndex=1;
66  mIndexMap.clear();
67  mNameMap.clear();
68 }
69 
70 // Size()
71 Idx SymbolTable::Size(void) const {
72  return mIndexMap.size();
73 }
74 
75 // MaxIndex()
77  return mMaxIndex;
78 }
79 
80 // MaxIndex(index)
82  if(index <= std::numeric_limits<Idx>::max()) {
83  mMaxIndex = index;
84  return;
85  }
86  std::stringstream errstr;
87  errstr << "symboltable overflow in \"" << mMyName << "\"";
88  throw Exception("SymbolTable::MaxIndex(inde))", errstr.str(), 40);
89 }
90 
91 // LastIndex()
93  return mNextIndex - 1;
94 }
95 
96 // ValidSymbol(rName)
97 bool SymbolTable::ValidSymbol(const std::string& rName) {
98  if(rName=="") return false;
99  for(std::size_t cp=0;cp<rName.size();cp++) {
100  char ch = rName[cp];
101  if(iscntrl(ch)) return false;
102  if(isspace(ch)) return false;
103  if(ch=='"') return false;
104  if(ch=='#') return false;
105  if(isdigit(ch)) continue;
106  if(isalpha(ch)) continue;
107  if(isprint(ch)) continue;
108  return false;
109  }
110  return true;
111 }
112 
113 // UniqueSymbol(rName)
114 std::string SymbolTable::UniqueSymbol(const std::string& rName) const {
115  if(!Exists(rName)) return (rName);
116  long int count=0;
117  std::string name=rName;
118  std::string bname=rName;
119  // if the name ends with extension "_123", remove the extension
120  std::size_t up = bname.find_last_of("_");
121  if(up != std::string::npos) {
122  bool ad=true;
123  for(std::size_t dp=up+1;dp<bname.size();dp++)
124  if(!isdigit(bname[dp])) ad=false;
125  if(ad)
126  bname.erase(up);
127  }
128  // try append extension "_123" until name is unique
129  do {
130  count++;
131  name=bname + "_" + ToStringInteger(count);
132  } while(Exists(name));
133  return name;
134 }
135 
136 
137 // InsEntry(index, rName)
138 Idx SymbolTable::InsEntry(Idx index, const std::string& rName) {
139  if( ! (index <= mMaxIndex)) {
140  std::stringstream errstr;
141  errstr << "symboltable overflow in \"" << mMyName << "\"";
142  throw Exception("SymbolTable::InsEntry(index,name))", errstr.str(), 40);
143  }
144  Idx nidx=Index(rName);
145  if((nidx!=0) && (nidx!=index)) {
146  std::stringstream errstr;
147  errstr << "Name " << rName << " allready exists in \"" << mMyName << "\"";
148  throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 41);
149  }
150  std::string idxname=Symbol(index);
151  if((idxname != "") && (idxname != rName)) {
152  std::stringstream errstr;
153  errstr << "Index " << index << " allready exists in \"" << mMyName << "\"";
154  throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 42);
155  }
156  if(!ValidSymbol(rName)) {
157  std::stringstream errstr;
158  errstr << "Name " << rName << " is not a valid symbol";
159  throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 43);
160  }
161 
162  mIndexMap[rName] = index;
163  mNameMap[index] = rName;
164 
165  if(mNextIndex<=index) mNextIndex=index+1;
166  return index;
167 }
168 
169 // InsEntry(rName)
170 Idx SymbolTable::InsEntry(const std::string& rName) {
171  Idx index=Index(rName);
172  if( index != 0) return index;
173  return InsEntry(mNextIndex,rName);
174 }
175 
176 
177 // SetEntry(index, rName)
178 void SymbolTable::SetEntry(Idx index, const std::string& rName) {
179  if(rName=="") {
180  ClrEntry(index);
181  return;
182  }
183  Idx nidx=Index(rName);
184  if((nidx!=0) && (nidx!=index)) {
185  std::stringstream errstr;
186  errstr << "Name " << rName << " allready exists in \"" << mMyName << "\"";
187  throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 41);
188  }
189  if(!ValidSymbol(rName)) {
190  std::stringstream errstr;
191  errstr << "Name " << rName << " is not a valid symbol";
192  throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 43);
193  }
194  // remove old entry from reverse map
195  std::map<Idx,std::string>::iterator nit = mNameMap.find(index);
196  if(nit != mNameMap.end()) mIndexMap.erase(nit->second);
197  // insert new name/index to maps
198  mIndexMap[rName] = index;
199  mNameMap[index] = rName;
200 }
201 
202 // SetDefaultSymbol(index)
204  ClrEntry(index);
205  std::string dname;
206  dname = UniqueSymbol(ToStringInteger(index));
207  InsEntry(index,dname);
208 }
209 
210 
211 // ClrEntry(index)
213  std::map<Idx,std::string>::iterator it = mNameMap.find(index);
214  if (it == mNameMap.end()) return;
215  mIndexMap.erase(it->second);
216  mNameMap.erase(it);
217 }
218 
219 // ClrEntry(rName)
220 void SymbolTable::ClrEntry(const std::string& rName) {
221  std::map<std::string,Idx>::iterator it = mIndexMap.find(rName);
222  if (it == mIndexMap.end()) return;
223  mNameMap.erase(it->second);
224  mIndexMap.erase(it);
225 }
226 
227 // RestrictDomain(set)
228 void SymbolTable::RestrictDomain(const IndexSet& rDomain) {
229  // trivial cases
230  if(rDomain.Empty()) { Clear(); return;}
231  if(Size()==0) return;
232  // lazy loop (todo: sorted iterate)
233  std::map<Idx,std::string>::iterator it, oit;
234  it = mNameMap.begin();
235  while(it!=mNameMap.end()) {
236  oit=it;
237  it++;
238  if(!rDomain.Exists(oit->first)) mNameMap.erase(oit);
239  }
240 }
241 
242 // Index(rName)
243 Idx SymbolTable::Index(const std::string& rName) const {
244  std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName);
245  if (it == mIndexMap.end())
246  return 0;
247  else
248  return it->second;
249 }
250 
251 // Symbol(index)
252 std::string SymbolTable::Symbol(Idx index) const {
253  std::map<Idx,std::string>::const_iterator it = mNameMap.find(index);
254  if (it == mNameMap.end())
255  return "";
256  else
257  return it->second;
258 }
259 
260 
261 
262 // Exists(index)
263 bool SymbolTable::Exists(Idx index) const {
264  std::map<Idx,std::string>::const_iterator it = mNameMap.find(index);
265  return (it != mNameMap.end());
266 }
267 
268 // Exists(rName)
269 bool SymbolTable::Exists(const std::string& rName) const {
270  std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName);
271  return ( it != mIndexMap.end());
272 }
273 
274 
275 // GlobalEventSymbolTablep
276 // (initialize on first use pattern)
278  static SymbolTable fls;
279  return &fls;
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
Class SymbolTable.
Faudes exception class.
Set of indices.
Definition: cfl_indexset.h:78
A SymbolTable associates sybolic names with indices.
void RestrictDomain(const IndexSet &rDomain)
Restrict to specified indicees.
Idx mNextIndex
Largest used index + 1.
std::map< Idx, std::string > mNameMap
Name lookup map.
void SetDefaultSymbol(Idx index)
Set default names ("1", "2", "3", ...) for index.
Idx LastIndex(void) const
Get the largest index in use.
std::map< std::string, Idx > mIndexMap
Index lookup map.
Idx mMaxIndex
Upper limit (incl)
static SymbolTable * GlobalEventSymbolTablep(void)
Get Static Symboltable ref (initialize on first use pattern)
std::string Symbol(Idx index) const
Symbolic name lookup.
void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Symboltable token io.
const std::string & Name(void) const
Return name of SymbolTable.
void Clear(void)
Clear all entries.
static bool ValidSymbol(const std::string &rName)
Test validiy of candidate symbol.
Idx MaxIndex(void) const
Get maximum index which this SymbolTable accepts.
void ClrEntry(Idx index)
Delete entry by index.
void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
Symboltable token io.
bool Exists(Idx index) const
Test existence of index.
void DoAssign(const SymbolTable &rSrc)
assign my members
std::string UniqueSymbol(const std::string &rName) const
Create unique symbolic name by adding an underscore and extra digits.
void SetEntry(Idx index, const std::string &rName)
Set symbolic name for existing entry.
SymbolTable(void)
Creates a new SymbolTable.
Idx InsEntry(Idx index, const std::string &rName)
Add new entry (aka symbolic name and index) to symboltable,.
Idx Size(void) const
Size of symboltabel.
std::string mMyName
Name of the SymbolTable.
Idx Index(const std::string &rName) const
Index lookup.
A TokenReader reads sequential tokens from a file or string.
long int ReadInteger(void)
Read integer token.
bool Eos(const std::string &rLabel)
Peek a token and check whether it ends the specified section.
void ReadEnd(const std::string &rLabel)
Close the current section by matching the previous ReadBegin().
std::string ReadString(void)
Read string token.
void ReadBegin(const std::string &rLabel)
Open a section by specified label.
A TokenWriter writes sequential tokens to a file, a string or stdout.
void WriteString(const std::string &rString)
Write string.
void WriteEnd(const std::string &rLabel)
Write end label.
int Columns(void) const
Get number of columns in a line.
void WriteInteger(Idx index)
Write non negative integer.
void WriteBegin(const std::string &rLabel)
Write begin label.
Base class of all libFAUDES objects that participate in the run-time interface.
Definition: cfl_types.h:239
bool Empty(void) const
Test whether if the TBaseSet is Empty.
Definition: cfl_baseset.h:1824
bool Exists(const T &rElem) const
Test existence of element.
Definition: cfl_baseset.h:2115
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
std::string ToStringInteger(Int number)
integer to string
Definition: cfl_helper.cpp:43

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen