|
libFAUDES
Sections
Index
|
cfl_symboltable.cppGo to the documentation of this file.00001 /** @file cfl_symboltable.cpp @brief Class SymbolTable */ 00002 00003 /* FAU Discrete Event Systems Library (libfaudes) 00004 00005 Copyright (C) 2006 Bernd Opitz 00006 Copyright (C) 2007 Thomas Moor 00007 Exclusive copyright is granted to Klaus Schmidt 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public 00020 License along with this library; if not, write to the Free Software 00021 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00022 00023 00024 #include "cfl_symboltable.h" 00025 #include <iostream> 00026 00027 namespace faudes { 00028 00029 // static symbol table (used for events, should be in vGenerator) 00030 SymbolTable SymbolTable::msEventSymbolTable; 00031 00032 // constructor 00033 SymbolTable:: SymbolTable(void) : 00034 mMyName("SymbolTable"), 00035 mMaxIndex(std::numeric_limits<Idx>::max()), 00036 mNextIndex(1) { 00037 } 00038 00039 // constructor 00040 SymbolTable:: SymbolTable(const SymbolTable& rSrc) { 00041 DoAssign(rSrc); 00042 } 00043 00044 // asignment 00045 void SymbolTable::DoAssign(const SymbolTable& rSrc) { 00046 mMyName=rSrc.mMyName; 00047 mIndexMap=rSrc.mIndexMap; 00048 mNameMap=rSrc.mNameMap; 00049 mMaxIndex=rSrc.mMaxIndex; 00050 mNextIndex=rSrc.mNextIndex; 00051 } 00052 00053 00054 // Name() 00055 const std::string& SymbolTable::Name(void) const { 00056 return mMyName; 00057 } 00058 00059 //Name(name) 00060 void SymbolTable::Name(const std::string& rName) { 00061 mMyName = rName; 00062 } 00063 00064 // Clear() 00065 void SymbolTable::Clear(void) { 00066 mMaxIndex=std::numeric_limits<Idx>::max(); 00067 mNextIndex=1; 00068 mIndexMap.clear(); 00069 mNameMap.clear(); 00070 } 00071 00072 // Size() 00073 Idx SymbolTable::Size(void) const { 00074 return mIndexMap.size(); 00075 } 00076 00077 // MaxIndex() 00078 Idx SymbolTable::MaxIndex(void) const { 00079 return mMaxIndex; 00080 } 00081 00082 // MaxIndex(index) 00083 void SymbolTable::MaxIndex(Idx index) { 00084 if(index <= std::numeric_limits<Idx>::max()) { 00085 mMaxIndex = index; 00086 return; 00087 } 00088 std::stringstream errstr; 00089 errstr << "symboltable overflow in \"" << mMyName << "\""; 00090 throw Exception("SymbolTable::MaxIndex(inde))", errstr.str(), 40); 00091 } 00092 00093 // LastIndex() 00094 Idx SymbolTable::LastIndex(void) const { 00095 return mNextIndex - 1; 00096 } 00097 00098 // ValidSymbol(rName) 00099 bool SymbolTable::ValidSymbol(const std::string& rName) { 00100 if(rName=="") return false; 00101 for(unsigned int cp=0;cp<rName.size();cp++) { 00102 char ch = rName[cp]; 00103 if(iscntrl(ch)) return false; 00104 if(isspace(ch)) return false; 00105 if(ch=='"') return false; 00106 if(ch=='#') return false; 00107 if(isdigit(ch)) continue; 00108 if(isalpha(ch)) continue; 00109 if(isprint(ch)) continue; 00110 return false; 00111 } 00112 return true; 00113 } 00114 00115 // UniqueSymbol(rName) 00116 std::string SymbolTable::UniqueSymbol(const std::string& rName) const { 00117 if(!Exists(rName)) return (rName); 00118 long int count=0; 00119 std::string name=rName; 00120 std::string bname=rName; 00121 // if the name ends with extension "_123", remove the extension 00122 unsigned int up = bname.find_last_of("_"); 00123 if(up != std::string::npos) { 00124 bool ad=true; 00125 for(unsigned int dp=up+1;dp<bname.size();dp++) 00126 if(!isdigit(bname[dp])) ad=false; 00127 if(ad) 00128 bname.erase(up); 00129 } 00130 // try append extension "_123" until name is unique 00131 do { 00132 count++; 00133 name=bname + "_" + ToStringInteger(count); 00134 } while(Exists(name)); 00135 return name; 00136 } 00137 00138 00139 // InsEntry(index, rName) 00140 Idx SymbolTable::InsEntry(Idx index, const std::string& rName) { 00141 if( ! (index <= mMaxIndex)) { 00142 std::stringstream errstr; 00143 errstr << "symboltable overflow in \"" << mMyName << "\""; 00144 throw Exception("SymbolTable::InsEntry(index,name))", errstr.str(), 40); 00145 } 00146 Idx nidx=Index(rName); 00147 if((nidx!=0) && (nidx!=index)) { 00148 std::stringstream errstr; 00149 errstr << "Name " << rName << " allready exists in \"" << mMyName << "\""; 00150 throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 41); 00151 } 00152 std::string idxname=Symbol(index); 00153 if((idxname != "") && (idxname != rName)) { 00154 std::stringstream errstr; 00155 errstr << "Index " << index << " allready exists in \"" << mMyName << "\""; 00156 throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 42); 00157 } 00158 if(!ValidSymbol(rName)) { 00159 std::stringstream errstr; 00160 errstr << "Name " << rName << " is not a valid symbol"; 00161 throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 43); 00162 } 00163 00164 mIndexMap[rName] = index; 00165 mNameMap[index] = rName; 00166 00167 if(mNextIndex<=index) mNextIndex=index+1; 00168 return index; 00169 } 00170 00171 // InsEntry(rName) 00172 Idx SymbolTable::InsEntry(const std::string& rName) { 00173 Idx index=Index(rName); 00174 if( index != 0) return index; 00175 return InsEntry(mNextIndex,rName); 00176 } 00177 00178 00179 // SetEntry(index, rName) 00180 void SymbolTable::SetEntry(Idx index, const std::string& rName) { 00181 if(rName=="") { 00182 ClrEntry(index); 00183 return; 00184 } 00185 Idx nidx=Index(rName); 00186 if((nidx!=0) && (nidx!=index)) { 00187 std::stringstream errstr; 00188 errstr << "Name " << rName << " allready exists in \"" << mMyName << "\""; 00189 throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 41); 00190 } 00191 if(!ValidSymbol(rName)) { 00192 std::stringstream errstr; 00193 errstr << "Name " << rName << " is not a valid symbol"; 00194 throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 43); 00195 } 00196 mIndexMap[rName] = index; 00197 mNameMap[index] = rName; 00198 } 00199 00200 // SetDefaultSymbol(index) 00201 void SymbolTable::SetDefaultSymbol(Idx index) { 00202 ClrEntry(index); 00203 std::ostringstream o; 00204 std::string dname; 00205 o << index; 00206 dname = UniqueSymbol(ToStringInteger(index)); 00207 InsEntry(index,dname); 00208 } 00209 00210 00211 // ClrEntry(index) 00212 void SymbolTable::ClrEntry(Idx index) { 00213 std::map<Idx,std::string>::iterator it = mNameMap.find(index); 00214 if (it == mNameMap.end()) return; 00215 mIndexMap.erase(it->second); 00216 mNameMap.erase(it); 00217 } 00218 00219 // ClrEntry(rName) 00220 void SymbolTable::ClrEntry(const std::string& rName) { 00221 std::map<std::string,Idx>::iterator it = mIndexMap.find(rName); 00222 if (it == mIndexMap.end()) return; 00223 mNameMap.erase(it->second); 00224 mIndexMap.erase(it); 00225 } 00226 00227 // RestrictDomain(set) 00228 void SymbolTable::RestrictDomain(const IndexSet& rDomain) { 00229 // trivial cases 00230 if(rDomain.Empty()) { Clear(); return;} 00231 if(Size()==0) return; 00232 // lazy loop (todo: sorted iterate) 00233 std::map<Idx,std::string>::iterator it, oit; 00234 it = mNameMap.begin(); 00235 while(it!=mNameMap.end()) { 00236 oit=it; 00237 it++; 00238 if(!rDomain.Exists(oit->first)) mNameMap.erase(oit); 00239 } 00240 } 00241 00242 // Index(rName) 00243 Idx SymbolTable::Index(const std::string& rName) const { 00244 std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName); 00245 if (it == mIndexMap.end()) 00246 return 0; 00247 else 00248 return it->second; 00249 } 00250 00251 // Symbol(index) 00252 std::string SymbolTable::Symbol(Idx index) const { 00253 std::map<Idx,std::string>::const_iterator it = mNameMap.find(index); 00254 if (it == mNameMap.end()) 00255 return ""; 00256 else 00257 return it->second; 00258 } 00259 00260 00261 00262 // Exists(index) 00263 bool SymbolTable::Exists(Idx index) const { 00264 std::map<Idx,std::string>::const_iterator it = mNameMap.find(index); 00265 return (it != mNameMap.end()); 00266 } 00267 00268 // Exists(rName) 00269 bool SymbolTable::Exists(const std::string& rName) const { 00270 std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName); 00271 return ( it != mIndexMap.end()); 00272 } 00273 00274 00275 // GlobalEventSymbolTablep 00276 SymbolTable* SymbolTable::GlobalEventSymbolTablep(void) { 00277 return &msEventSymbolTable; 00278 } 00279 00280 00281 //DoWrite(rTr,rLabel,pContext) 00282 void SymbolTable::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const 00283 { 00284 // default label 00285 std::string label=rLabel; 00286 if(label=="") label="SymbolTable"; 00287 00288 // write section 00289 rTw.WriteBegin(label); 00290 00291 // have two columns 00292 int ocol= rTw.Columns(); 00293 rTw.Columns(2); 00294 00295 // iterate over indices 00296 std::map< std::string, Idx >::const_iterator sit = mIndexMap.begin(); 00297 for(; sit != mIndexMap.end();++sit) { 00298 rTw.WriteInteger(sit->second); 00299 rTw.WriteString(sit->first); 00300 } 00301 00302 // restore columns 00303 rTw.Columns(ocol); 00304 00305 // end section 00306 rTw.WriteEnd(label); 00307 } 00308 00309 00310 //DoRead(rTr,rLabel,pContext) 00311 void SymbolTable::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00312 00313 // default label 00314 std::string label=rLabel; 00315 if(label=="") label="SymbolTable"; 00316 00317 // read section 00318 rTr.ReadBegin(label); 00319 00320 // iterate section 00321 while(!rTr.Eos(label)) { 00322 Idx idx = rTr.ReadInteger(); 00323 std::string sym= rTr.ReadString(); 00324 InsEntry(idx,sym); 00325 } 00326 00327 // done 00328 rTr.ReadEnd(label); 00329 } 00330 00331 00332 00333 00334 } // namespace |
libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3