///////////////////////////////////////////////////////////////////////// // CppSemiExp.cpp - declares semi-expression which collects tokens // // ver 1.3 from input stream via a CToker instance // // // // Language: Visual C++, ver 7.0 // // Platform: Dell Dimension 8300, Windows XP Prof, SP 1 // // Application: CSE687 prototype for project #1, Spring 2004 // // Author: Jim Fawcett, CST 2-187, Syracuse University // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////////////// #include "CppSemiExp.h" #include "CppToker.h" #include #include #include #include using namespace Scanner; //----< is this a C language comment? >---------------------------------- bool CCCommentFilter::present() { if(_pToker->curr() == "/*") return true; return false; } //----< discard C language comment >------------------------------------- bool CCCommentFilter::extract(std::string &token) { std::string temp; while((temp = _pToker->getTok()) != "*/") if(temp == "") break; // discard token return false; // no token returned } //----< is this a C++ language comment? >-------------------------------- bool CCppCommentFilter::present() { std::string temp = _pToker->curr(); if(temp.length() >= 2 && temp[0] == '/' && temp[1] == '/') return true; return false; } //----< discard C++ language comment >----------------------------------- bool CCppCommentFilter::extract(std::string &token) { std::string temp; while((temp = _pToker->getTok()) != "\n") if(temp == "") break; // discard token token = "\n"; // substitute return true; // token returned } // //----< is this a quoted string? >--------------------------------------- bool CDoubleQuoteFilter::present() { std::string temp = _pToker->curr(); if(temp.length() > 0 && temp[0] == '\"') return true; return false; } //----< collect quoted string as a token >------------------------------- bool CDoubleQuoteFilter::extract(std::string &token) { std::string temp = _pToker->curr(); _pToker->getTok(); while(_pToker->curr() != "\"" || _pToker->prev() == "\\") { temp += _pToker->curr(); _pToker->getTok(); } token = (temp += _pToker->curr()); return true; } //----< is this a quoted character? >------------------------------------ bool CSingleQuoteFilter::present() { std::string temp = _pToker->curr(); if(temp.length() > 0 && temp[0] == '\'') return true; return false; } //----< collect quoted character as a token >---------------------------- bool CSingleQuoteFilter::extract(std::string &token) { std::string temp = _pToker->curr(); _pToker->getTok(); while(_pToker->curr() != "\'" || _pToker->prev() == "\\") { temp += _pToker->curr(); _pToker->getTok(); } token = (temp += _pToker->curr()); return true; } // //----< CSemiExp constructor >------------------------------------------- CSemiExp::CSemiExp(CToker *pToker) : _pToker(pToker) { } //----< CSemiExp destructor >-------------------------------------------- CSemiExp::~CSemiExp(void) { // - user created CToker so don't destroy // - user creates filters so don't destroy } //----< register type derived from ITokenFilter >------------------------ void CSemiExp::registerFilter(ITokenFilter *pITokenFilter) { _filter.push_back(pITokenFilter); } //----< return number of tokens in semi-expression >--------------------- size_t CSemiExp::length() const { return _tok.size(); } //----< does this character terminat a semi-expression? >---------------- bool CSemiExp::isTerminator(const std::string &token) const { if(token=="{" || token=="}" || token==";") return true; if(length() == 0) return false; if(token=="\n" && _tok[0]=="#") return true; return false; } //----< remove all tokens >---------------------------------------------- void CSemiExp::clear() { _tok.clear(); } // //----< remove or transform groups of tokens >--------------------------- bool CSemiExp::filter(std::string &token) { std::string dummy; std::list::iterator iter; for(iter=_filter.begin(); iter!=_filter.end(); iter++) { if((*iter)->present()) { if((*iter)->extract(dummy=token)) { token = dummy; // return token via side effect return true; } else { return false; // don't return token } } } return true; } //----< extract semi-expressions from filtered stream >------------------ // // returns silently if no toker provided, e.g., created with default ctor // bool CSemiExp::get() { if(!_pToker) return false; clear(); std::string token; do { token = _pToker->getTok(); if(token == "") return false; if(filter(token)) { if(token != "\n") _tok.push_back(token); } } while(!isTerminator(token)); return true; } // //----< check for valid index >------------------------------------------ void CSemiExp::checkIndex(unsigned int i) { if(i<0 || _tok.size() <= i) throw std::exception("index out of domain in CSemiExp::insert"); } //----< insert token preceding element i >------------------------------- void CSemiExp::insert(unsigned int i, const std::string &token) { checkIndex(i); std::vector::iterator iter = _tok.begin(); _tok.insert(iter+i,token); } //----< append token at end of semi-expression >------------------------- void CSemiExp::push_back(const std::string &token) { std::vector::iterator iter = _tok.begin(); _tok.push_back(token); } //----< remove token from semi-expression >------------------------------ void CSemiExp::erase(unsigned int i) { checkIndex(i); std::vector::iterator iter = _tok.begin(); _tok.erase(iter+i); } //----< find token in semi-expression >---------------------------------- // // returns length() if not found // size_t CSemiExp::find(const std::string& token, size_t start) { size_t len = length(); for(size_t i=start; i------------------------- std::string& CSemiExp::operator [](unsigned int n) { if(n<0 || length()<= n) { std::string msg = "index out of domain in CSemiExp::operator[](int)"; throw std::exception(msg.c_str()); } return _tok[n]; } //----< return readonly reference to nth token >------------------------- std::string CSemiExp::operator [](unsigned int n) const { if(n<0 || length()<= n) { std::string msg = "index out of domain in CSemiExp::operator[](int)"; throw std::exception(msg.c_str()); } return _tok[n]; } //----< display semi-expression on cout with little formatting >--------- void CSemiExp::show(const std::string& msg, bool verbose) const { if(!verbose) return; std::cout << " "; if(msg.length() > 0) std::cout << msg << ": "; for(unsigned int i=0; i<_tok.size(); i++) if(_tok[i] != "\n") std::cout << _tok[i] << " "; std::cout << std::endl; } //----< display semi-expression on cout with little formatting >--------- std::string CSemiExp::showToString(const std::string& msg, bool verbose) const { if(!verbose) return ""; std::ostringstream sout; sout << " "; if(msg.length() > 0) sout << msg << ": "; for(unsigned int i=0; i<_tok.size(); i++) if(_tok[i] != "\n") sout << _tok[i] << " "; sout << std::endl; return sout.str(); } // ///////////////////////////////////////////////////////////////////////// // Test Stub #ifdef TEST_CPPSEMIEXP #include #include // int main() { std::string file = "..\\CppSemiExp.h"; std::ifstream in(file.c_str()); if(!in.good()) { std::cout << "\n\n can't open file " << file << "\n\n"; return 1; } CToker toker(&in); CSemiExp semi(&toker); semi.registerDefaultFilters(); while(semi.get()) semi.show(); semi.get(); semi.show(); std::cout << "\n\n"; } #endif