rendered paste body#include <iostream>#include <string>#include <stack>#include <fstream>class text_buffer{ std::string m_text;public: typedef std::string::const_iterator const_iterator; const_iterator begin() const {return m_text.begin();} const_iterator end() const {return m_text.end();} bool read_from_file(const std::string & file_name) { m_text.clear(); std::ifstream istr(file_name.c_str(),std::ios::binary); if(!istr) { std::cerr << "can't open input file:" << file_name << std::endl; return false; } int n = 0; char buf[1024]; while(n = istr.readsome(buf,1024)) m_text.append(buf,buf+n); return true; } };class alphabet{ char alpha[256];public: alphabet() { memset(alpha,0,256); } void init(const std::string & a) { for(std::string::const_iterator p = a.begin(); p != a.end(); ++p) { alpha[static_cast<const unsigned char>(*p)] = 1; } } bool is_alpha(const unsigned char c) {return alpha[c] == 1;}};bool bin_checker(const unsigned char c){ return c == 0x30 || c == 0x31;}bool dec_checker(const unsigned char c){ return c >= 0x30 && c <= 0x39;}bool hex_checker(const unsigned char c){ return dec_checker(c) || (c >= 0x61 && c <= 0x66);}class validator{ std::string tgOpen; std::string tgClose; alphabet alpha;public: bool init(const std::string & tag_file) { std::ifstream istr(tag_file.c_str()); if(!istr) { std::cerr << "can't open tag's file " << std::endl; return false; } std::getline(istr,tgOpen); std::getline(istr,tgClose); std::string al; // читаем алфавит std::getline(istr,al); alpha.init(al); if(tgOpen.size() != tgClose.size()) { std::cerr << "tag's file has incorrect format" << std::endl; return false; } return true; } void validate_ABC(const text_buffer & text) { text_buffer::const_iterator cur = text.begin(), end = text.end(); for (;cur != end;++cur) { if( !alpha.is_alpha(*cur)) { std::cerr << "symbol \'" << *cur << "\' not in alphabet" << std::endl; } } } template<typename CheckFunctor> void test_num(text_buffer::const_iterator &p, const text_buffer::const_iterator &end, CheckFunctor fun, const std::string & base ) { for(;p!=end && *p != ' ' && *p != '\t' && *p != '\n'; ++p) { if(!fun(*p)) { std::cerr << "Error! Symbol \'" << *p << "\' not digit in " << base << std::endl; } } } void validate_num(const text_buffer & text) { text_buffer::const_iterator cur = text.begin(), end = text.end(); for (;cur != end;) { switch(*cur) { case '@': test_num(++cur,end,&bin_checker,"bin"); break; case '$': test_num(++cur,end,&dec_checker,"dec"); break; case '#': test_num(++cur,end,&hex_checker,"hex"); break; default: ++cur; } } } bool check_num(text_buffer::const_iterator & cur, text_buffer::const_iterator end ) { switch(*cur) { case '@': test_num(++cur,end,&bin_checker,"bin"); return true; break; case '$': test_num(++cur,end,&dec_checker,"dec"); return true; break; case '#': test_num(++cur,end,&hex_checker,"hex"); return true; break; default: return false; } return false; } bool check_alpha(const text_buffer::const_iterator & cur) { if( !alpha.is_alpha(*cur)) { std::cerr << "symbol \'" << *cur << "\' not in alphabet" << std::endl; return false; } return true; } void validate_tag(const text_buffer & text) { bool comment = false; std::stack<char> tags; text_buffer::const_iterator cur = text.begin(), end = text.end(); for (;cur != end;) { if (*cur == '!') { comment=!comment; ++cur; continue; } if (!comment) { if( tgOpen.find(*cur) != std::string::npos) { std::cout << *cur << std::endl; tags.push(*cur); ++cur; continue; } int n; if( (n = tgClose.find(*cur)) != std::string::npos) { std::cout << *cur << std::endl; if (!tags.empty()) { if (tgOpen[n] != tags.top()) std::cout<<"tags error: no open tag!"<<std::endl; tags.pop(); } else { std::cout<<"tags error: wrong close tag!"<<std::endl; } ++cur; } else if(!check_num(cur,end)) { check_alpha(cur++); } } else ++cur; } if (!tags.empty()) { std::cout<<"tags error: no close tag!"<<std::endl; } std::cout<<"comment: "<<comment<<std::endl; } };int main(int argc, char ** argv){ if(argc != 3) { std::cerr <<"Usage: validator <text_file> <tag_file>" << std::endl; return 1; } text_buffer text; if(!text.read_from_file(argv[1])) { return 1; } validator val; if(!val.init(argv[2])) { return 1; } val.validate_tag(text); return 0;}