어휘 분석
어휘 분석 (Lexical Analysis)
어휘 분석(Lexical Analysis)은 컴파일러의 첫 번째 단계로, 소스 코드 문자열을 의미 있는 최소 단위인 토큰(Token)의 시퀀스로 변환하는 과정입니다. 이 단계를 수행하는 프로그램은 일반적으로 렉서(Lexer) 또는 스캐너(Scanner)라고 불립니다. 어휘 분석은 프로그래밍 언어의 구문적 구조를 이해하기 위한 기초를 마련하며, 이후의 구문 분석(Syntax Analysis) 및 의미 분석(Semantic Analysis) 단계에 필수적인 입력 데이터를 제공합니다.
개요 및 목적
컴파일러는 고수준 프로그래밍 언어로 작성된 소스 코드를 기계어 또는 중간 코드로 변환합니다. 이 과정에서 소스 코드는 단순한 문자의 나열이 아니라, 언어가 정의한 규칙에 따라 구조화된 의미를 가집니다. 어휘 분석의 주요 목적은 다음과 같습니다.
- 불필요한 정보 제거: 공백(Whitespace), 주석(Comment), 줄 바꿈 등 컴파일 과정에 영향을 주지 않는 문자들을 제거합니다.
- 토큰화(Tokenization): 소스 코드를 식별자(Identifier), 키워드(Keyword), 연산자(Operator), 리터럴(Literal) 등 최소 의미 단위인 토큰으로 분할합니다.
- 오류 감지: 정의되지 않은 문자나 잘못된 문자 시퀀스가 발견되면 즉시 어휘 분석 오류를 보고하여 디버깅을 용이하게 합니다.
어휘 분석의 동작 원리
어휘 분석기는 정규 표현식(Regular Expression)과 유한 상태 기계(Finite State Machine, FSM)의 원리를 기반으로 동작합니다. 일반적으로 다음과 같은 단계를 거칩니다.
1. 문자 시퀀스 읽기
렉서(Lexer)는 소스 코드 파일을 한 문자씩 또는 블록 단위로 읽어옵니다. 이때 현재 읽은 문자의 위치와 상태 정보를 추적합니다.
2. 패턴 매칭 및 토큰 생성
읽은 문자 시퀀스가 언어의 어휘 규칙(정규 표현식)과 일치하는지 확인합니다. 일치하는 경우 해당 시퀀스를 토큰으로 분류하고, 일치하지 않으면 오류를 처리하거나 다음 문자로 넘어갑니다.
3. 상태 전이
유한 상태 기계의 개념을 사용하여 현재 상태를 기반으로 다음에 읽을 문자가 토큰의 일부인지, 아니면 토큰의 종료를 의미하는지 결정합니다.
주요 토큰의 종류
어휘 분석기를 통과한 토큰은 일반적으로 토큰 타입(Token Type)과 토큰 값(Token Value)의 쌍으로 표현됩니다. 주요 토큰의 종류는 다음과 같습니다.
| 토큰 타입 | 설명 | 예시 |
|---|---|---|
| 키워드 (Keyword) | 언어가 미리 정의한 예약어로, 특별한 의미를 가집니다. | if, else, while, return, class |
| 식별자 (Identifier) | 프로그래머가 변수, 함수, 클래스 등의 이름으로 지정한 문자열입니다. | count, myFunction, UserClass |
| 리터럴 (Literal) | 소스 코드에 직접 명시된 고정된 값을 나타냅니다. | 42 (정수), "Hello" (문자열), 3.14 (실수) |
| 연산자 (Operator) | 산술, 비교, 논리 연산을 수행하는 기호입니다. | +, -, ==, &&, -> |
| 구분자 (Delimiter) | 구문적 구조를 구분하는 기호입니다. | ;, {, }, (, ) |
| 주석 (Comment) | 프로그램의 설명을 위한 텍스트로, 컴파일 시 무시됩니다. | // 주석, /* 주석 */ |
어휘 분석의 구현 방법
어휘 분석기를 구현하는 방법은 크게 두 가지로 나뉩니다.
1. 수동 구현 (Hand-crafted Lexer)
프로그래머가 직접 if-else 문이나 switch-case 문을 사용하여 문자를 읽고 토큰을 생성하는 로직을 작성합니다.
* 장점: 최적화가 용이하며, 복잡한 언어 규칙에 대한 정밀한 제어가 가능합니다.
* 단점: 유지보수가 어렵고, 새로운 언어 규칙 추가 시 코드가 복잡해집니다.
2. 자동 생성 도구 활용 (Lex/Flex 등)
Lex나 Flex와 같은 어휘 분석기 생성기(Generator) 도구를 사용하여 정규 표현식으로 토큰 규칙을 정의하면, 도구가 자동으로 C/C++ 등의 코드를 생성해 줍니다.
* 장점: 개발 속도가 빠르고, 규칙 변경 시 재컴파일이 용이합니다.
* 단점: 생성된 코드의 실행 효율성이 수동 구현보다 낮을 수 있으며, 디버깅이 어려울 수 있습니다.
어휘 분석의 중요성 및 한계
어휘 분석은 컴파일러 파이프라인의 시작점으로서, 이후 모든 처리 단계의 정확성에 영향을 미칩니다. 만약 어휘 분석 단계에서 토큰 분리가 잘못되면, 구문 분석기는 문법적 오류를 감지하지 못하거나 잘못된 해석을 하게 됩니다.
또한, 어휘 분석은 문맥에 의존적인(Context-dependent) 문제를 처리하기 어렵습니다. 예를 들어, class라는 단어가 키워드인지 식별자인지는 그 단어가 사용되는 문맥(예: class MyClass인지 MyClass class인지)에 따라 달라질 수 있습니다. 이러한 문맥 의존적인 문제는 어휘 분석 단계보다는 구문 분석 단계나 의미 분석 단계에서 해결되는 경우가 많습니다.
관련 문서 및 참고 자료
- 구문 분석 (Syntax Analysis): 토큰 시퀀스를 구문 트리(Parse Tree)로 변환하는 단계
- 유한 상태 기계 (Finite State Machine): 어휘 분석의 이론적 기반이 되는 계산 모델
- 정규 표현식 (Regular Expression): 토큰 패턴을 정의하기 위한 형식적 언어
- Lex / Flex: 널리 사용되는 어휘 분석기 생성 도구
본 문서는 컴파일러 원리에 대한 기초적인 설명을 포함하고 있으며, 실제 구현 시에는 사용된 프로그래밍 언어의 사양과 컴파일러 아키텍처에 따라 세부 동작이 다를 수 있습니다.
이 문서는 AI 모델(qwen/qwen3.6-35b-a3b)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.