Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

stringparser.h

Go to the documentation of this file.
00001 
00007 #ifndef __STRINGPARSER_H__
00008 #define __STRINGPARSER_H__
00009 
00010 #include <string>
00011 using std::string;
00012 #include <strstream>
00013 #include <vector>
00014 
00015 #include "tristate.h"
00016 
00055 class StringParser {
00056 public:
00057   StringParser() { };
00058   virtual ~StringParser() { }
00059 
00061   typedef std::vector<string>           arglist;
00063   typedef std::vector<string>::iterator arglist_iterator;
00065   typedef std::vector<string>::iterator argptr;
00066   typedef std::vector<string>::const_iterator const_argptr;
00067   
00068   StringParser(const StringParser&) { } 
00071   virtual StringParser* clone() const { return new StringParser(*this); };
00072 
00075 
00077   virtual double&   parse(const string& s, double&   x) const {  basicparse(s,x);  return x;  }
00079   virtual int&      parse(const string& s, int&      x) const {  basicparse(s,x);  return x;  }
00081   virtual Tristate& parse(const string& s, Tristate& x) const {  basicparse(s,x);  return x;  }
00083   virtual string&   parse(const string& s, string&   x) const {  x=s;              return x;  }
00084 
00085   
00087   virtual double*&   parse(const string& s, double*&   x) const {  basicparse(s,*x); return x;  }
00089   virtual int*&      parse(const string& s, int*&      x) const {  basicparse(s,*x); return x;  }
00091   virtual Tristate*& parse(const string& s, Tristate*& x) const {  basicparse(s,*x); return x;  }
00093   virtual string*&   parse(const string& s, string*&   x) const {  *x=s;             return x;  }
00094 
00095 
00097   virtual arglist&  parse(const string& s, arglist&  x) const {
00098     std::istrstream ist(s.c_str(),s.length());
00099     x.resize(0);
00100     string w;
00101     while (ist>>w)
00102       x.push_back(w);
00103     return x;
00104   }
00106 
00108   virtual string parse(const string& s) const {  string dummy;  return parse(s,dummy);  }
00109   
00113   virtual void error(const string&) const {  }
00114   
00115 private:
00116 
00129 //template <class T>
00130 #define BASICPARSE_DEF(T)                                               \
00131     static T& basicparse(const string& s, T& x)                         \
00132     {  std::istrstream ss(s.c_str(),s.length()); ss >> x; return x;  }
00133 
00134   BASICPARSE_DEF(double);
00135   BASICPARSE_DEF(int);
00136   BASICPARSE_DEF(Tristate);
00137 };
00138 
00139 
00140 
00141 
00158 class StringArgs {
00159   StringParser::arglist a; // Only used if we are constructed from string
00160   StringParser::argptr beg;
00161   StringParser::argptr end;
00162   
00163 public:
00165   const StringParser& p; 
00166 
00167   StringArgs(const StringParser& parser, StringParser::argptr b, StringParser::argptr e)
00168     :  beg(b), end(e), p(parser)  { }
00169   
00170   StringArgs(const StringParser& parser, const string& s) : p(parser)  {
00171     p.parse(s,a);
00172     beg=a.begin();
00173     end=a.end();
00174   }
00175 
00177   StringArgs(const StringArgs& other)
00178     : a(other.a), beg(other.beg), end(other.end), p(*other.p.clone()) {
00179       /*
00180         Copy constructor is tricky -- if the other was using an internal
00181         container, need to construct equivalent iterators for our own
00182         copy.
00183       */ 
00184       if (!other.a.empty()) {
00185         beg=a.begin()+((StringParser::const_argptr)(other.beg)-(StringParser::const_argptr)(other.a.begin()));
00186         end=a.begin()+((StringParser::const_argptr)(other.end)-(StringParser::const_argptr)(other.a.begin()));
00187       }
00188     }
00189 
00191   bool empty() const {  return (beg==end);  }
00192   
00194   bool oneremaining() const {  return (beg+1==end);  }
00195   
00198   template<class T>
00199   T top(const T& default_val) const {
00200     if (empty())
00201       return default_val;
00202     else {
00203       T result;
00204       p.parse(*(beg), result);
00205       return result;
00206     }
00207   }
00208 
00210   void skip() {  if (!empty()) beg++;  }
00211   
00213   template<class T>
00214   T next(const T& default_val) {
00215     if (empty())
00216       return default_val;
00217     else {
00218       T result;
00219       p.parse(*(beg++), result);
00220       return result;
00221     }
00222   }
00223 
00225   template<class T>
00226   T* next(const T& default_val, T*& ptr) {
00227     if (empty())
00228       *ptr = default_val;
00229     else
00230       p.parse(*(beg++), ptr);
00231     return ptr;
00232   }
00233 
00235   template<class T>
00236   bool nextis(const T& test_val) {
00237     if (!empty()) {
00238       T result;
00239       p.parse(*beg, result);
00240       if (test_val == result) {
00241         beg++;
00242         return true;
00243       }
00244     }
00245     return false;
00246   }
00247 
00250   template<class T>
00251   bool lookaheadone(const T& test_val) const {
00252     if (empty() || (beg+1)==end)
00253       return false;
00254 
00255     T result;
00256     p.parse(*(beg+1), result);
00257     return (test_val == result);
00258   }
00259 
00263   StringArgs recursiveparser() {  return recursiveparser(next(string("")));  }
00264 
00266   StringArgs recursiveparser(const string s) const {  return StringArgs(p, s);  }
00267 
00269   string stringrep() const {
00270     if (beg==end) return "";
00271     string result = *beg;
00272     for (StringParser::argptr i=beg+1; i!=end; i++)
00273       result = result + " '" + *i + "' ";
00274     return result;
00275   }
00276 };
00277 
00278 
00279 #endif /* __STRINGPARSER_H__ */

Generated on Mon Jan 20 02:35:45 2003 for RF-LISSOM by doxygen1.3-rc2