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
27namespace faudes {
28
29// faudes type std
30FAUDES_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;
51 mNameMap=rSrc.mNameMap;
54}
55
56
57// Name()
58const std::string& SymbolTable::Name(void) const {
59 return mMyName;
60}
61
62//Name(name)
63void SymbolTable::Name(const std::string& rName) {
64 mMyName = rName;
65}
66
67// Clear()
68void SymbolTable::Clear(void) {
69 mMaxIndex=std::numeric_limits<Idx>::max();
70 mNextIndex=1;
71 mIndexMap.clear();
72 mNameMap.clear();
73}
74
75// Size()
76Idx 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)
102bool 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)
119std::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)
143Idx 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)
175Idx 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)
183void 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)
225void 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)
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)
248Idx 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)
257std::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)
268bool 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)
274bool 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)
289void 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)
318void 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:958
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 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
bool Exists(const T &rElem) const
uint32_t Idx
std::string ToStringInteger(Int number)
Definition cfl_utils.cpp:43
AutoRegisterType< SymbolTable > gRtiSymboltable("Symboltable")

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen