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 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