C언어 > 컴파일러 만들기 5부

TODAY164 TOTAL2,227,494
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | C언어 | C언어 | 컴파일러 만들기 5부

페이지 정보

작성자 키트 작성일2017-09-12 14:04 조회1,386회 댓글0건

본문

 

 

스캐너 만들기 #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)을 해 보도록 하겠습니다.



출처: http://crystalcube.co.kr/111 [유리상자 속 이야기] 

댓글 0

조회수 1,386

등록된 댓글이 없습니다.

C언어HOME > C언어 > C언어 목록

게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기