All pastes #819525 Raw Edit

Unnamed

public cpp v1 · immutable
·published 2007-12-17 00:49 UTC
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;}