#ifndef _CLEXER_H
#define _CLEXER_H
#include <vector>
#include <windows.h>
#define MAX_SIZE_OF_BUFFER 65536
#define TOKEND_NUMBER 1000
#define TOKEND_STRING 1001
#define TOKEND_END 65534
#define TOKEND_IDENTIFIER 65535
#define TOKEND_NOTDEFINED 65536
typedef std::vector<CHAR*> SPLIT;
class CLexer
{
protected:
HANDLE m_File;
CHAR* m_Char; ///파일의 내용을 읽어드림
DWORD m_Pointer; ///현재 Buffer상에 읽고 있는 문자열의 위치
DWORD m_BufSize; ///Buffer의 크기
DWORD m_NowLoaded; ///현재 읽어 들여놓은 크기
DWORD m_TotalFileSize; ///파일의 전체크기
DWORD m_NowProgress; ///현재 진행
SPLIT m_spToken;
protected:
/*-----------------------------------------------------------
* 내부 처리용
*----------------------------------------------------------*/
CHAR GetNextChar();
public:
/*-----------------------------------------------------------
* 생성자 소멸자
*----------------------------------------------------------*/
CLexer(LPCSTR p_FileName=NULL, DWORD BufSize = MAX_SIZE_OF_BUFFER);
virtual ~CLexer();
/*-----------------------------------------------------------
* 인터페이스 함수
*----------------------------------------------------------*/
HRESULT Open(LPCSTR p_FileName, DWORD BufSize = MAX_SIZE_OF_BUFFER);
VOID Close();
BOOL Reset();
LONG GetLine(CHAR* TokenString);
LONG GetToken(CHAR* TokenString);
SPLIT& split(char* reword);
};
#endif
#include "Lexer.h"
CLexer::CLexer(LPCSTR p_FileName, DWORD BufSize)
{
m_Char = NULL; ///파일의 내용을 읽어드림
m_Pointer = 0; ///현재 Buffer상에 읽고 있는 문자열의 위치
m_BufSize = BufSize; ///Buffer의 크기
m_NowLoaded = 0; ///현재 읽어 들여놓은 크기
m_TotalFileSize = 0; ///파일의 전체크기
m_NowProgress = 0; ///현재 진행
if(p_FileName != NULL)
Open(p_FileName, BufSize);
}
CLexer::~CLexer()
{
if(m_File != NULL) Close();
//Token Vector 소멸
m_spToken.clear();
}
HRESULT CLexer::Open(LPCSTR p_FileName, DWORD BufSize)
{
///FileName이 NULL일 경우 종료
if(p_FileName == NULL) return FALSE;
///BUFSIZE가 0일경우 종료
if(BufSize == 0) return FALSE;
///파일 Open
m_File = CreateFile(p_FileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(m_File == INVALID_HANDLE_VALUE)
{
//TRACE("Cant open File!");
return E_FAIL;
}
m_TotalFileSize = GetFileSize(m_File, NULL);
m_NowProgress = 0;
m_Pointer = 0;
m_NowLoaded = 0;
m_BufSize = BufSize;
m_Char = new CHAR[m_BufSize];
ZeroMemory(m_Char, m_BufSize);
return S_OK;
}
VOID CLexer::Close()
{
if(m_File == NULL)
{
//TRACE("File is not Opened\n");
return;
}
///파일을 닫는다
CloseHandle(m_File);
m_File = NULL;
///Buffer를 지운다
m_BufSize = 0;
delete [] m_Char;
}
CHAR CLexer::GetNextChar()
{
if(m_Pointer == m_NowLoaded)
{
if(ReadFile(m_File, m_Char, m_BufSize, &m_NowLoaded, NULL) != TRUE)
{
return 0;
}
if(!m_NowLoaded)
{
return 0;
}
m_NowProgress++;
m_Pointer = 1;
return m_Char[0];
}
else ///버퍼가 차지 않았을 경우
{
m_NowProgress++;
m_Pointer++;
return m_Char[m_Pointer-1];
}
}
SPLIT& CLexer::split(char* string)
{
//벡터 초기화
m_spToken.clear();
int idx = 0;
int length = strlen(string);
for(int i=0; i < length; i++){
if(string[i] != ' ' && string[i] != '\t' && string[i] != '\r'){
m_spToken.push_back(&string[i]); //빈공간이 아닐 경우 startIndex로 지정
//빈공간이 나올때까지 whileLoop
while(string[i] != ' ' && string[i] != '\t' && string[i] != '\t' && string[i] != '\0') i++;
}
string[i] = '\0';
}
return m_spToken;
}
LONG CLexer::GetLine(CHAR* TokenString)
{
ZeroMemory(TokenString, sizeof(TokenString));
CHAR Char = GetNextChar();
while(Char == ' ' || Char == '\t' || Char == '\r' || Char =='\n')
{
Char = GetNextChar();
if(!Char) return TOKEND_END;
}
LONG Point = 0;
while(Char != '\n')
{
TokenString[Point] = Char;
Char = GetNextChar();
if(!Char) return TOKEND_END;
Point++;
}
TokenString[Point] = NULL;
return TOKEND_STRING;
}
LONG CLexer::GetToken(CHAR* TokenString)
{
ZeroMemory(TokenString, sizeof(TokenString));
CHAR Char = GetNextChar();
while(Char == ' ' || Char == '\t' || Char == '\r' || Char =='\n')
{
Char = GetNextChar();
if(!Char) return TOKEND_END;
}
/*-----------------------------------------------------------
* 숫자나 -가 붙어있는 숫자 검사후 넘버임을 리턴,
*----------------------------------------------------------*/
if((Char >= '0' && Char <= '9') || Char == '-')
{
LONG Point = 0;
while((Char >= '0' && Char <= '9') || Char == '-' || Char == '.')
{
TokenString[Point] = Char;
Char = GetNextChar();
if(!Char) return TOKEND_END;
Point++;
}
TokenString[Point] = NULL;
return TOKEND_NUMBER;
}
/*-----------------------------------------------------------
* " " 표 안에있는 스트링 검출
*----------------------------------------------------------*/
else if(Char == '"')
{
Char = GetNextChar();
if(!Char) return TOKEND_END;
LONG Point = 0;
while(Char != '"')
{
TokenString[Point] = Char;
Char = GetNextChar();
if(!Char) return TOKEND_END;
Point++;
}
TokenString[Point] = NULL;
return TOKEND_STRING;
}
/*-----------------------------------------------------------
* 그밖에 것들
*----------------------------------------------------------*/
else
{
TokenString[0] = Char;
Char = GetNextChar();
if(!Char) return TOKEND_END;
LONG Point = 1;
while(Char != ' ' && Char != '\t' && Char != '\t' && Char != '\n')
{
TokenString[Point] = Char;
Char = GetNextChar();
if(!Char) return TOKEND_END;
Point++;
}
TokenString[Point] = NULL;
return TOKEND_IDENTIFIER;
}
TokenString[0] = NULL;
return TOKEND_NOTDEFINED;
}
#include <stdio.h>
#include "Lexer.h"
int main(int argc, char **argv)
{
//Lexer 생성
CLexer * m_Lexer = new CLexer;
m_Lexer->Open(argv[1]);
//Lexer를 이용한 StirngToken
LONG token;
SPLIT strTok;
CHAR TokenString[256];
while(token = m_Lexer->GetToken(TokenString), token != TOKEND_END)
{
}
delete m_Lexer;
return 0;
}