150 likes | 468 Views
4. 어휘 ë¶„ì„ (Lexical analysis). 4-1. ì • ì˜ 4-2. í† í° ì¸ì‹ 4-3. 어휘분ì„ê¸°ì˜ êµ¬í˜„ 4-4. ë ‰ìŠ¤ (Lex). 4-1. ì • ì˜. ì •ì˜ ì›ì‹œí”„ë¡œê·¸ëž¨ì„ í•˜ë‚˜ì˜ ê¸´ 문ìžì—´ë¡œ ë³´ê³ ì°¨ë¡€ëŒ€ë¡œ 문ìžë¥¼ 검사하여 문법ì 으로 ì˜ë¯¸ 있는 ìµœì†Œì˜ ë‹¨ìœ„ë¡œ ë¶„í• í•´ë‚´ëŠ” 것 스ìºë„ˆ (Scanner) ì›ì‹œ í”„ë¡œê·¸ëž¨ì„ í† í°ìœ¼ë¡œ 분리하는 부분. ì¼ë°˜ 형태. 명 ì¹. : l(l+d) *. ìƒ ìˆ˜. : 526, 2.3, ‘string’ 등. 특수 형태. ì§€ì •ì–´.
E N D
4. 어휘 분석(Lexical analysis) 4-1. 정 의 4-2. 토큰 인식 4-3. 어휘분석기의 구현 4-4. 렉스(Lex)
4-1. 정 의 • 정의 • 원시프로그램을 하나의 긴 문자열로 보고 차례대로 문자를 검사하여 문법적으로 의미 있는 최소의 단위로 분할 해내는 것 • 스캐너 (Scanner) • 원시 프로그램을 토큰으로 분리하는 부분
일반 형태 명 칭 : l(l+d)* 상 수 : 526, 2.3, ‘string’등 특수 형태 지정어 : begin, end, for, goto등 연산자기호 : +, -, *, /, <, := 등 구분자 : ;, , , (, [, :등 • 토큰(Token) • 문법적 최소단위 • 형태
Symbol table lexeme • 토큰번호 • 각 토큰들을 효율적인 처리하기 위해서 고유의 내부번호 • 토큰값 • 토큰이 프로그래머가 사용한 값을 가질 때 그 값을 말한다 • 명칭의 토큰값은 그 자신의 스트링 값 • 상수의 토큰값은 그 자신의 상수 값 예제 if X < Y then X :=10; (29,0) (1,X) (18,0) (1,Y) (35,0) (1,X) (9,0) (2,10) (7,0) (1,10) : X (1,20) : Y
4-2. 토큰 인식 • 설계 시 주의사항 • 프로그래밍 언어의 각 토큰의 구조를 기술 할 때 이용되는 방법인 정규표현을 알고 있어야 하며, 이것들을 식별하기 위한 인식기가 필요한데, 인식기를 설계하는 방법인 상태 전이도와 유한 오토마타를 사용 • 상태전이도 • 유한 오토마타를 그림으로 표현한 흐름도로 어떤 모양의 토큰을 인식 할 수 있는지를 쉽게 알 수 있는 그림
명칭의 인식 l, d l S A start S = l(l+d)* 정수의 인식 + A d d d S C start B - d S = ‘+’d+ + -d+ + dd* = (‘+’+ - + )d+
실수의 인식 F d + d d . e d d S A B C D E start G d - S = d+.d+ + d+.d+e(+’+’+ - )d+ 스트링의 인식 c ´ S A B ´ start ´ S = ´(c + ´ ´)*´
4-3. 어휘분석기의 구현 • 미니 파스칼에 대한 어휘분석기 구현 • 특수 심벌 • 단어 심벌
b B 출발 A 27 1 - l/d > 15 16 = Look up keyword Table not found 2 3 l not l/d 17 not = 28 * ident exit d 18 19 : found = 4 d 5 6 not d number exit ; 29 20 not = keyword exit not * * . ( 21 22 . ) 7 8 9 1 * * , 30 not) and not* 23 not . 10 not* [ 31 24 = 11 12 < > 13 ) 25 = ] 32 14 not >,= + 26 A B 미니 파스칼의 상태전이도
렉 스 렉스 입력 어휘 분석기 입력 스트림 일련의 토큰들 4-4. 렉스(Lex) • 정의 • 1975년에 레스크에 의해 발표된 어휘분석기 생성기 • 기능 • 사용자가 정의한 정규 표현과 실행코드를 입력 받아 C언어로 쓰여진 프로그램 출력
렉스의 입력 • <정의부분> %{ 실행코드를 C언어로 기술할 때 필요한 자료구조, 변수 상수 }% 이름 정의 부분 : 특정한 정규표현을 하나의 이름으로 정의하여 그 형태의 정규표현이 필요 할 때만 쓸 수 있도록 해주는 부분 %% <규칙부분> :토큰의 형태를 표현하는 정규표현과 그 토큰이 인식되었을 때 처리할 행위를 기술하기 위한 부분인 실행코드 %% <사용자 부 프로그램 부분> : 렉스의 입력 작성시 사용되는 부 프로그램들을 정의
렉스의 정규표현 • 렉스에서 사용되는 연산자 “\ [ ] ^ - ? . * + | ( ) $ / { } % < > • “ : “사이에 있는 모든 문자는 텍스트문자로 취급 예) ( a“*”b = a * b ) ( a * b = a*b ) • \ : 한 개의 문자를 에스케이프 하기 위하여 사용 예) XYZ“++”, “XYZ++”, XYZ\+\+ • [] : 문자들의 클래스를 정의하는데 사용 예) [abc] : a, b, c중에서 한문자 • - : 범위를 나타내는 연산자 문자 예) [a-z] : a부터 z사이의 문자 중에 한문자 • ^ : 여집합을 표현 예) [^*] : *를 제외한 모든 문자 • \ : C언어의 에스케이프 문자열로 간주 예) [ \t\n] : 공백, 탭, 개행 문자중의 하나
* : 0번 이상 반복을 의미 예) [a-zA-Z][a-zA-Z0-9]* : 변수 인식을 위한 정규표현 • + : 한번 이상 반복 할 수 있음을 의미 예) [a-z]+ : 모든 소문자 문자열을 인식하는 정규표현 • ? : 선택을 의미 예) ab?c : abc 또는 ac • | : 택일을 위한 연산자 예) (ab | cd) : ab 또는 cd (ab | cd+)?(ef)* : abefef, efefef, cdef, cddd • ^ : 라인의 시작을 인식 예) ^abc : 라인의 시작에서 abc가 있을 때만 토큰으로 처리 • $ : 라인의 끝에서만 인식 • / : 접미 문맥을 명시할 때 사용 예) ab/cd : ab다음에 cd가 이어서 있을 때만 ab를 토큰으로 처리 • . : .는 newline문자를 제외한 모든 문자들 예) “- -”.* : - -부터 한 라인의 끝까지와 부합 • {} : 정의된 이름을 치환식으로 확장 할 때 사용
렉스의 실행코드 • 총괄변수와 함수 • yyleng : 매칭된 문자열의 길이를 저장하고 있는 변수 • yymore() : 현재 매칭된 문자열의 끝에 다음에 인식될 문자열이 덧붙여 지도록 하는 함수 • yyless(n) : n개의 문자만을 yytext에 남겨두고 나머지는 다시 처리 하기 위하여 입력 스트림으로 되돌려 보내는 함수 • input() : 입력 스트림으로부터 다음 문자를 읽는 함수 • output(c) : 출력 스트림으로부터 문자 c를 내보내는 함수 • unput(c) : 함수 input()에 의해 다시 읽혀지도록 문자 c를 입력 스트림으로 되돌려 보내는 기능을 하는 함수 • yywrap() : 렉스가 입력의 끝을 만났을 때 호출하는 함수 정상적인 경우에 복귀값은 1이다.
렉스 입력 lex.yy.c 스캐너 lex cc lex library • 스캐너의 생성 및 동작 • 스캐너의 생성과정 • 렉스의 선택규칙 • 가장 길게 인식된 토큰을 우선으로 한다. • 인식될 수 있는 토큰의 길이가 같은 경우 먼저 나타난 규칙의 정규 표현으로 인식한다.