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 Generator) 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(std::size_t 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 std::size_t up = bname.find_last_of("_"); 00123 if(up != std::string::npos) { 00124 bool ad=true; 00125 for(std::size_t 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 // remove old entry from reverse map 00197 std::map<Idx,std::string>::iterator nit = mNameMap.find(index); 00198 if(nit != mNameMap.end()) mIndexMap.erase(nit->second); 00199 // insert new name/index to maps 00200 mIndexMap[rName] = index; 00201 mNameMap[index] = rName; 00202 } 00203 00204 // SetDefaultSymbol(index) 00205 void SymbolTable::SetDefaultSymbol(Idx index) { 00206 ClrEntry(index); 00207 std::string dname; 00208 dname = UniqueSymbol(ToStringInteger(index)); 00209 InsEntry(index,dname); 00210 } 00211 00212 00213 // ClrEntry(index) 00214 void SymbolTable::ClrEntry(Idx index) { 00215 std::map<Idx,std::string>::iterator it = mNameMap.find(index); 00216 if (it == mNameMap.end()) return; 00217 mIndexMap.erase(it->second); 00218 mNameMap.erase(it); 00219 } 00220 00221 // ClrEntry(rName) 00222 void SymbolTable::ClrEntry(const std::string& rName) { 00223 std::map<std::string,Idx>::iterator it = mIndexMap.find(rName); 00224 if (it == mIndexMap.end()) return; 00225 mNameMap.erase(it->second); 00226 mIndexMap.erase(it); 00227 } 00228 00229 // RestrictDomain(set) 00230 void SymbolTable::RestrictDomain(const IndexSet& rDomain) { 00231 // trivial cases 00232 if(rDomain.Empty()) { Clear(); return;} 00233 if(Size()==0) return; 00234 // lazy loop (todo: sorted iterate) 00235 std::map<Idx,std::string>::iterator it, oit; 00236 it = mNameMap.begin(); 00237 while(it!=mNameMap.end()) { 00238 oit=it; 00239 it++; 00240 if(!rDomain.Exists(oit->first)) mNameMap.erase(oit); 00241 } 00242 } 00243 00244 // Index(rName) 00245 Idx SymbolTable::Index(const std::string& rName) const { 00246 std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName); 00247 if (it == mIndexMap.end()) 00248 return 0; 00249 else 00250 return it->second; 00251 } 00252 00253 // Symbol(index) 00254 std::string SymbolTable::Symbol(Idx index) const { 00255 std::map<Idx,std::string>::const_iterator it = mNameMap.find(index); 00256 if (it == mNameMap.end()) 00257 return ""; 00258 else 00259 return it->second; 00260 } 00261 00262 00263 00264 // Exists(index) 00265 bool SymbolTable::Exists(Idx index) const { 00266 std::map<Idx,std::string>::const_iterator it = mNameMap.find(index); 00267 return (it != mNameMap.end()); 00268 } 00269 00270 // Exists(rName) 00271 bool SymbolTable::Exists(const std::string& rName) const { 00272 std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName); 00273 return ( it != mIndexMap.end()); 00274 } 00275 00276 00277 // GlobalEventSymbolTablep 00278 SymbolTable* SymbolTable::GlobalEventSymbolTablep(void) { 00279 return &msEventSymbolTable; 00280 } 00281 00282 00283 //DoWrite(rTr,rLabel,pContext) 00284 void SymbolTable::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const 00285 { 00286 // default label 00287 std::string label=rLabel; 00288 if(label=="") label="SymbolTable"; 00289 00290 // write section 00291 rTw.WriteBegin(label); 00292 00293 // have two columns 00294 int ocol= rTw.Columns(); 00295 rTw.Columns(2); 00296 00297 // iterate over indices 00298 std::map< std::string, Idx >::const_iterator sit = mIndexMap.begin(); 00299 for(; sit != mIndexMap.end();++sit) { 00300 rTw.WriteInteger(sit->second); 00301 rTw.WriteString(sit->first); 00302 } 00303 00304 // restore columns 00305 rTw.Columns(ocol); 00306 00307 // end section 00308 rTw.WriteEnd(label); 00309 } 00310 00311 00312 //DoRead(rTr,rLabel,pContext) 00313 void SymbolTable::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00314 00315 // default label 00316 std::string label=rLabel; 00317 if(label=="") label="SymbolTable"; 00318 00319 // read section 00320 rTr.ReadBegin(label); 00321 00322 // iterate section 00323 while(!rTr.Eos(label)) { 00324 Idx idx = rTr.ReadInteger(); 00325 std::string sym= rTr.ReadString(); 00326 InsEntry(idx,sym); 00327 } 00328 00329 // done 00330 rTr.ReadEnd(label); 00331 } 00332 00333 00334 00335 00336 } // namespace libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen |