반응형
컴파일러의 구조
컴파일러는 Front-end (전단부) 와 Back-end (후단부) 로 나뉜다.
- Front-end → 소스코드의 의미를 분석하고, 중간 표현(IR)을 생성하는 부분
- Back-end → IR을 최적화하고, 실제 기계어 코드로 변환하는 부분

컴파일러의 컴포넌트
컴파일러의 컴포넌트는 다음과 같이 나눠진다

| 1. Lexical Analyzer (어휘 분석기) | 문자 스트림(character stream)을 읽고, 토큰(token)으로 나눔 → a = b + c; → <id,a>, <=,=>, <id,b>, <+,+>, <id,c> |
Token stream |
| 2. Syntax Analyzer (구문 분석기) | 토큰을 문법에 맞게 트리 구조로 분석 → 구문 트리(syntax tree) 생성. 즉, 프로그램의 구조(문법적 계층)를 파악함. |
Syntax tree |
| 3. Semantic Analyzer (의미 분석기) | 구문이 문법적으로 맞더라도, 의미적으로 유효한지 검사.예: 변수 선언, 타입 일치 검사, 스코프 확인 등. | AST (Abstract Syntax Tree) |
| 4. Intermediate Code Generator (중간 코드 생성기) | AST를 기반으로 중간 표현(IR) 생성. → t1 = b + c / a = t1 같은 3-address code |
IR (Intermediate Representation) |
| 5. Machine-Independent Code Optimizer (기계 독립적 코드 최적화) | IR 단계에서의 최적화 수행 (CPU 종류와 무관). → 상수 폴딩, 불필요한 계산 제거, 루프 단순화 등. |
최적화된 IR |
| 6. Code Generator (코드 생성기) | IR을 실제 기계어 또는 어셈블리 코드로 변환 → Intel x86, ARM 등 특정 아키텍처 명령으로 변환 |
Target-machine code |
| 7. Machine-Dependent Code Optimizer (기계 의존적 최적화) | CPU 구조나 레지스터 구조에 맞게 코드 최적화. → 레지스터 할당, 파이프라인 효율화 등. |
최종 목적 코드 |
symbol Table (심볼 테이블)
- 프로그램 내 변수, 함수, 타입, 범위(scope) 등의 정보를 저장하는 데이터베이스.
- 컴파일 전체 과정에서 참조된다.
- 예를 들어, 의미 분석기나 코드 생성기에서 변수의 타입/주소 정보를 찾을 때 사용된다.
Front-end vs Back-end
| 구분 | 주요 단계 | 주요 목적 | 출력 |
| Front-end | 어휘 분석, 구문 분석, 의미 분석, 중간 코드 생성 | 프로그램의 의미를 이해하고, 추상화된 IR 생성 | IR |
| Back-end | 코드 최적화, 코드 생성, 기계 의존적 최적화 | 효율적인 기계어 코드 생성 | Target Machine Code |
컴파일러의 컴포넌트 - Front-end

1단계: Lexical Analysis (어휘 분석기)
입력: 문자 스트림 (원시 소스코드)
출력: 토큰(Token) 스트림
역할
- 소스 코드를 의미 단위(Token) 로 쪼갬
- 각 단어가 어떤 종류인지 분류 (식별자 id, 연산자 op, 숫자 num 등)
- 동시에 심볼 테이블(Symbol Table) 을 생성해 변수 정보를 기록한다.
2단계: Syntax Analysis (구문 분석기)
입력: 토큰 스트림
출력: Parse Tree (구문 트리)
역할
- 토큰들이 문법에 맞게 배열되어 있는지 검사한다,
- 문법 규칙(Grammar)에 따라 구조적인 트리를 만든다.

3단계: Semantic Analyzer — 의미 분석기
입력: Syntax Tree (구문 트리)
출력: Annotated Syntax Tree (주석이 달린 구문 트리 = AST)
역할
- 변수의 타입 검사(type checking), 형 변환(type conversion), 의미적 오류 탐지 수행한다.
- rate * 60 에서 rate가 float인데 60이 int라면?
- inttofloat(60)으로 자동 형변환(inserted cast)
4단계: Intermediate Code Generator — 중간 코드 생성기
입력: AST
출력: IR (Intermediate Representation, 중간 코드)
역할
- 기계어에 가까운 중간 형태로 변환한다.
- 이 IR은 최적화나 실제 코드 생성의 기반이 된다.
t1 = inttofloat(60) ; 상수 60을 float으로 변환
t2 = id3 * t1 ; rate * 60.0
t3 = id2 + t2 ; initial + (rate * 60)
id1 = t3 ; position = 결과 저장
컴파일러의 컴포넌트 - Back-end

5단계: Code Optimizer — 코드 최적화기
입력: IR
출력: 최적화된 IR (더 효율적인 형태)
역할
- 불필요한 중간 변수 제거, 중복 계산 최소화 등 수행한다.
- inttofloat(60)이 여러 번 등장하면 한 번만 계산하도록 최적화 가능하다.
6단계: Code Generator — 코드 생성기
입력 : 최적화된 중간 코드 (Optimized IR)
출력: 타깃 머신 코드 (Target Machine Code) → 실제 CPU 명령어(어셈블리 수준)
역할
- 중간 코드(IR)를 실제 하드웨어가 이해할 수 있는 명령어 형태로 변환한다.
- 각 명령에 대응하는 레지스터와 명령어를 선택한다.
- 변수의 주소 계산(address computation) 및 레지스터 할당 수행한다.
- CPU 아키텍처(예: Intel, ARM 등)에 맞는 기계 명령어로 변환한다.
반응형
'{Lecture} > Compiler' 카테고리의 다른 글
| [컴파일러] BNF 정리 (0) | 2025.10.23 |
|---|---|
| [컴파일러] 촘스키 언어 계층 정리 - 문법 정리 (0) | 2025.10.23 |
| [컴파일러] NFA -> DFA 변환 (0) | 2025.10.23 |
| [컴파일러] 컴파일러란? (0) | 2025.10.22 |
| [컴파일러] 3주차 Grammar Basic (0) | 2025.09.16 |