본문 바로가기
프로그래밍 언어

[컴파일러] - 어휘 분석 (Lexical analysis) III

by CHML 2016. 1. 25.
1. 개요

이전 글에서 서술한 어휘 분석의 토큰, 정규식, 정규문법 등의 개념을 이용하여 실제로 실행이 가능한 어휘 분석기를 구현하는 과정을 설명한다. C나 Java와 같은 프로그래밍 언어를 이용하여 직접 어휘 분석기를 구현한다면 파일입출력, 문자열 처리, 정규식과 정규문법의 구현 등 실질적으로는 컴파일러와 관련이 없는 프로그래밍 작업이 어휘 분석기 구현의 대부분을 이루게 될 것이다. 그래서 이 글에서는 "Flex"라는 오픈소스 툴을 이용하여 간단하게 어휘 분석기를 구현하는 방법을 설명한다. Flex는 어휘 분석기 툴로 가장 유명한 Lex의 최신 버전이다.


2. Flex 설치

Flex는 GNU General Public License로 공개된 소프트웨어로써, 별도의 라이센스 구입 없이 이용할 수 있다. Flex의 Windows 버전은 이 페이지에서 다운 받을 수 있다.

다운로드 페이지에서 Complete package, except sources를 다운받아서 실행하면 자동으로 설치가 완료된다. 그 다음, flex.exe가 설치된 경로를 Windows 환경변수에 추가하면 Flex 설치가 완료된다. Flex의 설치에 대한 더욱 자세한 설명은 이 글에 서술되어 있다.


3. 예제

이 부분에서는 Flex를 이용하여 간단한 어휘 분석기를 생성한다. 아래의 어휘 분석기는 C언어의 주석과 int, float 타입에 string 타입을 추가한 어휘 분석기이며 어휘 분석기가 인식할 수 있는 연산자는 +, -, *, %가 있다. Flex는 확장자가 .l인 파일을 입력 파일로 받는다.


3-1) 전체 파일

아래의 [코드 1]은 Flex를 이용하여 어휘 분석기를 생성하기 위한 코드이다. 코드에서 [0-9]+와 같은 정규식 형태의 정의가 있는데, 이는 Unix 유틸리티에서 프로그램 구현상 정규식을 확장한 형태이다. [0-9]+라는 확장 정규식은 정규식 (0 | 1 | 2 | ... | 9)+와 같다.


[코드 1] Flex를 이용한 어휘 분석기 생성


3-2) 선언부

아래의 [코드 2]는 [코드 1]의 선언부이다. Flex는 C언어를 기반으로 동작하기 때문에 C언어의 라이브러리를 사용할 수 있다. 일반적으로 어휘 분석기는 어휘 분석 다음 단계인 구문 분석과 의미 분석에서 소스 코드에 작성된 문자열을 실제 값으로 사용할 수 있도록 어휘구문의 값을 형변환하여 전달한다. 예를 들어, 소스 코드에서 ""로 둘러싸여 있지 않은 어휘항목 100 있다면, 어휘 분석기는 100 이라는 문자열을 정수형 타입 100으로 구문 분석기와 의미 분석기에 전달한다. 소스 코드에 작성된 문자열을 정수나 실수값으로 변환하기 위해 문자열을 처리하기 위한 코드가 필요한데, 이를 위해 C언어의 string 라이브러리를 사용한다. 선언부에서는 string 라이브러리를 사용하기 위해 string.h를 include한다. stdlib.h는 지금 예제에서는 사용되지 않지만, 비정상적인 종료나 다른 기능을 이용하기 위해 include 한다. 마지막으로, y.tab.h는 어휘 분석 다음 과정에서 생성되는 파일이므로 아직까지는 그 의미를 이해할 필요가 없다.

헤더 파일을 include 하는 코드 밑에는 %option yylineno라는 옵션 설정이 있다. 이 코드는 구문 분석을 수행하는 중에 소스 코드에 오류가 발견되면, 해당 오류가 소스 코드의 몇 번째 줄에서 발생했는지 출력하기 위해 yylineno라는 변수에 현재 소스 코드의 라인을 저장하라는 선언이다. 현재 상용화된 컴파일러에서 syntax 오류가 발생하면 소스 코드의 몇 번째 라인에서 오류가 발생했는지 프로그래머에게 알려주는데, yylineno는 이와 같은 기능을 구현하기 위한 것이다.


[코드 2] 예제 어휘 분석기의 선언부


3-3) 정규문법 정의

[코드 3]은 정규식을 이용하여 정규문법을 정의한 코드이다.


[코드 3] 정규식을 이용한 정규문법 정의