/////////////////////////////////////////////////////////////// // semi.cpp - build semiexpression, e.g., list of tokens // // ver 2.3 terminated by special characters // // // // Language: Visual C++, ver 6.0 // // Platform: Micron Dual Pentium Pro 200, Win NT 4.0 // // Application: CSE784 Example // // Author: Jim Fawcett, CST 2-187, Syracuse Univ. // // (315) 443-3948, fawcett@ecs.syr.edu // /////////////////////////////////////////////////////////////// #pragma warning(disable : 4786) #include #include #include "tok.h" #include "semi.h" using namespace std; //----< constructor >------------------------------------------ semiExp::semiExp(istream &input) : Toker(input), _next(0), linesAtFirstTok(0) { } //----< append token to end of semiExpression >---------------- size_t semiExp::append(const string &tok) { se.push_back(tok); return se.size(); } //----< return number of tokens in semiExpression >------------ size_t semiExp::length() const { return se.size(); } //----< remove all elements from semiExpression >-------------- void semiExp::flush() { se.erase(se.begin(),se.end()); } //----< is first char of token one of the special chars? >----- bool semiExp::isTerminator(const string &tok) { switch(tok[0]) { case '{' : return true; case '}' : return true; case ';' : return true; case '\n': if(se.size() > 0) { for(size_t i=0; i------------------ bool semiExp::get(bool includeNewline) { string tok; se.erase(se.begin(),se.end()); _next = 0; bool more; while((more = Toker.getTok(tok)) == true) { if(includeNewline || tok[0] != '\n') { if(se.size() == 0) linesAtFirstTok = lines(); se.push_back(tok); } if(isTerminator(tok)) break; } if(se.size() == 0) { se.push_back(tok); return false; } if(!more && (se[se.size()-1] != tok)) se.push_back(tok); return more; } //----< how many lines when we collected first token? >-------- unsigned int semiExp::linesAtFirstToken() { return linesAtFirstTok; } //----< if this condition is false, abort with message >------- void semiExp::check(bool condition, const char *msg) { if(!condition) throw msg; } //----< index operator >--------------------------------------- string& semiExp::operator[](size_t n) { check(0<=n && n---------------------------------- semiExp& semiExp::operator +=(const string &tok) { se.push_back(tok); return *this; } // //----< send each token in semiExpression to stdout >---------- void semiExp::display(size_t i, size_t j) { size_t k; for(k=i; k<=j && k---------------------------- size_t semiExp::find(const string &tok, size_t j) { size_t i; for(i=j; i------------------ size_t semiExp::textFind(const string &s, int j) { size_t i; for(i=j; i-------------------------------- size_t semiExp::next(const string &tok) { size_t i; for(i=_next; i------------------------------------- void semiExp::resetNext() { _next = 0; } // //----< is this closing token match? >------------------------- string semiExp::closes(const string &tok) { switch(tok[0]) { case '(' : return ")"; case '[' : return "]"; case '{' : return "}"; default : return "no match"; } } //----< find closure >----------------------------------------- // // Useful only if preceded by successful search for '(' or '[' size_t semiExp::findClosure() { string tok; if(_next) tok = se[_next-1]; else return se.size(); size_t i, level = 1; for(i=_next; i-------------------------------- // // Useful only if preceded by successful search for '(', '[', or '{' size_t semiExp::findExClosure() { string tok; if(_next) tok = se[_next-1]; else return -1; size_t i, level = 1; do { for(i=_next; i---------------------------- void semiExp::remove(size_t i) { if(i<0 || se.size() <= i) return; se.erase(se.begin()+i); } //----< constructor >------------------------------------------ packedTokens::packedTokens() { toks["::"] = both; toks["(" ] = both; toks[")" ] = both; toks["[" ] = both; toks["]" ] = both; toks["." ] = both; toks["," ] = left; toks[";" ] = left; toks["*" ] = right; toks["&" ] = right; toks[":" ] = not; toks["{" ] = not; toks["}" ] = not; toks["const"] = not; } //----< is this token in the packed token set >---------------- bool packedTokens::in(const string &s,packType pt) const { map::const_iterator it = toks.find(s); if(it != toks.end()) if(it->second == pt) return true; return false; } // //----< format semi-expression using token packing >----------- string packedTokens::format(semiExp &se) { size_t i; string temp; for(i=0; i-------------------------------------------- #ifdef TEST_SEMI #include #include void main(int argc, char *argv[]) { ifstream in; semiExp se(in); if(argc == 1) { cout,"\n please enter name of file to process\n"; return; } cout << "\n Testing Collection of SemiExpressions " << "\n =======================================\n"; int i; for(i=1; i 0) { se0.remove(0); se0.display(); } cout << "\n removing all tokens from the back: " << "\n ------------------------------------\n"; seSave.display(); while(seSave.length() > 0) { seSave.remove(seSave.length()-1); seSave.display(); } cout << "\n attempting to remove tokens from empty semiExp: " << "\n -------------------------------------------------\n"; seSave.remove(0); seSave.display(); // cout << "\n Testing Closure operations " << "\n ============================\n"; string s1 = "string& operator[](int n);"; istrstream test1(s1.c_str()); cout << " analyzing string: " << s1 << "\n\n"; semiExp se1(test1); se1.get(); size_t pos = se1.find("("); pos = se1.findClosure(); cout << " The closure of \"(\" is at position " << static_cast(pos) << '\n'; string s2 = "if(pred) { cout x; } else cout y;"; istrstream test2(s2.c_str()); cout << "\n analyzing string: " << s2 << "\n\n"; semiExp se2(test2); se2.get(); se2.display(); cout << "\n finding closure of \"{\"\n\n"; se2.find("{"); se2.findExClosure(); se2.display(); se2.get(); se2.display(); cout << "\n Testing index error handling " << "\n ==============================\n"; try { se[-1]; } catch(const char *msg) { cout << " " << msg << "\n\n"; } cout << "\n the number of lines in this file is: " << se.lines() << '\n'; cout << "\n the net number of braces in this file is: " << se.scopeLevel() << '\n'; cout << "\n\n"; } #endif