#include "stdafx.h" #include #include "KTokenParser.h" #include #pragma warning(disable:4311) #pragma warning(disable:4267) KTokenParser::KTokenParser() { static char Whitespacechr[] = {'\n', '\r', ' ', '\t'}; static char Tokendata[] = { KTOKEN_HANDLER::KTOKEN_COMMA, ',' ,KTOKEN_HANDLER::KTOKEN_ASSIGN, '=' ,KTOKEN_HANDLER::KTOKEN_OBRACE, '{' ,KTOKEN_HANDLER::KTOKEN_CBRACE, '}' }; SetWhiteSpaceChar(Whitespacechr, _countof(Whitespacechr) ); SetTokenChar(Tokendata, _countof(Tokendata) ); } KTokenParser::~KTokenParser() { } void KTokenParser::SetWhiteSpaceChar(char *pWhiteSpaceChar, int nCount) { m_pWhiteSpaceChar = pWhiteSpaceChar; m_nWhiteSpaceCount = nCount; } void KTokenParser::SetTokenChar(char* pTokenChar, int nCount) { m_pTokenChar = pTokenChar; m_nTokenCharCount = nCount; } bool KTokenParser::AddToken(LPCSTR lpszToken, short tokenID, K_TOKEN_MSG fn) { // Token is already added. if( m_mapTokenList.find(lpszToken) != m_mapTokenList.end() ) return false; m_mapTokenList.insert(std::make_pair(lpszToken, KTOKEN_MAP(tokenID,fn) ) ); return true; } void KTokenParser::LoadStream(KStream & stream) { int nLineCount = 1; while(1) { bool bRet = _getNextToken(stream,nLineCount); if(!bRet) { m_pTokenHandler->_OnTokenEnd(); break; } } } bool KTokenParser::_getNextChar( KStream &stream, char *c, int &linecount ) { char chr; while ( 1 ) { nextchar: if ( stream.Read( &chr, 1 ) ) { if ( chr == '\n' ) ++linecount; for ( int i=0 ; i < m_nWhiteSpaceCount; i++ ) if ( chr == m_pWhiteSpaceChar[i] ) goto nextchar; *c = chr; return true; } else return false; } } bool KTokenParser::_getNextWord( KStream &stream, char *c, bool &isWhiteSpace, int &linecount ) { char chr; isWhiteSpace = false; while ( 1 ) { if ( stream.Read( &chr, 1 ) ) { for ( int i=0 ; i < m_nWhiteSpaceCount ; i++ ) { if ( chr == m_pWhiteSpaceChar[i] ) { if ( chr == '\n' ) ++linecount; isWhiteSpace = true; *c = chr; return true; } } *c = chr; return true; } else return false; } } bool KTokenParser::_getNextString(KStream & stream, std::string & name, int & linecount) { char chr; while ( 1 ) { if ( stream.Read( &chr, 1 ) ) { if ( chr == '\n' ) ++linecount; if(chr == '"') return true; name += chr; } else return false; } } bool KTokenParser::_skipline( KStream &stream, int &linecount ) { char chr; while ( 1 ) { if ( stream.Read( &chr, 1 ) ) { if ( chr == '\n' ) { ++linecount; return true; } } else return false; } } bool KTokenParser::_skiptocomment( KStream &stream, int &linecount ) { char chr; while ( 1 ) { if ( stream.Read( &chr, 1 ) ) { if ( chr == '\n' ) ++linecount; if ( chr == '*' ) { stream.Read( &chr, 1 ); if ( chr == '/' ) return true; else stream.Seek( -1, KStream::seekCur ); } } else return false; } } bool KTokenParser::_getNextToken( KStream &stream, int &linecount) { char c; std::string name; using namespace KTOKEN_HANDLER; while ( 1 ) { if ( _getNextChar(stream, &c,linecount ) == false ) return false; // String을 읽게 되는 경우 if(c == '"') { bool bValid = _getNextString(stream, name, linecount); m_pTokenHandler->_OnNoTokenFound((DWORD)name.c_str(),linecount,0); return bValid; } for ( int i=0 ; i< m_nTokenCharCount/2 ; i++ ) { if ( m_pTokenChar[i*2+1] == c ) { m_pTokenHandler->_OnCharTokenFound(m_pTokenChar[i * 2], linecount,0); return true; } } if( c) name += c; DWORD pos = stream.Tell(); bool ws; if ( _getNextWord( stream, &c, ws, linecount ) == false ) { return false; } std::string tempname = name; tempname += c; if ( strcmp( tempname.c_str(), "//" ) == 0 ) { name = ""; if ( _skipline( stream, linecount ) == false ) return false; continue; } if ( strcmp( tempname.c_str(), "/*") == 0 ) { name = ""; if ( _skiptocomment( stream, linecount ) == false ) return false; continue; } stream.Seek( pos, KStream::seekSet ); while ( 1 ) { bool ws; DWORD pos = stream.Tell(); if ( _getNextWord(stream, &c, ws, linecount) == false ) { TokenMap::iterator it = m_mapTokenList.find(name); if(it != m_mapTokenList.end() ) (m_pTokenHandler->* it->second.fn)(it->second.tokenID,linecount,0); return false; } if ( ws ) // word end { TokenMap::iterator it = m_mapTokenList.find(name); if(it != m_mapTokenList.end() ) { (m_pTokenHandler->* it->second.fn)(it->second.tokenID,linecount,0); } else { m_pTokenHandler->_OnNoTokenFound((DWORD)name.c_str(),linecount,0); } return true; } for ( int i=0 ; i < m_nTokenCharCount / 2 ; i++ ) { if ( m_pTokenChar[i*2+1] == c ) { stream.Seek( pos, KStream::seekSet ); TokenMap::iterator it = m_mapTokenList.find(name); if(it != m_mapTokenList.end() ) { (m_pTokenHandler->* it->second.fn)(it->second.tokenID,linecount,0); } else { m_pTokenHandler->_OnNoTokenFound((DWORD)name.c_str(),linecount,0); } return true; } } if( c ) name += c; } } } // KTokenHandler Implement KTokenHandler::KTokenHandler() { m_TokenParser.SetHandler(this); } // Just Dummy (for compiling) void KTokenHandler::_InitializeTokenMap() { } void KTokenHandler::_AddToken(LPCSTR lpszToken, short tokenID, K_TOKEN_MSG fn) { bool bRet = m_TokenParser.AddToken(lpszToken,tokenID,fn); if(!bRet) { #ifndef _RELEASE char buff[128]; sprintf(buff,"Token : %s add Error", lpszToken); MessageBox(NULL,buff, "Error", MB_OK); #endif assert(false); } }