Angler.lee 2012. 9. 13. 16:46
#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;
}​