Files
2026-06-01 12:46:52 +02:00

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);
}
}