libFAUDES

Sections

Index

cfl_symboltable.cpp

Go 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 SymbolTable& 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   return *this;
00052 }
00053 
00054 
00055 // Name()
00056 const std::string& SymbolTable::Name(void) const {
00057   return mMyName;
00058 }
00059     
00060 //Name(name)
00061 void SymbolTable::Name(const std::string& rName) {
00062   mMyName = rName;
00063 }
00064 
00065 // Clear()
00066 void SymbolTable::Clear(void) {   
00067   mMaxIndex=std::numeric_limits<Idx>::max();
00068   mNextIndex=1;
00069   mIndexMap.clear();
00070   mNameMap.clear();
00071 }
00072 
00073 // Size()
00074 Idx SymbolTable::Size(void) const {   
00075   return mIndexMap.size();
00076 }
00077 
00078 // MaxIndex()
00079 Idx SymbolTable::MaxIndex(void) const {
00080   return mMaxIndex;
00081 }
00082     
00083 // MaxIndex(index)
00084 void SymbolTable::MaxIndex(Idx index) {
00085   if(index <= std::numeric_limits<Idx>::max()) {
00086     mMaxIndex = index;
00087     return;
00088   }
00089   std::stringstream errstr;
00090   errstr << "symboltable overflow in \"" << mMyName << "\"";
00091   throw Exception("SymbolTable::MaxIndex(inde))", errstr.str(), 40);
00092 }
00093     
00094 // LastIndex()
00095 Idx SymbolTable::LastIndex(void) const {
00096   return mNextIndex - 1;
00097 }
00098     
00099 // ValidSymbol(rName)
00100 bool SymbolTable::ValidSymbol(const std::string& rName)  {
00101   if(rName=="") return false;
00102   for(unsigned int cp=0;cp<rName.size();cp++) {
00103     char ch = rName[cp];
00104     if(iscntrl(ch)) return false;
00105     if(isspace(ch)) return false;
00106     if(ch=='"')    return false;
00107     if(ch=='#')    return false;
00108     if(isdigit(ch)) continue;
00109     if(isalpha(ch)) continue;
00110     if(isprint(ch)) continue;
00111     return false;
00112   }
00113   return true;
00114 }
00115 
00116 // UniqueSymbol(rName)
00117 std::string SymbolTable::UniqueSymbol(const std::string& rName) const {
00118   if(!Exists(rName)) return (rName);
00119   long int count=0;
00120   std::string name=rName;
00121   std::string bname=rName;
00122   // if the name ends with extension "_123", remove the extension
00123   unsigned int up = bname.find_last_of("_");
00124   if(up != std::string::npos) {
00125     bool ad=true;
00126     for(unsigned int dp=up+1;dp<bname.size();dp++)
00127       if(!isdigit(bname[dp])) ad=false;
00128     if(ad) 
00129       bname.erase(up);
00130   }
00131   // try append extension "_123" until name is unique
00132   do {
00133     count++;
00134     name=bname + "_" + ToStringInteger(count);
00135   } while(Exists(name));
00136   return name;
00137 }
00138 
00139 
00140 // InsEntry(index, rName)
00141 Idx SymbolTable::InsEntry(Idx index, const std::string& rName) {
00142   if( ! (index <= mMaxIndex)) {
00143     std::stringstream errstr;
00144     errstr << "symboltable overflow in \"" << mMyName << "\"";
00145     throw Exception("SymbolTable::InsEntry(index,name))", errstr.str(), 40);
00146   }
00147   Idx nidx=Index(rName);
00148   if((nidx!=0) && (nidx!=index)) {
00149     std::stringstream errstr;
00150     errstr << "Name " << rName << " allready exists in \"" << mMyName << "\"";
00151     throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 41);
00152   }
00153   std::string idxname=Symbol(index);
00154   if((idxname != "") && (idxname != rName)) {
00155     std::stringstream errstr;
00156     errstr << "Index " << index << " allready exists in \"" << mMyName << "\"";
00157     throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 42);
00158   }
00159   if(!ValidSymbol(rName)) {
00160     std::stringstream errstr;
00161     errstr << "Name " << rName << " is not a valid symbol";
00162     throw Exception("SymbolTable::InsEntry(index,name)", errstr.str(), 43);
00163   }
00164 
00165   mIndexMap[rName] = index;
00166   mNameMap[index] = rName;
00167 
00168   if(mNextIndex<=index) mNextIndex=index+1; 
00169   return index;
00170 }
00171 
00172 // InsEntry(rName)
00173 Idx SymbolTable::InsEntry(const std::string& rName) {
00174   Idx index=Index(rName);
00175   if( index != 0) return index;
00176   return InsEntry(mNextIndex,rName);
00177 }
00178 
00179 
00180 // SetEntry(index, rName)
00181 void SymbolTable::SetEntry(Idx index, const std::string& rName) {
00182   if(rName=="") {
00183     ClrEntry(index);
00184     return;
00185   }
00186   Idx nidx=Index(rName);
00187   if((nidx!=0) && (nidx!=index)) {
00188     std::stringstream errstr;
00189     errstr << "Name " << rName << " allready exists in \"" << mMyName << "\"";
00190     throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 41);
00191   }
00192   if(!ValidSymbol(rName)) {
00193     std::stringstream errstr;
00194     errstr << "Name " << rName << " is not a valid symbol";
00195     throw Exception("SymbolTable::SetEntry(index,name)", errstr.str(), 43);
00196   }
00197   mIndexMap[rName] = index;
00198   mNameMap[index] = rName;
00199 }
00200 
00201 // SetDefaultSymbol(index)
00202 void SymbolTable::SetDefaultSymbol(Idx index) {
00203   ClrEntry(index); 
00204   std::ostringstream o;
00205   std::string dname;
00206   o << index;
00207   dname = UniqueSymbol(ToStringInteger(index));
00208   InsEntry(index,dname);
00209 }
00210 
00211 
00212 // ClrEntry(index)
00213 void SymbolTable::ClrEntry(Idx index) {
00214   std::map<Idx,std::string>::iterator it = mNameMap.find(index);
00215   if (it == mNameMap.end()) return;
00216   mIndexMap.erase(it->second);
00217   mNameMap.erase(it);
00218 }
00219 
00220 // ClrEntry(rName)
00221 void SymbolTable::ClrEntry(const std::string& rName) {
00222   std::map<std::string,Idx>::iterator it = mIndexMap.find(rName);
00223   if (it == mIndexMap.end()) return;
00224   mNameMap.erase(it->second);
00225   mIndexMap.erase(it);
00226 }
00227 
00228 // RestrictDomain(set)
00229 void SymbolTable::RestrictDomain(const IndexSet& rDomain) {
00230   // trivial cases
00231   if(rDomain.Empty()) { Clear(); return;}
00232   if(Size()==0) return;
00233   // lazy loop (todo: sorted iterate)
00234   std::map<Idx,std::string>::iterator it, oit;
00235   it = mNameMap.begin();
00236   while(it!=mNameMap.end()) {
00237     oit=it;
00238     it++;
00239     if(!rDomain.Exists(oit->first)) mNameMap.erase(oit);
00240   }
00241 }
00242 
00243 // Index(rName)
00244 Idx SymbolTable::Index(const std::string& rName) const {
00245   std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName);
00246   if (it == mIndexMap.end()) 
00247     return 0;
00248   else 
00249     return it->second;
00250 }
00251 
00252 // Symbol(index)
00253 std::string SymbolTable::Symbol(Idx index) const {
00254   std::map<Idx,std::string>::const_iterator it = mNameMap.find(index);
00255   if (it == mNameMap.end()) 
00256     return "";
00257   else 
00258     return it->second;
00259 }
00260 
00261 
00262 
00263 // Exists(index)
00264 bool SymbolTable::Exists(Idx index) const {
00265   std::map<Idx,std::string>::const_iterator it = mNameMap.find(index);
00266   return (it != mNameMap.end());
00267 }
00268 
00269 // Exists(rName)
00270 bool SymbolTable::Exists(const std::string& rName) const {
00271   std::map<std::string,Idx>::const_iterator it = mIndexMap.find(rName);
00272   return ( it != mIndexMap.end());
00273 }
00274 
00275 
00276 // GlobalEventSymbolTablep 
00277 SymbolTable* SymbolTable::GlobalEventSymbolTablep(void) {
00278   return &msEventSymbolTable; 
00279 }
00280 
00281 
00282 //DoWrite(rTr,rLabel,pContext)
00283 void SymbolTable::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const 
00284 {
00285   // default label
00286   std::string label=rLabel;
00287   if(label=="") label="SymbolTable"; 
00288 
00289   // write section
00290   rTw.WriteBegin(label);
00291  
00292   // have two columns
00293   int ocol= rTw.Columns();
00294   rTw.Columns(2);
00295 
00296   // iterate over indices
00297   std::map< std::string, Idx >::const_iterator sit = mIndexMap.begin();
00298   for(; sit != mIndexMap.end();++sit) {
00299     rTw.WriteInteger(sit->second);
00300     rTw.WriteString(sit->first);
00301   }
00302   
00303   // restore columns
00304   rTw.Columns(ocol);
00305 
00306   // end section
00307   rTw.WriteEnd(label);
00308 }
00309 
00310 
00311 //DoRead(rTr,rLabel,pContext)
00312 void SymbolTable::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00313 
00314   // default label
00315   std::string label=rLabel;
00316   if(label=="") label="SymbolTable"; 
00317   
00318   // read section
00319   rTr.SeekBegin(label);
00320 
00321   // iterate section  
00322   while(!rTr.Eos(label)) {
00323     Idx idx = rTr.ReadInteger();
00324     std::string sym= rTr.ReadString();
00325     InsEntry(idx,sym);
00326   }
00327 
00328   // done
00329   rTr.SeekEnd(label);
00330 }
00331 
00332 
00333 
00334 
00335 } // namespace

libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3