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  Copywrite (C) 2007, 2024 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 // faudes type std
30 FAUDES_TYPE_IMPLEMENTATION(Void,SymbolTable,Type)
31 
32 // Autoregister for xml output
34 
35 // constructor
37  mMyName("SymbolTable"),
38  mMaxIndex(std::numeric_limits<Idx>::max()),
39  mNextIndex(1) {
40 }
41 
42 // constructor
44  DoAssign(rSrc);
45 }
46 
47 // asignment
49  mMyName=rSrc.mMyName;
50  mIndexMap=rSrc.mIndexMap;
51  mNameMap=rSrc.mNameMap;
52  mMaxIndex=rSrc.mMaxIndex;
54 }
55 
56 
57 // Name()
58 const std::string& SymbolTable::Name(void) const {
59  return mMyName;
60 }
61 
62 //Name(name)
63 void SymbolTable::Name(const std::string& rName) {
64  mMyName = rName;
65 }
66 
67 // Clear()
68 void SymbolTable::Clear(void) {
69  mMaxIndex=std::numeric_limits<Idx>::max();
70  mNextIndex=1;
71  mIndexMap.clear();
72  mNameMap.clear();
73 }
74 
75 // Size()
76 Idx SymbolTable::Size(void) const {
77  return mIndexMap.size();
78 }
79 
80 // MaxIndex()
82  return mMaxIndex;
83 }
84 
85 // MaxIndex(index)
87  if(index <= std::numeric_limits<Idx>::max()) {
88  mMaxIndex = index;
89  return;
90  }
91  std::stringstream errstr;
92  errstr << "symboltable overflow in \"" << mMyName << "\"";
93  throw Exception("SymbolTable::MaxIndex(inde))", errstr.str(), 40);
94 }
95 
96 // LastIndex()
98  return mNextIndex - 1;
99 }
100 
101 // ValidSymbol(rName)
102 bool SymbolTable::ValidSymbol(const std::string& rName) {
103  if(rName=="") return false;
104  for(std::size_t cp=0;cp<rName.size();cp++) {
105  char ch = rName[cp];
106  if(iscntrl(ch)) return false;
107  if(isspace(ch)) return false;
108  if(ch=='"') return false;
109  if(ch=='#') return false;
110  if(isdigit(ch)) continue;
111  if(isalpha(ch)) continue;
112  if(isprint(ch)) continue;
113  return false;
114  }
115  return true;
116 }
117 
118 // UniqueSymbol(rName)
119 std::string SymbolTable::UniqueSymbol(const std::string& rName) const {
120  if(!Exists(rName)) return (rName);
121  long int count=0;
122  std::string name=rName;
123  std::string bname=rName;
124  // if the name ends with extension "_123", remove the extension
125  std::size_t up = bname.find_last_of("_");
126  if(up != std::string::npos) {
127  bool ad=true;
128  for(std::size_t dp=up+1;dp<bname.size();dp++)
129  if(!isdigit(bname[dp])) ad=false;
130  if(ad)
131  bname.erase(up);
132  }
133  // try append extension "_123" until name is unique
134  do {
135  count++;
136  name=bname + "_" + ToStringInteger(count);
137  } while(Exists(name));
138  return name;
139 }
140 
141 
142 // InsEntry(index, rName)
143 Idx SymbolTable::InsEntry(Idx index, const std::string& rName) {
144  if( ! (index <= mMaxIndex)) {
145  std::stringstream errstr;
146  errstr << "symboltable overflow in \"" << mMyName << "\"";
147  throw Exception("SymbolTable::InsEntry(index,name))", errstr.str(), 40);
148  }
149  Idx nidx=Index(rName);
150  if((nidx!=0) && (nidx!=index)) {
151  std::stringstream errstr;
152  errstr << "Name " << rName << " allready exists in \"" << mMyName << "\"";
153  throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 41);
154  }
155  std::string idxname=Symbol(index);
156  if((idxname != "") && (idxname != rName)) {
157  std::stringstream errstr;
158  errstr << "Index " << index << " allready exists in \"" << mMyName << "\"";
159  throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 42);
160  }
161  if(!ValidSymbol(rName)) {
162  std::stringstream errstr;
163  errstr << "Name " << rName << " is not a valid symbol";
164  throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 43);
165  }
166 
167  mIndexMap[rName] = index;
168  mNameMap[index] = rName;
169 
170  if(mNextIndex<=index) mNextIndex=index+1;
171  return index;
172 }
173 
174 // InsEntry(rName)
175 Idx SymbolTable::InsEntry(const std::string& rName) {
176  Idx index=Index(rName);
177  if( index != 0) return index;
178  return InsEntry(mNextIndex,rName);
179 }
180 
181 
182 // SetEntry(index, rName)
183 void SymbolTable::SetEntry(Idx index, const std::string& rName) {
184  if(rName=="") {
185  ClrEntry(index);
186  return;
187  }
188  Idx nidx=Index(rName);
189  if((nidx!=0) && (nidx!=index)) {
190  std::stringstream errstr;
191  errstr << "Name " << rName << " allready exists in \"" << mMyName << "\"";
192  throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 41);
193  }
194  if(!ValidSymbol(rName)) {
195  std::stringstream errstr;
196  errstr << "Name " << rName << " is not a valid symbol";
197  throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 43);
198  }
199  // remove old entry from reverse map
200  std::map<Idx,std::string>::iterator nit = mNameMap.find(index);
201  if(nit != mNameMap.end()) mIndexMap.erase(nit->second);
202  // insert new name/index to maps
203  mIndexMap[rName] = index;
204  mNameMap[index] = rName;
205 }
206 
207 // SetDefaultSymbol(index)
209  ClrEntry(index);
210  std::string dname;
211  dname = UniqueSymbol(ToStringInteger(index));
212  InsEntry(index,dname);
213 }
214 
215 
216 // ClrEntry(index)
218  std::map<Idx,std::string>::iterator it = mNameMap.find(index);
219  if (it == mNameMap.end()) return;
220  mIndexMap.erase(it->second);
221  mNameMap.erase(it);
222 }
223 
224 // ClrEntry(rName)
225 void SymbolTable::ClrEntry(const std::string& rName) {
226  std::map<std::string,Idx>::iterator it = mIndexMap.find(rName);
227  if (it == mIndexMap.end()) return;
228  mNameMap.erase(it->second);
229  mIndexMap.erase(it);
230 }
231 
232 // RestrictDomain(set)
233 void SymbolTable::RestrictDomain(const IndexSet& rDomain) {
234  // trivial cases
235  if(rDomain.Empty()) { Clear(); return;}
236  if(Size()==0) return;
237  // lazy loop (todo: sorted iterate)
238  std::map<Idx,std::string>::iterator it, oit;
239  it = mNameMap.begin();
240  while(it!=mNameMap.end()) {
241  oit=it;
242  it++;
243  if(!rDomain.Exists(oit->first)) mNameMap.erase(oit);
244  }
245 }
246 
247 // Index(rName)
248 Idx SymbolTable::Index(const std::string& rName) const {
249  std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName);
250  if (it == mIndexMap.end())
251  return 0;
252  else
253  return it->second;
254 }
255 
256 // Symbol(index)
257 std::string SymbolTable::Symbol(Idx index) const {
258  std::map<Idx,std::string>::const_iterator it = mNameMap.find(index);
259  if (it == mNameMap.end())
260  return "";
261  else
262  return it->second;
263 }
264 
265 
266 
267 // Exists(index)
268 bool SymbolTable::Exists(Idx index) const {
269  std::map<Idx,std::string>::const_iterator it = mNameMap.find(index);
270  return (it != mNameMap.end());
271 }
272 
273 // Exists(rName)
274 bool SymbolTable::Exists(const std::string& rName) const {
275  std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName);
276  return ( it != mIndexMap.end());
277 }
278 
279 
280 // GlobalEventSymbolTablep
281 // (initialize on first use pattern)
283  static SymbolTable fls;
284  return &fls;
285 }
286 
287 
288 //DoWrite(rTr,rLabel,pContext)
289 void SymbolTable::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const
290 {
291  // default label
292  std::string label=rLabel;
293  if(label=="") label="SymbolTable";
294 
295  // write section
296  rTw.WriteBegin(label);
297 
298  // have two columns
299  int ocol= rTw.Columns();
300  rTw.Columns(2);
301 
302  // iterate over indices
303  std::map< std::string, Idx >::const_iterator sit = mIndexMap.begin();
304  for(; sit != mIndexMap.end();++sit) {
305  rTw.WriteInteger(sit->second);
306  rTw.WriteString(sit->first);
307  }
308 
309  // restore columns
310  rTw.Columns(ocol);
311 
312  // end section
313  rTw.WriteEnd(label);
314 }
315 
316 
317 //DoRead(rTr,rLabel,pContext)
318 void SymbolTable::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
319 
320  // default label
321  std::string label=rLabel;
322  if(label=="") label="SymbolTable";
323 
324  // read section
325  rTr.ReadBegin(label);
326 
327  // iterate section
328  while(!rTr.Eos(label)) {
329  Idx idx = rTr.ReadInteger();
330  std::string sym= rTr.ReadString();
331  InsEntry(idx,sym);
332  }
333 
334  // done
335  rTr.ReadEnd(label);
336 }
337 
338 
339 
340 
341 } // namespace
Class SymbolTable.
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
Definition: cfl_types.h:959
void RestrictDomain(const IndexSet &rDomain)
std::map< Idx, std::string > mNameMap
void SetDefaultSymbol(Idx index)
Idx LastIndex(void) const
std::map< std::string, Idx > mIndexMap
static SymbolTable * GlobalEventSymbolTablep(void)
std::string Symbol(Idx index) const
void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
const std::string & Name(void) const
static bool ValidSymbol(const std::string &rName)
Idx MaxIndex(void) const
void ClrEntry(Idx index)
void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
bool Exists(Idx index) const
void DoAssign(const SymbolTable &rSrc)
std::string UniqueSymbol(const std::string &rName) const
void SetEntry(Idx index, const std::string &rName)
Idx InsEntry(Idx index, const std::string &rName)
Idx Size(void) const
Idx Index(const std::string &rName) const
long int ReadInteger(void)
bool Eos(const std::string &rLabel)
void ReadEnd(const std::string &rLabel)
std::string ReadString(void)
void ReadBegin(const std::string &rLabel)
void WriteString(const std::string &rString)
void WriteEnd(const std::string &rLabel)
int Columns(void) const
void WriteInteger(Idx index)
void WriteBegin(const std::string &rLabel)
bool Empty(void) const
Definition: cfl_baseset.h:1787
bool Exists(const T &rElem) const
Definition: cfl_baseset.h:2180
uint32_t Idx
AutoRegisterType< SymbolTable > gRtiSymboltable("Symboltable")
std::string ToStringInteger(Int number)
Definition: cfl_utils.cpp:43

libFAUDES 2.33h --- 2025.06.18 --- c++ api documentaion by doxygen