1 / 72

COMPILER

COMPILER. Chapter 4. 어휘 분석. 김 영 균 ygkim@cespc1.kumoh.ac.kr. Contents. 1. 서론 2. 토큰 인식 3. 어휘 분석기의 구현 4. 렉스 (Lex). 4.1 서론. • 어휘분석 (lexical analysis) 이란 원시 프로그램을 하나의 긴 문자열로 보고 차례대로 문자를 검조 (scanning) 하여 , 문법적으로 의미 있는 최소 단위로 분할해 내는 것을 말함 .

nau
Télécharger la présentation

COMPILER

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. COMPILER Chapter 4. 어휘 분석 김 영 균 ygkim@cespc1.kumoh.ac.kr

  2. Contents 1. 서론 2. 토큰 인식 3. 어휘 분석기의 구현 4. 렉스(Lex)

  3. 4.1 서론 • 어휘분석(lexical analysis)이란 원시 프로그램을 하나의 긴 문자열로 보고 차례대로 문자를 검조(scanning)하여, 문법적으로 의미 있는 최소 단위로 분할해 내는 것을 말함. - 문법적인 단위(syntactic entity)를 토큰(token)이라고 부름. - 컴파일러(compiler)에서 이러한 작업을 하는 부분을 어휘 분석기(lexical analyzer)또는 스캐너(scanner)라고 함. 일련의 토큰 원시 프로그램 어휘 분석기 < 그림 4.1 어휘 분석기 >

  4. 4.1 서론 • 토큰은 유한 오토마타에 의해 인식될 수 있으며, 토큰의 구조는 프로그래밍 언어 설계자나, 컴파일러 설계자에 의해 결정 됨. 프로그래밍 언어는 다음과 같은 토큰의 종류를 갖는다. • 일반 형태 1. 명칭(identifier) ... stk, ptr, sum1, sum2 등 2. 상수(constant) ... 526, 2.3, 0.1234e-10, ‘string’ 등 • 특수 형태 3. 지정어(keyword) ... begin, end, for, goto, if등 4. 연산자 기호(operator symbol) ... +, -, *, /, <, :=등 5. 구분자(delimiter) ... ; , , , ( , [, : 등

  5. 4.1 서론 • 일반 형태 프로그래머가 프로그램을 작성할 때 사용하는 명칭과 상수. • 특수 형태 - 언어를 정의할 때, 언어 설계자가 정의하는 예약어들. - 지정어는 고유한 의미를 갖는 단어로 문법적인 구조를 나타내기 위해 사용. - 연산자 기호는 연산의 의미를 나타내는 기호, - 구분자 기호는 문법 항목을 구분해 주는 기능을 하는 특수 문자.

  6. 4.1 서론 • 토큰 - 각 토큰들은 효율적인 처리를 위해서, 고유의 내부 번호 (internal number)를 갖음. 이것을 토큰 번호(token number)라고 부름. - 일반 형태의 토큰은 프로그래머가 사용한 값을 갖음, 이 값을 토큰 값(token value)라고 함. - 명칭의 토큰 값은 그 자신의 스트링 값(string value)이며, 상수의 토큰 값은 그 자신의 상수값 임. - 어휘 분석기가 파서(parser)에게 넘겨주는 토큰의 정보는 일반적으로 토큰 번호와 토큰 값의 순서쌍으로 구성.

  7. 4.1 서론 • 토큰 번호 - 토큰번호는 명칭이 1, 상수는 2, 그리고 각 특수 형태는 자신을 나타내는 고유의 정수를 갖는다고 하자. 토큰 값은 일반 형태일 때는 자신의 값이 되며, 특수 형태는 토큰 값을 갖지 않지만 편의상 0으로 표시. - 입력 스트림(input stream) if X < Y then X:=10; 은 (29,0) (1,X) (18, 0) (1, Y) (35, 0) (1, X) (9,0) (2,10) (7,0) 으로 변환 됨.

  8. 4.1 서론 - 프로그래머가 사용한 명칭의 토큰은 토큰값과 그 속성을 나타내는 정보를 심벌 테이블(symbol table)에 보관, 의미 분석과 코드 생성 과정에서 중요하게 이용. - 심벌 테이블 운영(symbol table management)은 어휘 분석 과정이나 구문 분석 과정, 의미 분석 과정에서 행하여 짐. - 어휘 분석 과정에서 이루어지는 경우, 어휘 분석기가 원시 프로그램을 분석, 토큰들을 생산하는 과정에서 얻어진 명칭을 가지고, 예약어를 미리 정의한 심벌 테이블을 검색하여, 찾으면 예약어를 인식한 것이므로 그에 해당하는 토큰 번호를 찾아서 구문 분석기에 전달.

  9. 4.1 서론 - 찾지 못하면, 프로그래머가 사용한 새로운 명칭의 토큰을 인식한 것이므로, 심벌 테이블에 명칭을 삽입하고, 구문분석기에게는 명칭에 대한 토큰 값으로 스트링 값이 아닌, 심벌 테이블의 인덱스(index)를 전달 함. - 이렇게 함으로서, 구문 분석기가 심벌 테이블을 검색하는데 드는 시간을 경감. - 구문 분석의 결과에 따른 여러 가지 속성들을 그 인덱스를 이용하여 간단히 추가하면 됨.

  10. 4.1 서론 - 앞의 토큰 표현 예에서, (1,X), (1,Y)는 다음과 같은 경우, 즉 X와 Y에 대한 스트링 값 대신에 그에 해당하는 심벌 테이블의 인덱스를 사용하여, (1,10), (1,20)으로 구문 분석기에 전달 할 수 있음. < Pascal program의 예 > program text(input, output); var X,Y : integer; begin if X < Y then X:=10; end.

  11. ... ... 10 x integer var 1 ...... 20 y integer var 1 ...... 4.1 서론 - 앞 예제 Pascal program의 심벌 테이블의 모양은 토큰 토큰 속성들 ... < 심벌 테이블의 형태 >

  12. 4.1 서론 - 어휘 분석 과정에서 심벌 테이블을 운영하지 않으면, 이와 같은 모든일을 구문 분석기가 해야 함. - 어휘 분석기는 원시 프로그램의 줄번호를 기억, 필요할 때 원시 프로그램을 줄별로 출력할 수 있게 해 줌, 어휘 분석시 원시 프로그램의 불필요한 공백과 주석(comment)을 모두 처리하는 일을 함. - 구문 분석기(syntax analyzer ; parser)와의 관계는 그림 4.3에 도식화. 스캐너는 파서가 토큰이 필요할 때 호출하는 서브루틴임.

  13. 4.1 서론 - 구문 분석기와의 관계 입력 프로그램 Get token 스캐너 파서 Token

  14. 4.2 토큰 인식 • 어휘 분석기 설계 전에, - 정규 표현(regular expression) 프로그래밍 언어의 각 토큰의 구조를 기술할 때 이용. - 상태 전이도(transition diagram)와 유한 오토마타(finite automata)를 정규 표현으로 얻는 것을 잘 이해하고 있어야 함. - 상태 전이도 유한 오토마타를 그림으로 표현하는 흐름도(flow graph), 어떤 모양의 토큰을 인식할 수 있는지를 쉽게 알 수 있는 그림. 상태 전이도의 각 노드는 상태를 표시, 레이블이 문자인 지시선은 한 상태로부터 원시 프로그램속의 그 문자를 읽고 다음 상태로의 이동을 나타냄.

  15. 4.2 토큰 인식 - 이중 원으로 표시된 노드는 한 토큰의 인식을 나타내는 종결 상태를 나타냄. - 각 토큰의 종류를 인식하는 인식기를 구성하기 전에, 문자를 다음과 같이 분류함. letter  a | b | c ... | z | A | B | C ... | Z  l digit  0 | 1 | 2 ... | 9  d special-char  + | - | * | / | . | , | ... 단, 편의상 letter는 l로, digit은 d로 나타냄.

  16. l,d start l S A 4.2.1 명칭의 인식 - 명칭의 구조는 먼저 letter가 오고, 그 다음에 letter나 digit이 반복되는 형태. 영문자 “엘” < 길이에 관계 없이 인식하는 상태 전이도 > - 이것을 정규 문법을 거쳐 정규 표현으로 바꾸면 다음과 같다. S  1A A  lA | dA |  S = 1A A = 1A + dA +  = ( l + d )A +  = ( l + d)*  S = l(l+d)*

  17. 4.2 토큰 인식 • 처음에 상태 S에서 출발, - 원시 프로그램 속에서, letter를 읽고 A상태로 가며, 다음 문자를 읽고, letter이거나 digit이면, 다시 A상태가 됨. 이것을 반복하다 letter 또는 digit이 아닌 문자가 나오면 명칭으로 인식하게 됨. - C언어의 명칭인 경우, letter에 _(under scrore)를 포함시키면 됨.

  18. d A + start d S C B - d 4.2.2 정수의 인식 • 정수는 처음에 +나 -부호가 나올 수 있으며, 그 후에 digit이 반복해서 나오는 형태를 갖음. - 다음은 정수 상수를 인식하는 상태 전이도, 정규 문법, 정규 표현을 나타냄. d < 정수 상수를 인식하는 상태 전이도>

  19. 4.2.2 정수의 인식 • 정수 상수를 인식하는 정규 문법, 정규 표현 S  +A | -B | dC A  dC B  dC C  dC |  C = dC +  = d* = d* A = B = dC = dd* = d+ S = ‘+’d+ + -d+ + dd* = (‘+’ + - + ) d+ - 정규 표현에서 합집합의 의미를 나타내는 +와 terminal +를 구별하기 위해서 terminal +는 ‘+’로 표시.

  20. S A B C D F G E 4.2.3 실수의 인식 • 실수를 인식하는 상태 전이도 d d + d d start d · d e d d • 실수를 인식하는 정규 표현 S  dA A  dA | .B B  dC C  dC | eD |  D  dE | +F | -G E  dE |  F  dE G  dE -

  21. S A B C D F G E 4.2.3 실수의 인식 • 실수를 인식하는 상태 전이도 d d + d d start d · d e d d • 실수를 인식하는 정규 표현 S  dA A  dA | .B B  dC C  dC | eD |  D  dE | +F | -G E  dE |  F  dE G  dE -

  22. 4.2.3 실수의 인식 • 정규 문법으로 부터 정규 표현를 구하면, E = dE +  = d* F = dE = dd* = d+ G = dE = dd* = d+ D = dE + ‘+’F + -G = dd* + ‘+’d+ + -d+ = d+ + ‘+’d+ + -d+ = (  + ‘+’ + - )d+ C = dC + eD +  = dC + e( + ‘+’ + -)d+ +  = d*(e( + ‘+’ + -)d+ + ) A = dA + .B = d*.B = d*.d+(e( + ‘+’ + - )d+ + )

  23. 4.2.3 실수의 인식 S = dA = dd*.d+(e( + ‘+’ + - ) d+ + ) = d+.d+(e( + ‘+’ + - ) d+ + ) = d+.d+ + d+.d+e( + ‘+’ + - )d+  S = d+.d+ + d+.d+e( + ‘+’ + - )d+ 따라서, 실수의 형태는 지수 부분이 없는 구조(fixed-point number)와 지수 부분이 존재하는 구조(float-point number)로 구성 됨.

  24. c ‘ start ‘ A B S ‘ 4.2.4 스트링 상수(String Constant)의 인식 •스트링 상수는 일련의 문자를 ‘(quote)와 ‘사이에 표시하여 표현 ‘를 스트링 상수 안에 넣기 위해서는 연속해서 두개를 사용. - 그림 4.7은 스트링 상수를 인식하는 상태 전이도와 정규 문법, 그리고 정규 표현을 나타내며, 그 패턴(pattern)을 인식하는 프로그램의 일부. < 그림 4.7 스트링 상수를 인식하는 상태 전이도 >

  25. 4.2.4 스트링 상수(String Constant)의 인식 • 앞의 상태 전이도에서 여기서, c는 ‘이외의 문자를 나타냄. 즉, c = char_set - {‘}이다. S  ‘A A  cA | ‘B B  ‘A |  A = cA + ‘B = cA + ‘(‘A + ) = cA + ‘’A + ‘ = ( c + ‘’)A + ‘ = (c + ‘’)*’ S = ‘A = ‘(c + ‘’)*’ - 정규 표현 ‘(c+’’)*’에서 알 수 있듯이 스트링 상수는 ‘으로 시작해서 ‘이외의 문자나 연속된 ‘이 반복해서 나올 수 있고, ‘으로 끝나게 됨.

  26. 4.2.4 스트링 상수(String Constant)의 인식 • 맨 처음 ‘을 본 다음 상태에서 정규 표현 (c+’’)*’을 인식하여 처리하는 C프로그램은 아래와 같다. do { while (getchar() != ‘\’’ ) ; ch=getchar(); } while ( ch == ‘\’’);

  27. a * ) start ( * * D A B C S b 4.2.5 주석(Comment)의 처리 • 모든 프로그래밍 언어는 프로그램 설명을 위해 주석 사용. - 교재에서는 (* 와 *)사이에 주석을 기술한다고 가정. (Pascal 언어 방식 ) - (*와 *)를 인식하는 오토마타와 정규 문법, 그리고 정규 표현을 생각해 보면, a는 * 이외의 문자, b는 *, ) 이외의 문자를 나타냄. 즉, a = char_set - { * } 그리고 b = char_set - { *, ) } 이다. < 주석을 인식하는 오토마타, 정규 문법, 정규 표현 >

  28. 4.2.5 주석(Comment)의 처리 • 주석을 인식하는 상태 전이도의 정규 표현 S  (A A  *B B  aB | *C C  *C | bB | ) D D   C = ‘*’C + bB + ‘)’ ------> X = X +  = * C = ‘*’*(bB + ‘)’) B = aB + ‘*’’*’*(bB + ‘)’) = aB + ‘*’’*’*bB + ‘*’’*’*’)’ = (a + ‘*’’*’*b)B + ‘*’’*’*’)’ ------> X = X +  = * = (a + ‘*’’*’*b)*’*’’*’*’)’ A = ‘*’B =‘*’(a+ ‘*’’*’*b)*’*’’*’*’)’ S = ‘(‘A = ‘(‘’*’(a + ‘*’’*’*b)*’*’’*’*’)’  S = ‘(‘A = ‘(‘’*’(a + ‘*’’*’*b)*’*’’*’*’)’

  29. 4.2.5 주석(Comment)의 처리 • (*를 주석의 시작으로 인식하여 *)를 처리하는 프로그램은 다음과 같다. 즉, 일련의 입력 스트림에서 *)를 인식하는 프로그램. do { while ( ch != ‘*’) ch = getchar(); ch = getchar(); } while ( ch != ‘)’ ); - 컴파일러를 위한 어휘 분석기는 주어진 입력을 선형 시간 (linear time)내에 처리해야 하기 때문에 반드시 결정적 유한 오토마타로 구현 해야 함.

  30. 4.2.5 주석(Comment)의 처리 • 정규표현으로 기술된 토큰을 인식하는 어휘 분석기를 구현 하는 방법. - 정규 표현으로부터 비결정적 유한 오토마타를 구성, - 비결정적 유한 오토마타를 결정적 유한 오토마타로 변환. - 상태수가 최소화된 결정적 유한 오토마타를 얻어 프로그래밍하면 효율적인 어휘 분석기 구현 가능.

  31. 4.3 어휘 분석기의 구현 • 어휘분석기 구현 - 문법 표현(grammar description)으로부터 terminal심벌들의 형태(즉, 토큰의 구조)를 얻음. ( 보통문법 표현으로부터 PGS(Parser Generating System)가 terminal 심벌과그 내부 번호를 지정해 줌. 내부 번호는 파싱테이블과 밀접한 관계를 가짐. ) - 이 토큰(token)들을 인식할 수 있는 프로그램을 작성. - 인식 프로그램을 작성하는 방법은 1) 일반적인 프로그래밍 언어를 사용하여 작성. 2) 어휘 분석기 생성기로부터 얻음.

  32. 4.3 어휘 분석기의 구현 • 어휘분석기를 일반적인 프로그래밍 언어로 작성. 1) 토큰들을 인식하기 위한 유한 오토마타를 상태 전이도로 표시. 2) 상태 전이도로부터 실제의 프로그래밍 언어로 각 상태에 대한 프로그램을 작성. • 토큰 종류에 따라 설명한 이론을 이용. 미니 파스칼에 대한 어휘 분석기를 구성해 보면, 미니 파스칼에 대한 문법은 부록 A에 있음.(pp.499)

  33. 4.3 어휘 분석기의 구현 • 미니 파스칼의 토큰을 이루는 특수 심벌(special symbol)과 단어 심벌(word symbol)은 다음과 같다.  특수 심벌 + - * , ; : := . .. ( ) [ ] = <> < <= > >=  단어 심벌 array begin const div do end if mod of procedure program integer then var while - 위 토큰들을 인식하는 미니 파스칼의 전체 상태 전이도는 그림 4.9와 같다.

  34. ( d l 9 8 2 5 6 3 4 10 4.3 어휘 분석기의 구현 • 미니 파스칼의 상태 전이도( 교재 pp120참조) start b 1 l/d Look up Keyword Table not l/d not found ident exit d not d keyword exit number exit * not* ) * * 7 1 not* not) and not *

  35. < > : 19 14 17 13 20 4.3 어휘 분석기의 구현 > 11 12 = not >, = = 15 16 not = = 18 not =

  36. = ) . 23 A A + * - ; , [ ] 32 30 25 31 28 29 27 26 24 4.3 어휘 분석기의 구현 . 21 22 not .

  37. 4.3 어휘 분석기의 구현 - 어휘 분석기를 C프로그램으로 작성 함수 scanner가 입력 소스에서 한 개의 토큰을 분할해서 복귀하는 루틴. 토큰을 인식할 때, 읽어 들인 문자가 더 이상 그 토큰에 속하지 않는 경우 이 문자는 다음번의 토큰 인식할 때 다시 처리 되어야 함. - 이와 같은 과정을 retract라 부르며, C언어에서는 함수 ungetc()가 그와 같은 기능을 함.

  38. 4.3 어휘 분석기의 구현 - 교재 pp.121~124 참조 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> struct tokentype scanner() { struct tokentype token; int i,j,k,num; char ch, id[ID_LENGTH]; token.number = tnull; do { while (( ch = getchar()) == ‘ ‘); /* skip blanks */ if( isalpha(ch) ) { /* identifier or keyword */ i=0;

  39. 4.3 어휘 분석기의 구현 do { if ( id < ID_LENGTH ) id[i++] = ch; ch = getchar(); } while (isalnum(ch)); id[i] = ‘\0’; ungetc(ch, stdin); /* retract */ /* find the identifier in the keyword table */ i=0; j = NUMKEYWORD -1; do { /* binary search */ k = (i + j) / 2; if ( strcmp(id, keyword[k] ) >= 0 ) i = k + 1; if ( strcmp(id, keyword[k] ) <= 0 ) j = k - 1; } while ( i <= j );

  40. 4.3 어휘 분석기의 구현 if ( (i-1) > j ) /* found, keyword exit */ token.number = tnum[k]; else { /* not found, ident exit */ token.nubmer = tident; strcpy(token.value.id, id); } } /* identifier or keyword */ else if (isdigit(ch)) { /* number */ num = 0; do { num = 10*num + (int)(ch - ‘0’); ch = getchar(); } while ( isdigit(ch) ); ungetc(ch, stdin); /* retract */ token.number = tnumber; token.value.num = num; } /* number */

  41. 4.3 어휘 분석기의 구현 else switch(ch) { /* special characters */ case ‘(‘ : /* state 7 */ ch = getchar(); if ( ch == ‘*’ ) /* comment */ do { while ( ch != ‘*’ ) ch = getchar(); ch = getchar(); } while ( ch != ‘)’ ); else { token.number = tlparen; ungetc(ch, stdin); /* retract */ } break; case ‘<‘ : /* state 11 */ ch = getchar(); if ( ch == ‘>’ ) token.number = tnequal ; else if( ch == ‘=‘ ) token.number = tlesse; else { token.number = tless; ungetc(ch, stdin); /* retract */ }

  42. 4.3 어휘 분석기의 구현 break; case ‘>’ : /* state 15 */ ch = getchar(); if ( ch == ‘=‘ ) token.number = tgreate ; else { token.number = tgreat; ungetc( ch, stdin ); /* retract */ } break; case ‘:’ : /* state 18 */ ch = getchar(); if ( ch == ‘=‘ ) token.number = tassign; else { token.number = tcolon; ungetc(ch, stdin); /* retract */ } break;

  43. 4.3 어휘 분석기의 구현 case ‘.’ : /* state 21 */ ch = getchar(); if ( ch == ‘.‘ ) token.number = tddot; else { token.number = tdot; ungetc(ch, stdin); /* retract */ } break; case ‘=‘ : token.number = tequal; break; case ‘)’ : token.number = trparen; break; case ‘+’ : token.number = tplus; break; case ‘-’ : token.number = tminus; break; case ‘*’ : token.number = ttimes; break; case ‘;’ : token.number = tsemicolon; break; case ‘,’ : token.number = tcomma; break; case ‘[‘ : token.number = tlbracket; break; case ‘]’ : token.number = trbracket; break; case EOF : token.number = teof; break; } /* switch end */

  44. 4.3 어휘 분석기의 구현 } while ( token.number == tnull ); return token; } /* end of scanner */ - 함수 scanner()에서 사용된 외부 변수(external variable)들의 의미 (1) 각 토큰의 토큰 번호를 나타내는 tsymbol의 형은 열거형으로 다음과 같은 내용으로 정의 됨. enum tsymbol { tnull, tident, tnumber, tplus, tminus, ttimes, tcomma, tsemicolon, tcolon, tassign, tdot, tddot, tlparen, trparen, tlbracket, trbracket, tequal, tnequal, tless, tlesse, tgreat, tgreate, teof, arraysym, beginsym, constsym, divsym, dosym, endsym, ifsym, intsym, modsym, ofsym, procsym, progsym, thensym, varsym, whilesym };

  45. 4.3 어휘 분석기의 구현 (2) ID_LENGTH는 유효한 명칭의 길이를 나타내는 상수, NUM_KEYWORD는 단어 심벌의 개수를 나타내며, 미니 파스칼에서는 15개의 단어 심벌이 있다. #define ID_LENGTH 12 #define NUMKEYWORD 15 (3) tokentype은 파서에게 넘겨주는 형태로 구조형으로 정의 됨. struct tokentype { int number; /* token number */ union { char id[ID_LENGTH]; int num; } value; /* token value */ }; 여기서 number는 토큰 번호를 갖는 변수, 토큰 값을 갖는 일반 형태의 명칭과 상수는 각각 id와 num의 변수에 저장됨. 파서가 토큰을 요구할 때 어휘 분석기는 이 형태의 값을 배정하여 이양.

  46. 4.3 어휘 분석기의 구현 (4) keyword는 각 지정어의 스트링 값을 갖는 배열, tnum은 각 지정어에 해당하는 토큰 번호를 갖는 배열이다. keyword와 tnum배열은 다음과 같은 초기값을 갖는다. char *keyword[] = { “array”, “begin”, “const”, “div”, “do”, “end”, “if”, “integer”, “mod”, “of”, “procedure”, “program”, “then”, “var”, “while” }; enum tsymbol tnum[] = { arraysym, beginsym, constsym, divsym, dosym, endsym, ifsym, intsym, modsym, ofsym, procsym, progsym, thensym, varsym, whilesym }; - 함수 scanner()는 parser와 함께, 미니 파스칼 컴파일러를 위한 실질적인 전반부로 사용 됨.

  47. 4.4 렉스(Lex) - 렉스(Lex)는 1975년경, 레스크(Lesk, M. E.)에 의해 발표된 어휘 분석기 생성기 이다. 입력 스트림(input stream)에서 정규 표현으로 기술된 토큰들을 찾아 내는 프로그램을 작성하는 데, 유용한 도구이다. - 렉스의 기능 사용자가 정의한 정규표현과 실행 코드(action)를 입력으로 받아, C언어로 쓰여진 프로그램을 출력. 이 프로그램은 입력 스트림에서 정규 표현에 해당하는 토큰을 찾았을 때, 그에 결합된 실행 코드를 수행함. 렉스 입력 렉스 입력 스트림 어휘 분석기 일련의 토큰들 < 그림 4.10 렉스의 기능 >

  48. 4.4 렉스(Lex) - 렉스(Lex) 사용자는 렉스 입력 형식에 따라, 필요한 토큰의 구조를 기술하고, 그에 따른 행동만 C언어로 작성하면 필요한 프로그램을 얻을 수 있다. • 렉스의 입력 렉스의 입력(lex source)은 다음과 같이 세 부분으로 구성. < 정의 부분 > %% < 규칙 부분 > %% < 사용자 부프로그램 부분 > %%가 각 부분의 구분자이며, 각 부분은 반드시 순서적으로 기술.

  49. 4.4 렉스(Lex) - 렉스(Lex) 사용자는 렉스 입력 형식에 따라, 필요한 토큰의 구조를 기술하고, 그에 따른 행동만 C언어로 작성하면 필요한 프로그램을 얻을 수 있다. • 렉스의 입력 렉스의 입력(lex source)은 다음과 같이 세 부분으로 구성. < 정의 부분 > %% < 규칙 부분 > %% < 사용자 부프로그램 부분 > %%가 각 부분의 구분자이며, 각 부분은 반드시 순서적으로 기술.

  50. 4.4 렉스(Lex) - < 정의 부분 >은 다음과 같은 형태를 갖음. % { /* This part is merely copied onto the generated program */ % } 이름1치환식1 이름2 치환식2 ... 이름n 치환식n %{와 %}사이에는 실행코드를 C언어로 기술할 때, 필요한 자료구조, 변수, 상수를 정의 할 수 있는 부분. 렉스는 %{와 %}사이에 있는 프로그램 부분을 렉스의 출력인 lex.yy.c의 앞 부분에 그대로 복사. - 이름 정의 부분은 특정한 정규 표현을 하나의 이름으로 정의, 그 형태의 정규 표현이 필요할 때마다 쓸 수 있도록 해주는 부분.

More Related