Lex
2023. 9. 28. 06:04ㆍ전공/컴파일러
Lex란?
- 어휘 분석기(Scanner)를 생성하는 프로그램
- 문자 입력 스트림의 어휘적 처리를 위해 디자인된 프로그램 생성기
- 입력 : 정규 표현, 일부 코드
- 출력 : 프로그램
- source(정규표현, 일부 코드 조각) → lex → yylex(프로그램을 만드는 분석기)
- 입력 → yylex → 출력
- 어휘 분석 단계를 수행하기 위해 파서 생성기와 함께 사용됨
- lex : 정규 표현만 인식
- Yacc : context free grammar를 인식하는 parser 생성
입력 토큰을 인식하기 위한 저수준의 분석기가 필요
- 어휘 수준에서 변환, 분석, 통계정보 수집을 위해 단독으로 사용됨
Lex with Yacc
통계정보를 위한 Lex
Lex의 일반적인 형식
{definitions}
%%
{rules}
%%
{user subroutines}
- %%로 3 부분을 나눔
- definition과 user subroutines는 생략 가능
- 첫 번째 %%는 rule의 시작을 표현하기 위해 필수적으로 있어야 함
Rule
- 사용자의 제어 결정을 표현
- 테이블 형태
- 왼쪽은 정규 표현
- 오른쪽은 정규 표현이 인식되었을 때 실행할 행동, 프로그램 조각
- 정규 표현의 끝은 첫 번째 빈칸 또는 tab
- 행동
- 기본적으로 한 줄의 C 표현
- 여러 줄일 경우 { }로 감싼다.
정규 표현
- 매치돼야 할 문자열의 집합을 기술
- Text 문자+ 연산자 문자(반복, 선택, 다른 특징)
- 알파벳과 숫자는 항상 text문자
연산자 문자
- , [, ], ^, -, ?, ., *, +, |, (, ), &, /, {, }, %, <, >
- text로 표현할 때는 “ ” 또는 \를 붙여줌
- “+” or \+
- [] : 문자 클래스
- [abc] : a 또는 b 또는 c를 매칭
- - : 범위
- [a-z] : 소문자
- [a-z0-9] : 소문자와 숫자
- ^ : not
- [^abc] : a, b, c를 제외한 나머지 문자 매칭
- \ : ASCII
- [\40-\176]
- ? : 선택적
- [ab?c] : ac or abc
- 반복 표현
- * : 0번 이상 반복되는 문자
- + : 1번 이상 반복되는 문자
- 변수 : [A-Za-z_][A-Za-z0-9]*
- | : 교대
- ab|cd : ab or cd
- ( ) : 그룹
- (ab|cd)
- ^ : 시작 문자
- $ : 끝 문자
- / : 따라오는 context
- Ab/cd : cd가 따라오는 Ab
- { } : 반복 또는 정의 확장
- {digit} : 미리 정의된 digit 확인
- a{1,5} : a가 1~5번 나타나는 문자열
Lex 행동
- 기본
- 입력을 출력으로 복사
- yytext : 어떤 정규 표현에서 매칭되는 실제 text를 알고 싶을 때 사용
- yyleng : 매칭된 문자의 수
- yytext[yyleng-1] : 매칭된 문자 중 마지막 문자
- yymore() : 다음 입력까지 인식돼야 할 때 사용
- yyless(n) : 현재 모든 문자열이 성공적으로 매칭될 필요 없을 때 사용
모호한 Source Rule
- 현재 입력에 매칭될 수 있는 표현이 1개 이상일 때
- 가장 길게 매칭되는 것을 선호
- 문자열 길이가 같을 경우 첫 번째로 주어진 rule을 선호
- ‘ ‘ 안의 문자 인식
- ex) ‘first quoted string here. ‘second’ here
- ‘.*’ 을 사용하면 → ‘first quoted string here. ‘second’ here
가장 긴 문자열을 인식하기 때문 - ‘[^.\n’]*’ → ‘ first’, ‘second’로 인식
Definition
- 매크로 정의
- 주언어, 시작 조건 등 선택
- 헤더 파일, 변수, 코드 임포트
- 생성된 소스코드에 그대로 복사됨
- 생성된 소스코드에 그대로 복사됨
User subroutines
- 생성된 소스코드에 그대로 복사
HW
reserved if|then|else|end|repeat|until|read|write
identifier [a-zA-Z][a-zA-Z0-9]*
%%
[ \\t\\n]+ ;
{reserved} ;
^{identifier} printf("%s\\n",yytext);
. ;
nat [0-9]+
signedNat ("+"|"-")?{nat}
number {signedNat}("."{nat})?(E{signedNat})?
%%
[ \\t\\n]+ ;
^{number}$ printf("%s\\n", yytext);
. ;
%{
int cnt = 0;
%}
%%
[ \\t\\n] ;
.*a$ cnt++;
. ;
%%
int main(){
yylex();
printf("Number of sentences that ends with a: %d\\n", cnt);
return 0;
}
%{
int cnt = 0;
%}
%%
[ \\t\\n]+ ;
. cnt++;
%%
int main(){
yylex();
printf("Total characters: %d\\n", cnt);
return 0;
}
'전공 > 컴파일러' 카테고리의 다른 글
Context Free Grammar (0) | 2023.09.28 |
---|---|
Lexical analysis (0) | 2023.09.28 |
Finite Automata (0) | 2023.09.28 |
Regular expression (0) | 2023.09.28 |
Formal Language, Grammar and Automata (0) | 2023.09.28 |