Archive

Lex 기초 본문

기타

Lex 기초

mariabeetle 2017. 10. 7. 20:11

1. Lex사용하기

- Window환경, C언어를 사용해 lexical analyzer(어휘분석기)를 구현하자.

- Lex 프로그램 결과로 만들어내는 파일의 이름은 'lex.yy.c'가 된다.

- 명령어

> flex lexer.l

> gcc lex.yy.c -lfl

> ./a.out sample1.cl

- Lex파일 구성요소

# 첫 번째는 선언(declaration)이나 정의(definition)가 포함된다.

# 두 번째는 각 프로그램이 수행하는 일에 대한 규칙(translation rule)을 정의한다.

# 세 번째는 보조 프로시저(auxilary procedure) 또는 지원 프로그램(supporting routines)를 담는다.

# 꼭 필요한 부분은 두 번째 부분이고, 첫 번째와 세 번째는 생략이 가능하다.

# 각 부분을 구분할때 '%%' 기호를 사용한다.


2. 예제들을 통한 Lex(Flex) 설명

1) 파일의 줄 번호 붙이기 - ver1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
    첫 번째 부분.
    %{ %}로 둘러싸인 부분은 별다른 처리 없이 그대로 'lex.yy.c'에 포함된다.
    lineno 변수를 글로벌 변수로 활용이 가능하다.
*/
%{
    int lineno = 1;
%}
 
// 구분자 %%를 넣었다.
%%
 
/*
    여기서 두 번째 부분이다.
    예제에서 2개의 패턴이 정의되어 있다.
*/
// ECHO는 Lex(Flex)에서 정의된 매크로(macro). 지금 인식된 토큰을 출력한다.
// 여기서 ECHO는 '\n'이 되고, 줄바꿈을 호출하게 된다.
\n         { lineno++; ECHO; }
 
/*
    '^'는 한 줄에서 제일 앞을 의미.
    '.'는 Lex(Flex)에서 줄바꿈 문자를 제외한 임의의 문자를 의미
    '*'는 정규표현식과 같은 의미로 * 앞의 패턴이 0번, 임의의 횟수의 반복을 의미
    '$'는 한 줄의 제일 마지막을 의미.
    'yytext'는 Lex(Flex)에서 토큰을 저장하는 버퍼( 문자 배열. )
    (패턴에 부합한 문자 배열을 출력, 'ECHO'와 'print("%s", yytext)'는 같은 결과 )
*/
^.*$    printf("%d\t%s", lineno, yytext);
cs


2) 글자 수, 단어 수, 파일 줄 수 카운트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
%{
    // 글자 수, 단어 수, 줄 수를 세기 위한 변수
    //'lex.yy.c'에 전역 변수로 포함
    int nchar, nword, nline;
%}
 
%%
 
\n            ++nchar, ++nline;
// '['와 ']'는 문자 클래스(character class)를 나타낸다.
// ' \t\n'는 공백(" ")이나 탭, 줄바꿈이 부합한다.
// '^'는 대괄호 안에서 사용되면 '후속 문자들을 제외한 다른 문자들'이라는 의미를 가진다.
// '[^ \t\n]는 공백, 탭, 줄바꿈 문자를 제외한 다른 임의의 문자들이 부합힌다.
// '+'는 그 앞의 패턴에 부합하는 스트링이 한 번 이상 임의 횟수로 반복됨을 의미한다.
[^ \t\n]+    ++nword, nchar += yyleng;
.            ++nchar;
 
%%
 
int main(void){
    yylex();
    print("%d\t%d\t%d\n", nchar, nword, nline);
    return 0;
}
cs


'기타' 카테고리의 다른 글

격파르타 SQLD 챌린지 실제 합격 후기  (0) 2024.06.02
공개데이터 정리  (0) 2022.08.07
소프트웨어 개발 모델  (0) 2017.10.12
Comments