컴파일러 강의를 수강할 때 Scanner, Parser 등을 구현하는 실습 및 과제를 했습니다.
교수님께서는 Visual Studio 2019 버전 기준으로 설명을 진행해주셨고, Mac으로 진행하는 방법은 알려주지 않으셨습니다...😢
Mac에서 꼭 실행시키겠다는 저의 일념으로 찾아낸!!!
Mac M1 환경에서 Flex 사용하는 방법을 공유하고자 합니다.
터미널로 실행하면 편하고 좋으니까.. Flex를 사용해야하는 Mac 유저분들께 도움이 되길 바랍니다.
터미널을 켜서 아래의 명령어로 flex를 설치합니다.
$ brew install flex
아래의 명령어들을 활용하여 우리가 만든 .l
파일로 Scanner를 생성한 후 직접 사용해봅시다.
$ flex scanner.l
flex
명령어는 우리가 작성한 scanner.l 파일로 lex.yy.c 파일을 생성하는 명령어입니
다.
lex.yy.c
파일은 scanner.l에서 작성한 definition part, rules, user subroutines 을 담고 있는 lex 파일 입니다.
🙋♀️ lex.yy.c 파일이 원하는 방향과는 다르게 동작해서 수정하고 싶은데,
혹시 lex.yy.c 파일을 직접적으로 수정해도 되나요??lex.yy.c 파일은 절대 수정하면 안됩니다!
lex 파일에서 수정하고 싶은 부분이 있는 것은 scanner.l 파일을 작성할 때 잘못 작성한 것이며,
lex.yy.c를 수정하고 싶다면 scanner.l 파일을 수정한 후 다시 위의 명령어를 실행시켜 새로운 lex.yy.c 파일을 생성해야 합니다.기존에 존재하는 lex.yy.c 파일을 삭제하지 않아도 그 위에 덮어씌워지니 lex.yy.c 파일은 일일이 삭제하지 않아도 됩니다.
$ gcc lex.yy.c -ll
gcc
명령어는 GNU Compiler Collection의 약자로 C언어 컴파일러를 실행하는 명령어입니다.
-ll
option은 Solaris의 libl lex 라이브러리를 사용한다는 의미입니다!
위에서 생성한 lex.yy.c 파일을 포함하여 모든 c 파일은 그 상태로 실행할 수 없고, 무조건 컴파일러를 이용하여 실행파일을 생성해야 그 실행파일로 실행할 수 있습니다.
위 명령어로 생성되는 a.out
이 바로 실행파일입니다!
🙋♀️ zsh: command not found: gcc 에러가 뜬다면?
위 에러는 gcc가 설치되어 있지 않다는 의미입니다!
해결 방법은 아래의 명령어를 입력하여 gcc를 설치하는 것입니다.1. gcc 설치
xcode-select --install
2. gcc 설치 확인
gcc -v
위 명령어 실행으로 gcc 버전이 뜬다면 성공적으로 설치된 것입니다!
‼️🙋♀️ 만약 위의 예시처럼 사용할 파일이 하나의 lex 파일(.l 파일)만이 아니라,
여러 c파일(.c), 헤더파일(.h)을 함께 사용하는 경우엔 어떻게 해야 할까요?한꺼번에 컴파일하기가 답입니다..!
쉽게 말해서 필요한 파일을 몽땅 때려넣어 gcc 명령어를 먹이면 됩니다.만들고자 하는 Scanner에서 lex.yy.c, glob.h, tn.h, main.c, reporterr.c, symtable.c 총 6개의 파일을 사용해야 하는 경우엔
$ gcc lex.yy.c, glob.h, tn.h, main.c, reporterr.c, symtable.c -ll
를 실행하여 a.out 파일을 생성하면 됩니다! 매우 쉽죠?
(이거 몰라서 집에 박혀있는 윈도우컴 꺼낼까말까 14번 정도 고민했습니다..)
🙋♀️ 실행하니까 warning 문구가 떠요...
신경 쓸 필요 없습니다! 에러가 뜨는게 아니라면 그냥 무시하셔도 됩니다 ~
저희 팀 스캐너 파일로 보여드리자면,,
컴파일했을 때 warning 문구가 주구장창 떠도
아무런 이상 없이 잘 동작한답니다 !
$ ./a.out < testdata.dat
2번에서 생성된 a.out 파일에 넣고 싶은 파일을 입력하면 입력 결과가 나온답니다!
위 코드의 'testdata.dat' 자리에 넣고 싶은 파일을 입력하시면 됩니다!
주의할 점은 경로를 잘 맞춰주셔야 한다는 것입니다!
a.out 파일과 넣고 싶은 데이터 파일(testdata1.dat)이 같은 경로에 있다면
$ ./a.out < testdata1.dat
a.out 파일과 넣고 싶은 데이터 파일(testdata2.dat)이 다른 경로에 있다면
(testdata2.dat가 a.out과 같은 위치에 있는 testdata 폴더에 있다고 가정)$ ./a.out < testdata/testdata2.dat
$ brew install flex # flex 설치
$ flex scanner.l # scanner.l 파일로 lex.yy.c 파일 생성
$ gcc lex.yy.c -ll # lex.yy.c 파일로 a.out 파일(실행파일) 생성
$ ./a.out < testdata.dat # a.out 파일에 넣고 싶은 데이터 삽입
🥰 끝장나는 컴파일러 실습&과제 하시길 바랍니다 !