- Scanner.h
#pragma once
#include "global.h"
#include "Utility.h"
#include "TreeNode.h"
#define BUFLEN 500
class Scanner
{
/*
- 정규표현-> DFA 고안Scanner
: -> 상태-(전이)-> 상태-(전이)-> 상태-(전이)-> 상태.....
*/
// 식별자상태에대한Deterministic Finite Automation
enum
StateType {
START, // 시작상태
INASSIGN, // 지정연산자: 시작상태에서; 입력에의해도착, 만약계속해서= 입력시지정연산
토큰이생성. (else 오류토큰)
INCOMMENT, // 주석문: /*에의해서도착하여*/ 입력에의해서다시시작상태로반환됨
INNUM, // digit 측정
INID, // ID(영문자+ digit)를scan. (식별자를찾음)
DONE // 모든인식상태는Done으로귀결
} ;
public:
Scanner(void);
~Scanner(void);
int
getNextChar(void);
void
ungetNextChar(void);
TokenType getToken(void); // 입력문자를소비하여DFA에의해서인식되는다음토큰을반환.
char
lineBuf[BUFLEN]; /* holds the current line */
int
linepos; /* current position in LineBuf */
int
bufsize; /* current size of buffer string */
bool
EOF_flag; /* corrects ungetNextChar behavior on EOF
*/
};
- Scanner.cpp
#include "Scanner.h"
Scanner::Scanner(void)
{
linepos = 0;
bufsize = 0;
EOF_flag = false;
}
Scanner::~Scanner(void)
{
}
/******************************************************
getNextChar
- linebuf에서문자를읽어옴.
-
getNextChar fetches the next non-blank character
from
lineBuf, reading in a new line if lineBuf is
exhausted
*******************************************************/
int Scanner::getNextChar(void)
{
if
(!(linepos < bufsize))
{
lineno++;
if
(fgets(lineBuf,BUFLEN-1,fSource)) // fSource 파일에서읽어서버퍼를채움.
{
if
(EchoSource) fprintf(fListing,"%4d: %s",lineno,lineBuf);
bufsize =
strlen(lineBuf);
linepos = 0;
return
lineBuf[linepos++];
}
else
{
EOF_flag = true;
return
EOF;
}
}
else return lineBuf[linepos++];
}
/******************************************************
ungetNextChar
- linebuf에서문자를읽어옴.
*******************************************************/
void Scanner::ungetNextChar(void)
{
if
(!EOF_flag) linepos-- ;
}
/*************
GetToken() *****************************
- 입력문자를소비하여DFA에의해서인식되는다음토큰을반환.
- case1 :
DFA에따른automata 상태,
- case2 : 현재입력문자처리.
-
START, // 시작상태
INASSIGN,
// 지정연산자: 시작상태에서; 입력에의해도착, 만약계속해서= 입력시지정연산
토큰이생성. (else 오류토큰)
INCOMMENT,
// 주석문: /*에의해서도착하여* / 입력에의해서다시시작상태로반환됨
INNUM, // digit 측정
INID, // ID(영문자+ digit)를scan. (식별자를찾음)
DONE // 모든인식상태는Done으로귀결
*******************************************************/
TokenType
Scanner::getToken(void) //
{
/* index for
storing into tokenString */
int
tokenStringIndex = 0;
/* holds
current token to be returned */
TokenType currentToken;
/* current
state - always begins at START */
StateType state = START;
bool
save; // 문자가tokenString에추가될지의여부를나타냄(빈칸, 주석문, \\등의비소비문자등이포함되지않도록하는데필요)
while
(state != DONE)
{ int c
= getNextChar();
save = true;
switch
(state)
{ case
START:
if
(isdigit(c))
state = INNUM;
else if (isalpha(c))
state = INID;
else if (c == ':')
state = INASSIGN;
else if ((c == ' ') ||
(c == '\t') || (c == '\n'))
save = false;
else if (c == '{')
{ save = false;
state = INCOMMENT;
}
else
{ state = DONE;
switch
(c)
{ case
EOF:
save = false;
currentToken = END_FILE;
break;
case '=':
currentToken = EQ;
break;
case '<':
currentToken = LT;
break;
case '+':
currentToken = PLUS;
break;
case '-':
currentToken = MINUS;
break;
case '*':
currentToken = TIMES;
break;
case '/':
currentToken = OVER;
break;
case '(':
currentToken = LPAREN;
break;
case ')':
currentToken = RPAREN;
break;
case ';':
currentToken = SEMI;
break;
default:
currentToken = TYPE_ERROR;
break;
}
}
break;
case
INCOMMENT:
save = false;
if
(c == EOF)
{ state = DONE;
currentToken = END_FILE;
}
else
if (c == '}')
state = START;
break;
case
INASSIGN:
state = DONE;
if
(c == '=')
currentToken = ASSIGN;
else
{ /*
backup in the input */
ungetNextChar();
save = false;
currentToken =
TYPE_ERROR;
}
break;
case
INNUM:
if
(!isdigit(c))
{ /*
backup in the input */
ungetNextChar();
save = false;
state = DONE;
currentToken = NUM;
}
break;
case
INID:
if
(!isalpha(c))
{ /*
backup in the input */
ungetNextChar();
save = false;
state = DONE;
currentToken = ID;
}
break;
case
DONE:
default:
/* should never happen */
fprintf(fListing,"Scanner Bug: state= %d\n",state);
state = DONE;
currentToken = TYPE_ERROR;
break;
}
if
((save) && (tokenStringIndex <= MAXTOKENLEN))
tokenString[tokenStringIndex++] =
(char) c;
if
(state == DONE)
{ tokenString[tokenStringIndex] = '\0';
if
(currentToken == ID)
;// currentToken = reservedLookup(tokenString);
}
}
if
(TraceScan) {
fprintf(fListing,"\t%d: ",lineno);
//
printToken(currentToken,tokenString);
}
return
currentToken;
}
'Programming Language > C++' 카테고리의 다른 글
[D.P] SingleTon (0) | 2011.09.07 |
---|---|
[단위전략] Tipelist - 타입 사이즈 Sort 구현 (0) | 2010.11.04 |
[단위전략] Clone()에서 Typelist까지... (0) | 2010.11.04 |