// SimpleParser.cpp: implementation of the CSimpleParser class. // ////////////////////////////////////////////////////////////////////// #include "SimpleParser.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CSimpleParser::CSimpleParser() { m_szFileName = NULL; m_szMaskString = NULL; m_lMaskLen = 0; m_lPointerInMask = 0; m_pFile = NULL; //m_lTokenCount = 0; m_lLineCount = 0; m_lTokenInLine = 0; m_vec_szTokens.reserve( 10 ); m_vec_szTmpLine.reserve( 1000 ); } CSimpleParser::~CSimpleParser() { if( m_pFile ) { fclose( m_pFile ); m_pFile = NULL; } SAFE_DELETEA( m_szFileName ); SAFE_DELETEA( m_szMaskString ); for( int i = 0; i < m_vec_szTokens.size(); i++ ) { SAFE_DELETEA( m_vec_szTokens[i] ); } m_vec_szTokens.clear(); m_vec_szTmpLine.clear(); } bool CSimpleParser::Reset() { if( m_pFile ) { fclose( m_pFile ); m_pFile = NULL; } SAFE_DELETEA( m_szFileName ); SAFE_DELETEA( m_szMaskString ); m_lMaskLen = 0; m_lPointerInMask = 0; //m_lTokenCount = 0; for( int i = 0; i < m_vec_szTokens.size(); i++ ) { SAFE_DELETEA( m_vec_szTokens[i] ); } m_vec_szTokens.clear(); m_vec_szTmpLine.clear(); m_lLineCount = 0; m_lTokenInLine = 0; return true; } bool CSimpleParser::OpenFile( const char* szFileName, const char* szMaskString ) { _ASSERT( szFileName ); FILE* fp; if( szMaskString ) { // decrypting mode if( (fp = fopen(szFileName, "rb")) == NULL ) { return false; // file open error } } else { // normal mode if( (fp = fopen(szFileName, "rt")) == NULL ) { return false; // file open error } } Reset(); m_pFile = fp; m_szFileName = new char[strlen(szFileName) + 1]; strcpy( m_szFileName, szFileName ); if( szMaskString ) { m_lMaskLen = strlen(szMaskString); m_szMaskString = new char[m_lMaskLen+1]; strcpy( m_szMaskString, szMaskString ); m_lPointerInMask = 0; } return true; } inline static bool IsWhiteSpace( char c ) { if( '\n' == c ) return true; if( '\t' == c ) return true; if( ' ' == c ) return true; return false; } // white space¾øÀÌ Á¸Àç ÀÚü°¡ ÇϳªÀÇ ÅäÅ«ºÐ¸®ÀÌÀ¯°¡ µÇ´Â ¹®ÀÚ¸¦ operator¶ó°í ÇÑ´Ù. // (³»¸¾´ë·Î-_-;;) inline static bool IsOperator( char c ) { if( '(' == c ) return true; if( ')' == c ) return true; if( '{' == c ) return true; if( '}' == c ) return true; if( '[' == c ) return true; if( ']' == c ) return true; if( '<' == c ) return true; if( '>' == c ) return true; // +- ±âÈ£ Á¦¿Ü...-_-; ºÎÈ£·Î ¾²ÀÏ ¼ö ÀÖ´Ù. /*if( '+' == c ) return true; if( '-' == c ) return true;*/ if( '*' == c ) return true; if( '/' == c ) return true; if( ',' == c ) return true; // '.' Á¦¿Ü. ¼Ò¼öÁ¡À¸·Î ¾²ÀδÙ-_-;; ÀÌ·±.. //if( '.' == c ) return true; if( ':' == c ) return true; if( ';' == c ) return true; if( '`' == c ) return true; if( '\'' == c ) return true; if( '=' == c ) return true; if( '|' == c ) return true; return false; } int CSimpleParser::GetChrFromFile() { int c; if( m_szMaskString ) { c = fgetc(m_pFile); if( EOF == c ) { return EOF; } c ^= m_szMaskString[m_lPointerInMask]; if( 0xD == c ) // LF/CR combo ó¸® { // ¸¶½ºÅ·µÈ ´ÙÀ½ ij¸¯ÅÍ ¾ò¾î¿À±â int c2 = m_szMaskString[(m_lPointerInMask+1)%m_lMaskLen] ^ fgetc(m_pFile); if( 0xA == c2 ) { m_lPointerInMask = (m_lPointerInMask + 2) % m_lMaskLen; return '\n'; } else { fseek( m_pFile, -1, SEEK_CUR ); } } m_lPointerInMask = (m_lPointerInMask + 1) % m_lMaskLen; return c; } //else ºí·°ÀÌÁö¸¸ ±¸Á¶ÀûÀ¸·Î ÇÊ¿ä¾ø¾îÁ³À½(decrypting ¾Æ´Ï¸é normalÀ̴ϱî) // normal reading return fgetc(m_pFile); } int CSimpleParser::ReadLine() { int i; // clear previously read tokens for( i = 0; i < m_vec_szTokens.size(); i++ ) { SAFE_DELETEA( m_vec_szTokens[i] ); } m_vec_szTokens.clear(); // check if stream opened if( !m_pFile ) { return EOF; } int c; while( (c = GetChrFromFile()) != EOF ) { if( '\n' == c ) { //m_vec_szTmpLine.push_back('\0'); break; } m_vec_szTmpLine.push_back( (char)c ); } m_lLineCount++; m_lTokenInLine = 0; if( feof(m_pFile) ) { fclose(m_pFile); m_pFile = NULL; //return EOF; } std::vector vec_szTmpToken; vec_szTmpToken.reserve( 100 ); // allocate appropriate space for 1 token for( i = 0; i < m_vec_szTmpLine.size(); i++ ) { if( IsWhiteSpace( m_vec_szTmpLine[i] ) ) { continue; } if( '/' == m_vec_szTmpLine[i] ) // 'comment' check { if( (i+1) < m_vec_szTmpLine.size() && '/' == m_vec_szTmpLine[i+1] ) { break; // skip parsing remainder of the line } } if( IsOperator(m_vec_szTmpLine[i]) ) { vec_szTmpToken.push_back( m_vec_szTmpLine[i] ); vec_szTmpToken.push_back('\0'); } else switch( m_vec_szTmpLine[i] ) { case '\"': // beginning of a string for( i++ ; i < m_vec_szTmpLine.size(); i++ ) { if( '\"' == m_vec_szTmpLine[i] ) // end of a string { break; } vec_szTmpToken.push_back( m_vec_szTmpLine[i] ); } vec_szTmpToken.push_back('\0'); break; default: // otherwise parse normal token for( ; i < m_vec_szTmpLine.size(); i++ ) { if( IsWhiteSpace(m_vec_szTmpLine[i]) ) { break; } else if( IsOperator(m_vec_szTmpLine[i]) ) { i--; // one char backward break; } vec_szTmpToken.push_back( m_vec_szTmpLine[i] ); } vec_szTmpToken.push_back('\0'); break; } // copy parsed token char* szTmp = new char[vec_szTmpToken.size()]; strcpy( szTmp, &(vec_szTmpToken[0]) ); vec_szTmpToken.clear(); m_vec_szTokens.push_back(szTmp); } m_vec_szTmpLine.clear(); return m_vec_szTokens.size(); } char* CSimpleParser::GetToken( int n ) { static char cDummyEmptyToken = '0'; if( (n+1) > m_vec_szTokens.size() ) { //return NULL; return &cDummyEmptyToken; } return m_vec_szTokens[n]; } int CSimpleParser::GetTokenNum() { return m_vec_szTokens.size(); } int CSimpleParser::GetLineNum() { return m_lLineCount; } char* CSimpleParser::GetFileName() { return m_szFileName; } char* CSimpleParser::GetNextToken() { if( m_lTokenInLine >= GetTokenNum() ) { do { if( EOF == ReadLine() ) { return NULL; } } while( 0 == GetTokenNum() ); } return GetToken( m_lTokenInLine++ ); }