검색결과 리스트
Total에 해당되는 글 162건
글
스캐너 만들기 #2
지난 시간에 스캐너를 만들기 위해서 문법 정의를 하였습니다.
그런데 빼먹은 부분이 있습니다.
바로 문자열을 표현할때 쓰는 따옴표(double-quotes), 문자를 표현할때 쓰는 홑따옴표(single-quotes) 부분입니다.
그리고 여러줄 주석을 사용할때 쓰는 '/*', '*/' 도 정의하지 않았네요.
이 부분은 지난시간에 정의한 것과는 조금 레벨이 다릅니다.
형식이 있는 단어 스캔
C언어에서 문자열의 경우 따옴표("") 로 감싸게 됩니다.
즉, '따옴표로 시작해서 따옴표로 끝남' 이라는 형석이 있는것이죠.
이걸 단순히 스캔한다면,
TOKEN : {
<STRING : "\"" (~[])* "\"">
}
이렇게 될 것입니다.
소스코드에 아래와 같은 부분이 있다고 가정해 봅시다.
int main() {
string name = "hong gil-dong";
string address = "seoul";
return 0;
}
이런 경우에, 위 정규표현식에 매칭되는 부분은 어디일가요?
"hong gil-dong" , "seoul" 이렇게 2개가 아닙니다.
"hong gil-dong";
string address ="seoul"
여기까지 통째로 매핑되어 버립니다.
왜냐면 정규표현식에서는 "최대 길이 일치의 원칙(longest match principle)" 이라는게 존재하기 때문입니다.
/* */ 로 표현하는 주석도 한번 살펴 볼까요?
int main() {
/*
string name = "hong gil-dong";
string address = "seoul";
*/
int age = 10;
/*
int count = 20;
*/
return 0;
}
이 경우에 아래와 같이 토큰 정의를 했다고 가정해 봅시다.
SKIP: { <"/*" (~[])* "*/"> }
과연 위 정규표현식에 의해서 처리되는 문자열은 어디까지 일까요?
네, 앞서 말씀드린 "최대 길이 일치의 원칙" 에 의해서 아래처럼 되어버립니다.
/*
string name = "hong gil-dong";
string address = "seoul";
*/
int age = 10;
/*
int count = 20;
*/
이런 문제 해결을 위해서 JavaCC 에서는 '상태(state)' 라는 것을 제공해 줍니다.
MORE : { <"/*"> : IN_BLOCK_COMMENT }
<IN_BLOCK_COMMENT> MORE: { <~[]> }
<IN_BLOCK_COMMENT> SKIP: { <"*/"> : DEFAULT }
MORE : { <"\""> : IN_DB_QUOTES }
<IN_DB_QUOTES> MORE : { <(~["\""])+>
| <"\\" ~[]> }
<IN_DB_QUOTES> TOKEN : { <STRING : "\""> : DEFAULT }
먼저 앞에 있는 <IN_BLOCK_COMMENT> 는
"현재 스캔 상태가 'IN_BLOCK_COMMENT' 일 경우에만, 다음 어휘해석 규칙을 사용하겠다" 라는 의미입니다.
그리고 MORE 는 '현재 어떤 문자열을 찾기 위해서 스캔중이다' 라는걸 의미합니다.
즉, MORE 로 문자열(소스코드)의 파싱이 종료된다면, 오류가 발생하게 되죠.
소스코드가 아래처럼 되면 오류가 발생되어야 하기 때문에 MORE 를 사용하는 것입니다.
int main() {
/*
string name = "hong gil-dong";
string address = "seoul";
return 0;
}
만약 MORE 가 없다면, 정상적으로 스캔되고 끝나버리겠지요.
JavaCC 의 표현방식을 보다보면 조금 헷갈리실 것 같아서 정리하고 넘어가겠습니다.
가장 앞에 붙을 수 있는 명령들은 TOEKN, SKIP, MORE, SPECIAL_TOKEN 등이 있습니다.
그리고 이런 명령들 뒤에는 세미콜론(:) 이 붙게 됩니다.
그 뒤에 모든 내용을 대괄호({}) 로 감싸게 되죠.
이 안에는 스캔할 문법이 들어갑니다.
<토큰명: 정규표현식> : 변경될 상태
이런 형태로 들어갑니다.
그런데 여기서 '토큰명', '변경될 상태'는 생략이 가능합니다.
이번에 마지막으로 문자를 스캔할 규칙을 작성해 보겠습니다.
MORE : { <"'"> : IN_SNG_QUOTE }
<IN_SNG_QUOTE> MORE : {
<~["\'", "\\", "\n", "\r"]> : QUOTE_TERM
| <"\\" ~[]> : QUOTE_TERM
}
<QUOTE_TERM> TOKEN: { <CHARACTER: "'"> : DEFAULT }
조금 복잡하긴 합니다만, 차근차근 하나씩 따라가시면 크게 어렵진 않으실거라 믿습니다.
이렇게 어휘분석(lexical analyzing)이 끝이 났습니다.
다음에는 구문분석(syntax analyzing)을 해 보도록 하겠습니다.
'개발관련 > 컴파일러' 카테고리의 다른 글
컴파일러 만들기 6부 (17) | 2014.05.31 |
---|---|
컴파일러 만들기 4부 (0) | 2012.07.12 |
컴파일러 만들기 3부 (1) | 2012.07.12 |
컴파일러 만들기 2부 (8) | 2012.07.11 |
컴파일러 만들기 1부 (4) | 2012.07.10 |
RECENT COMMENT