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