본문 바로가기

진리는어디에

Lex & Yacc 컴파일


NOTE - 유입 키워드를 보고 컴파일러를 만들기 위해 이 페이지를 들리시는 분들이 많다는 것을 알게 되었습니다. 이 페이지는 Lex & Yacc를 컴파일 하는 방법에 대해 다루고 있습니다. Lex & Yacc를 이용해 컴파일러를 만들고 싶으신 분들은 Lex & Yacc Tutorial로 가셔야 합니다.


학교에서 배울 때는 분명히 Lex & Yacc로 배웠고, 책 제목도 그렇지만 실제 사용하는 바이너리 이름은 flex와 bison입니다. 이번 포스팅에서는 lex & yacc(flex & bison)을 컴파일 하는 방법에 대해 알아 보도록 하겠습니다.

lex & yacc 를 이용해 컴파일러를 만드는 방법은 [진리는어디에] - Lex & Yacc Tutorial을 보시면 됩니다.

설명을 위해 lex 파일을 lexer.l, yacc 파일을 parser.y 라고 가정 합니다.

아래 각 운영 체제 별 가이드 된 내용들을 커맨드 창에 입력하여 컴파일 하면 lexer.h, lexer.cpp와 parser.h, parser.cpp 가 만들어 집니다. .h와 .cpp를 따로 분리 해서 만들어 내도록 컴파일 하는 이유가 있었는데...너무 오래 되서 이유를 까먹었습니다. 아마도 저렇게 해야 프로젝트에 포함시키기 편했던가 그랬을 겁니다.

리눅스(gcc)

$ flex --nounistd --header-file=lexer.h -o lexer.cpp lexer.l
$ bison --defines=parser.h -o parser.cpp parser.y

리눅스는 기본적으로 flex와 bison이 설치 되어 있기 때문에 별도의 과정 없이 바로 컴파일이 가능 합니다.
아닙니다!! 제가 거짓말 했습니다!! 기본적으로 설치가 안되어 있습니다!!!

NOTE - 리눅스의 종류는 다양하기 때문에 운영체제 마다 각자의 고유한 패키지 인스톨 방법을 제공합니다. 예를 들어 Ubuntu 계열에는 apt install bison 과 같은 커맨드로 설치 가능합니다.

윈도우(Visual Studio)

> win_flex --nounistd --header-file=lexer.h -o lexer.cpp lexer.l
> win_bison --defines=parser.h -o parser.cpp parser.y

NOTE - 윈도우에서는 기본적으로 lex & yacc 를 제공하지 않기 때문에 별도의 설치가 필요 합니다. [여기] 에서 다운 받으셔도 되고, 아래의 첨부파일을 이용하셔도 됩니다.
다운로드 후 압축을 푸시면 여러 파일과 디렉토리가 있는데 실제 컴파일에 필요한 것은 win_bison.exe, win_flex.exe, data 디렉토리입니다. 불필요하다면 나머지는 삭제해도 됩니다. 소스포지에 가끔 프로젝트가 없어지는 경우가 있어서 직접 파일을 첨부 했습니다.

win_flex_bison3-latest.zip
0.99MB

NOTE - Visual Studio에서 '--nounistd' 옵션을 지정하지 않고 컴파일 하는 경우 "fatal error C1083: Cannot open include file: 'unistd.h': No such file or directory"가 발생합니다. unistd.h 는 Posix 계열 운영체제에서만 지원 하기 때문에 윈도우 환경서 unistd.h를 사용하고 싶다면 다음 링크를 참조 합니다. Visual Studio - 리눅스 용 프로젝트의 인텔리센스를 위한 헤더 파일 처리 방법

부록 1. Visual Studio Custom Compiler 등록

커스텀 컴파일러를 등록해주면 프로젝트 빌드 시 Visual Studio가 자동으로 lex & yacc 파일을 컴파일 해줍니다.

lexer.l 파일을 선택하고 우클릭, "속성 > 사용자 빌드 도구 > 일반"을 선택하여 아래와 같이 입력해줍니다.

  • 명령줄 : win_flex --nounistd --header-file=%(Filename).h -o %(Filename).cpp %(Filename).l
  • 설명 : win_flex --nounistd --header-file=%(Filename).h -o %(Filename).cpp %(Filename).l
  • 출력 : %(Filename).h;%(Filename).cpp

parser.y 파일 역시 동일한 과정을 진행 해줍니다. 다만 입력 값은 달라야 합니다.

  • 명령줄 : win_bison --defines=%(Filename).h -o %(Filename).cpp %(Filename).y
  • 설명 : win_bison --defines=%(Filename).h -o %(Filename).cpp %(Filename).y
  • 출력 : %(Filename).h;%(Filename).cpp

부록 2. 참조

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!