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