297 lines
5.6 KiB
C++
297 lines
5.6 KiB
C++
#include "stdafx.h"
|
|
#include <assert.h>
|
|
#include "KTokenParser.h"
|
|
#include <kfile/KStream.h>
|
|
|
|
#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);
|
|
}
|
|
}
|
|
|