About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
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 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