Lex와 Yacc을 이용한 Calculator 구현 부산대학교 정보∙컴퓨터 공학 전공 2009-2학기 컴파일러 2009.09.22
intermediate code generator The rest of process intermediate code generator source program target program semantic analyzer syntax analyzer lexical analyzer code optimizer code generator error handler symbol-table manager ‘Lex’를 이용하여 생성 ‘Yacc’ 을
Lex를 이용한 lexical analyzer 생성(1/3)
Lex를 이용한 lexical analyzer 생성 (2/3) Lex의 input specification 정의, 규칙, 사용자 부프로그램의 세 부분으로 이루어 짐. 각 부분을 구별하는 구분자로 %% 를 사용. 정의절 lexer 안에서 lex가 사용할 옵션을 처리하는 부분. 일반적으로 lexer가 작동하는 실행 환경을 설정. lexer 안으로 그대로 복사되는 C 코드는“%{”과 “%}”로 둘러쌈. 정의는 규칙 부분에서 사용됨. 규칙절 lexer의 기능을 지정하는 패턴과 동작을 담고 있는 부분. reguiar expression(패턴)과 그것과 매칭되었을 때 실행되는 동작 코드로 이루어 짐.
Lex를 이용한 lexical analyzer 생성 (3/3) 사용자 부프로그램 동작 코드를 작성할 때 사용되는 부프로그램들을 정의하기 위한 곳으로 lex의 출력인 lex.yy.c에 그대로 복사. 반드시 입력의 끝을 만났을 때 처리를 해야하는 yywrap() 함수를 작성해야 함.
Yacc을 이용한 Syntax Analyzer 생성(1/2)
Yacc을 이용한 Syntax Analyzer 생성(2/2) 사용자가 정의한 문법을 받아들여 그 문법에 맞는 “문장(sentences)”을 인식하는 syntax analyzer(parser) 생성 Yacc의 input specification lex와 마찬가지로 정의, 규칙, 사용자 부프로그램으로 이루어 짐. 정의 문법에서 사용하는 토큰에 대한 선언, 생성된 parser 내부의 스택에서 사용되는 다양한 값의 타입들을 담고 있음. 규칙 parser를 위한 문법을 담고 있음 사용자 부프로그램 Yacc이 생성하는 parser에 그대로 복사되는 C 코드를 담고 있음.
lex와 yacc의 결합
Lex와 Yacc을 이용한 Calculator 구현 Yacc이 생성할 parser에 토근을 제공하기 위한 lex %{ #include “calc.tab.h” extern int yylval; %} %% [0-9]+ { yylval = atoi(yytext); return NUMBER;} [ \t]; \n return 0; \. return yytext[0]; 정의 패턴 동작 규칙
Lex와 Yacc을 이용한 Calculator 구현 Calculator 문법을 가진 Yacc input specification %token NAME NUMBER %left '-' '+' %left '*' '/' %nonassoc UMINUS %% statement: NAME '=' expression | expression { printf("= %d\n", $1); } ; expression: expression '+' expression { $$ = $1 + $3; } | expression '-' expression { $$ = $1 - $3; } | expression '*' expression { $$ = $1 * $3; } | expression '/' expression {if($3 == 0) yyerror("divide by zero"); else $$ = $1 / $3; } | '-' expression %prec UMINUS { $$ = -$2; } | '(' expression ')' { $$ = $2; } | NUMBER { $$ = $1; } 정의 규칙
Lex/Yacc 사용법 – Visual Studio.NET 2005 Parser Generator 설치 pargen.zip 의 압축을 푼다. [DISK1]의 설치 파일을 실행한다. 라이브러리 libcd.lib 을 C:\ParGen\LIB\MSDEV 폴더에 저장한다.
Lex/Yacc 사용법 – Visual Studio.NET 2005 응용 프로그램 종류: 콘솔 응용 프로그램 추가옵션: 빈프로젝트
Lex/Yacc 사용법 – Visual Studio.NET 2005 디렉토리 (포함, 라이브러리, 소스) 환경설정 [도구] > [옵션] 디렉터리 표시: [포함 파일] [c:\ParGen\INCLUDE] 추가 디렉터리 표시: [라이브러리] [c:\ParGen\LIB\MSDEV] 추가 디렉터리 표시: [소스파일] [c:\ParGen\SOURCE] 추가
Lex/Yacc 사용법 – Visual Studio.NET 2005 프로젝트 환경 설정 [구성속성] > [C/C++] > [전처리기] : YYDEBUG 추가 [구성속성] > [링커] > [입력] : 추가종속성에 yld.lib 추가
Lex/Yacc 사용법 – Visual Studio.NET 2005 Parser generator로 컴파일 [Project] > [Compile File] 로 calc.y 컴파일. calc.c와 calc.h가 생성됨. calc.c -> calc.tab.c, calc.h -> calc.tab.h로 파일명 변경 lex 컴파일 결과와의 중복을 피하기 위해 변경 calc.tab.h는 lex에서 이용 [Project] > [Compile File] 로 calc.l 컴파일.
Lex/Yacc 사용법 – Visual Studio.NET 2005 calc.c, calc.h, calc.tab.c, calc.tab.h를 프로젝트에 추가 빌드 후 실행
기타 Visual Studio 2003 환경에서도 동일. Lex와 Yacc의 종류는 매우 많음. 기타 문의 사항이 있을 경우 GNU Bison & Flex : win32용도 있음, 소스 코드 개방. Abraxas Yacc & Lex : MS-DOS용 Pclex와 Pcyacc 포함. 기타 문의 사항이 있을 경우 인공지능 연구실 김민호 전화: 510-2875 E-mail: karma@pusan.ac.kr Lex와 Yacc에 대한 자료는 웹에 많이 있으므로 여러가지 자료를 참고한다면 어렵지 않을 것임