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

libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3