#ifndef CPPSEMIEXP_H // compile if CPPSEMIEXP_H is not in symbol table #define CPPSEMIEXP_H // put CPPSEMIEXP_H in symbol table ///////////////////////////////////////////////////////////////////////// // CppSemiExp.h - 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 // ///////////////////////////////////////////////////////////////////////// /* * Module Operations: * ================== * CppSemiExp.h Declares a class CSemiExp designed to collect tokens from * a std stream and assemble them into meaningful sequences. Semi-expressions. * end in single character tokens "{", "}", ";", or "\n" following a #. * * A semi-expression contains just the right amount of code for analysis * without requiring a lot of state management. * * Public Interface: * ================= * std::fstream in(someFile); * CToker toker(&in); * CSemiExp semi(&toker); // create CSemiExp instance * while(semi.get()) // extract next semi-expression * // do something with semi * int n = semi.length(); // read number of tokens * std::string tok = semi[2]; // read 3rd token's value * semi[1] = "test"; // change 2nd token's value * size_t loc = se.find("{"); // find occurance of "{" token * semi.show(verbose); // display on cout if verbose is true * semi.clear(); // remove all tokens * CppCommentFilter filt1(&toker); // define C++ comment filter * CCCommentFilter filt2(&toker); // define C comment filter * CDoubleQuoteFilter filt3(&toker); // define double quote filter * CSingleQuoteFilter filt4(&toker); // define single quote filter * semi.registerFilter(&filt1); // filter stuff from semi-expression * */ // /* * Maintenance History: * ==================== * ver 1.3 : 24 Feb 04 * - Fixed a bug reported by Carmen Vaca Ruiz and Ashish Poddar. * - Thanks Carmen and Ashish! * With version 1.2, if you set the working directory to, say, ".." in * scan project properties then the scanner crashes. The problem was * still due to registerDefaultFilters. Specifically due to the * static filters I put there holding a pointer to the wrong CToker * object when you come out of the scanner's recursion. I've fixed * this by wiping out the registerDefaultFilters() function, never to * return. * - Now you must register the filters individually in place * of the call to that function. Sigh. * ver 1.2 : 18 Feb 04 * - added a test harness to make detailed testing easier. * - fixed two bugs reported by Priyaa Nachimuthu - Thanks Priyaa! * - CppSemiExp crashes when copied or assigned to another instance * in a nested scope and use filtering after copy is destroyed. * Problem was due to deletions in the destructor for filters * created by another instance. Sigh. * Fixed by making default filters static and not deleting in * destructor. * - C++ comment filter hung if there was a comment at the end of * a file with no newline following. Fixed by checking for bad * stream state in all the filters. * ver 1.1 : 08 Feb 04 * - added Find function * - added bodies for CDoubleQuoteFilter and CSingleQuoteFilter * ver 1.0 : 12 Jan 04 * - first release * * Build Process: * ============== * Required Files: * CppSemiExp.h, CppSemiExp.cpp, CppToker.h, CppToker.cpp * * Compiler Command: * cl /DTest_CPPSEMIEXP /EHsc CppSemiExp.cpp CppToker.cpp; */ // #include "CppToker.h" #include #include namespace Scanner { /////////////////////////////////////////////////////////////////////// // family of token filters class ITokenFilter { public: ITokenFilter(CToker *pToker) : _pToker(pToker) {} virtual bool present()=0; virtual bool extract(std::string &token)=0; void setToker(CToker* pToker) { _pToker = pToker; } protected: CToker *_pToker; }; class CCppCommentFilter : public ITokenFilter { public: CCppCommentFilter(CToker *pToker) : ITokenFilter(pToker) {} virtual bool present(); virtual bool extract(std::string &token); }; class CCCommentFilter : public ITokenFilter { public: CCCommentFilter(CToker *pToker) : ITokenFilter(pToker) {} virtual bool present(); virtual bool extract(std::string &token); }; class CDoubleQuoteFilter : public ITokenFilter { public: CDoubleQuoteFilter(CToker *pToker) : ITokenFilter(pToker) {} virtual bool present(); virtual bool extract(std::string &token); }; class CSingleQuoteFilter : public ITokenFilter { public: CSingleQuoteFilter(CToker *pToker) : ITokenFilter(pToker) {} virtual bool present(); virtual bool extract(std::string &token); }; // /////////////////////////////////////////////////////////////////////// // class representing semi-expressions class CSemiExp { public: CSemiExp(CToker *pToker=0); // constructor with default argument ~CSemiExp(); ////////////////////////////////////////////////////////// // Compiler generated copy constructor and assignment // operator work, so they are not provided here. bool get(); size_t length() const; std::string& operator[](size_t n); std::string operator[](size_t n) const; void insert(unsigned int i, const std::string &token); void push_back(const std::string &token); void erase(unsigned int i); size_t find(const std::string& token, size_t start=0); void clear(); void show(const std::string& msg="", bool verbose=true) const; std::string showToString(const std::string& msg="", bool verbose=true) const; void registerFilter(ITokenFilter *pITokenFilter); // void registerDefaultFilters(); private: bool isTerminator(const std::string &tok) const; bool filter(std::string &token); void checkIndex(unsigned int); CToker *_pToker; std::vector _tok; std::list _filter; }; } #endif