Programming Languages & Compilers
추상화의 도구인 프로그래밍 언어의 설계 원리와 이를 기계어로 변환하는 컴파일러의 내부 메커니즘을 정의하는 학습 노드입니다.
Article
M
Me
hyunyoun's Blog
programming-languages-compilersprogramming-languagescompilerslanguages-compilersmeta-overviewlearningcompiler-architecturelanguage-semantics9 min read
1. Overview
프로그래밍 언어와 컴파일러(Programming Languages & Compilers, PLC)는 인간의 논리적 사고를 컴퓨터가 물리적으로 실행 가능한 기계어로 정밀하게 변환하는 추상화 및 번역 계층을 다룹니다. 본 카테고리는 단순한 문법 사용법을 넘어, 언어의 구조적 명세(Syntax/Semantics), 타입 시스템의 안정성, 그리고 중간 코드(IR) 생성 및 저수준 최적화를 통한 실행 효율성 극대화를 탐구합니다.
CS2023의 Foundational Programming Languages (FPL) 및 Programming Languages and Compilers (PLC) 지식 영역을 근간으로 삼아, 명령형·객체 지향·함수형 패러다임의 설계 원칙과 소스 코드가 바이너리로 변하는 전 과정을 체계적으로 다룹니다.
최근의 PLC는 성능과 메모리 안전성을 런타임 오버헤드 없이 보장하려는 Rust의 소유권(Ownership) 모델, 브라우저를 넘어선 범용 바이너리 포맷인 WebAssembly(WASM), 그리고 LLVM 기반의 모듈형 컴파일러 인프라 중심으로 진화하고 있습니다. DSA(04)가 추상적 연산 효율을 높인다면, PLC는 그 연산이 하드웨어(02)에서 낭비 없이 실행되도록 번역 최적화를 수행합니다.
2. Scope & Boundaries
In-Scope
- 언어 설계 및 패러다임: 프로그래밍 모델(Imperative, Functional, Logic), 다형성(Polymorphism), 데이터 가변성 제어, 스코프(Scope) 및 클로저(Closure) 원리.
- 컴파일러 프론트엔드: 정규표현식과 어휘 분석(Lexing), 문맥 자유 문법(CFG)과 구문 분석(Parsing), 추상 구문 트리(AST) 구성, 정적 타입 검사.
- 중간 코드 및 최적화: 중간 표현(IR: SSA form), 제어 흐름 분석(CFG), 데이터 흐름 분석, 인라인 홯장(Inlining), 무효 코드 제거(DCE).
- 런타임 및 가상 머신: 가비지 컬렉션(GC) 메커니즘, JIT(Just-In-Time) / AOT(Ahead-Of-Time) 컴파일러, 런타임 타입 정보(RTTI).
Out-of-Scope
- 특정 SDK/라이브러리 튜토리얼: Spring, Django, React와 같은 상위 응용 프레임워크 사용법 → 14. WET 노드로 위임.
- 소프트웨어 개발 방법론: 애자일, TDD, CI/CD 파이프라인 구축 → 09. SEDO 노드로 위임.
- 운영체제 시스템 호출 메커니즘: 커널 내부의 스레드 스케줄링이나 가상 메모리 매핑 상세 구현 → 03. OSSM 노드로 위임.
Boundaries
- PLC는 **'코드를 기계어로 번역하는 규칙(Semantics)과 도구(Compiler)'**에 집중하며, 이 도구를 사용하여 실제 비즈니스 가치를 창출하는 소프트웨어 설계 패턴은 소프트웨어 엔지니어링(09. SEDO) 도메인에서 다룹니다.
- 컴파일러 최적화는 캐시 히트율(02. CAES)이나 레지스터 수(02. CAES)와 밀접하게 연관되지만, PLC는 그 하드웨어 특성에 맞춰 어셈블리를 어떻게 생성할 것인가에 초점을 맞춥니다.
3. Counterexample
- 단순 문법 예약어 암기:
if,while등의 키워드를 외우는 것은 PLC 학습이 아닙니다. 왜 특정 언어가 **정적 스코프(Lexical Scope)**를 택했는지, 클로저(Closure)가 호출 스택 소멸 후에도 변수를 어떻게 유지하는지, **힙 할당 방지(Escape Analysis)**가 왜 중요한지 분석하는 것이 핵심입니다. - 표준 라이브러리 인터페이스만 사용: 가비지 컬렉션(GC)의 수거 방식(Mark-and-Sweep, Generational)이나 런타임 지연(Stop-the-world) 원리를 모른 채 객체를 대량 생성하는 것은, 언어의 내부 메커니즘을 통제하지 못하는 'API 소비자'일 뿐입니다.
- 인터프리터는 무조건 느리다: "Python은 인터프리터라 느리다"는 단편적 결론을 넘어, JIT(Just-In-Time) 컴파일러(예: PyPy, V8)가 어떻게 런타임 프로파일링을 통해 핫 패스(Hot Path)를 기계어로 번역하여 속도를 비약적으로 높이는지 최적화 원리를 파악해야 합니다.
4. Prerequisites
- 수학과 컴퓨팅 논리 (Basic): 정규 표현식(Regular Expressions), 유한 오토마타(DFA/NFA), 문맥 자유 문법(Context-Free Grammar)은 어휘/구문 분석기의 수리적 기초입니다. (P1
) - 자료구조 (Recommended): 심볼 테이블(Hash Map) 및 구문 트리 구축을 위해 트리 순회 기법에 대한 심화 숙련도가 필요합니다. (P1
) - 컴퓨터 구조 (Practical): 레지스터 할당(Register Allocation) 알고리즘과 함수 호출 시의 명령어 스택 프레임 구조(Calling Convention)를 알아야 물리적 코드 생성을 이해할 수 있습니다. (P1
)
5. Learning Map
6. Learning Topics
Basic
Core Topic 01: 프로그래밍 패러다임과 설계 원칙 (Paradigms & Design)
- Why to Learn: 문제의 성격(상태 중심 vs 데이터 흐름 중심)에 따라 가장 효율적인 언어와 설계 모델을 선택하여 부작용(Side-effect)을 최소화하기 위함입니다.
- What to Learn:
- Concepts: 명령형(Imperative), 함수형(Functional: Immutability, HOF), 객체 지향(OOP: Encapsulation, Polymorphism), 선언형(Declarative), 제어 역전(IoC).
- Skills: 동일 로직을 패러다임별로 변환하여 설계적 이점 비교하기, 정적 스코프(Lexical Scope)와 동적 스코프(Dynamic Scope)의 차이 이해.
- Tools: Paradigm-specific Linters(예: ESLint
functional), 언어별 REPL(Read-Eval-Print Loop). - Trade-offs: 함수형 패러다임의 높은 추상화 수준 및 동시성 안전성 vs 불변 객체 생성으로 인한 런타임 성능 저하 및 메모리 오버헤드.
- How to Learn:
- 1단계: 간단한 리스트 상태 변경 로직을 절차적 루프문(for)으로 작성한 뒤, 함수형 고차 함수(
map,filter,reduce)로 부작용 없이 리팩토링합니다. - 2단계: '클로저(Closure)'가 발생하는 조건을 재현하고, 메모리 힙(Heap) 덤프를 통해 소멸되어야 할 스택 변수가 어떻게 유지되는지 관찰합니다.
- 1단계: 간단한 리스트 상태 변경 로직을 절차적 루프문(for)으로 작성한 뒤, 함수형 고차 함수(
- Implement: 특정 도메인(예: 대규모 병렬 데이터 처리)에 적합한 언어 패러다임 선택 및 아키텍처 가이드라인.
Recommended
Core Topic 02: 타입 시스템과 정적 분석 (Type Systems & Analysis)
- Why to Learn: 실행 전(Compile-time)에 논리 오류의 90%를 수학적으로 식별하여 런타임 크래시를 방지하고 유지보수성을 극대화하기 위함입니다.
- What to Learn:
- Concepts: 정적 vs 동적 타이핑(Static vs Dynamic), 강타입 vs 약타입(Strong vs Weak), 타입 추론(Type Inference), 제네릭(Generics), 공변성/반공변성(Covariance/Contravariance).
- Skills: 도메인 주도 설계(DDD)에 입각한 정합성 높은 타입 정의, 대수적 데이터 타입(Algebraic Data Types: Union, Intersection) 활용.
- Tools: TypeScript Compiler(tsc), Rust Analyzer, MyPy (Python static analysis).
- Trade-offs: 동적 타입 언어의 초기 개발 속도 및 유연성 vs 정적 타입 언어의 실행 안전성, 자동 완성 도구(IDE) 지원, 대규모 리팩토링 용이성.
- How to Learn:
- 1단계: TypeScript의 인터페이스와 유니온 타입을 이용해 복잡한 비즈니스 엔티티(예: 결제 상태)를 명세화하고 타입 가드(Type Guards)를 작성합니다.
- 2단계: Rust의 소유권(Ownership) 모델을 실습하며 다중 스레드 환경에서 데이터 경합(Data Race)이 컴파일 타임에 차단되는 원리를 경험합니다.
- Implement: 런타임 예외 처리를 컴파일 타임 에러로 강제하는 엄밀한 모듈 API 명세서(타입 선언 파일).
Practical
Core Topic 03: AST 및 컴파일러 프론트엔드 (AST & Frontend)
- Why to Learn: 린터(Linter), 코드 포매터, 트랜스파일러, 또는 사내 비즈니스 로직을 위한 도메인 특화 언어(DSL)를 직접 제작할 수 있는 엔지니어링 능력을 갖추기 위함입니다.
- What to Learn:
- Concepts: 어휘 분석(Scanning/Lexing), 구문 분석(Parsing: LL/LR), 추상 구문 트리(AST), 심볼 테이블(Symbol Table), 정적 의미 분석.
- Skills: 정규표현식을 이용한 토큰화, 재귀 하강 파서(Recursive Descent Parser) 구현, AST 순회 모델(Visitor Pattern).
- Tools: ANTLR, Lex/Yacc, Babel AST Explorer, Tree-sitter.
- Trade-offs: 문법 규칙 설계 시 파싱 속도(단순성) vs 언어 표현력(복잡성) 간의 균형 — 예: C++의 파싱 모호성.
- How to Learn:
- 1단계: 단순한 사칙연산 수식(
3 + 5 * 2)을 토큰화하고, 연산자 우선순위가 반영된 AST 트리로 직접 변환(파싱)해 봅니다. - 2단계: Babel AST 플러그인을 작성하여, 코드 내의 특정 함수 호출(예:
console.log)을 다른 코드 로직으로 자동 변환(Transpiling)하는 실습을 합니다.
- 1단계: 단순한 사칙연산 수식(
- Implement: 특정 보안 코딩 컨벤션을 강제하거나, 오래된 문법을 최신 문법으로 자동 수정해주는 커스텀 정적 분석(Linter) 도구.
Advanced
Core Topic 04: 런타임 시스템과 메모리 관리 (Runtime & Memory)
- Why to Learn: 가비지 컬렉션(GC)으로 인한 Stop-the-world 지연을 제어하고, 고성능 JIT 가상 머신의 최적화 기법을 이해하여 서버 애플리케이션의 꼬리 지연시간(Tail Latency)을 줄이기 위함입니다.
- What to Learn:
- Concepts: GC 알고리즘(Mark-and-Sweep, Copying), 세대별 수집(Generational GC), 참조 카운팅(Reference Counting), JIT 컴파일링, 인라인 확장(Inlining).
- Skills: 런타임 메모리 단편화 분석, 힙 덤프(Heap Dump) 추적을 통한 메모리 누수(Leak) 지점 식별, 가비지 컬렉터 튜닝.
- Tools: JVM Flags(
-XX:+UseG1GC), Chrome V8 Inspector (Memory/Performance profile),jstat,jmap. - Trade-offs: 메모리 사용량(Footprint)의 최소화 vs GC 발생 빈도 감소 및 시스템 응답성 지연 방지(Throughput vs Latency).
- How to Learn:
- 1단계: 대량의 수명 짧은 객체를 무한 루프에서 생성/삭제하는 Java/Node.js 코드를 작성하고 모니터링 도구로 GC 발생 주기와 Stop-the-world 지연을 관찰합니다.
- 2단계: JIT 컴파일러가 빈번하게 호출되는 함수('Hot Spot')를 감지하여 기계어로 컴파일한 후, 함수 인자 타입이 바뀌었을 때 역최적화(Deoptimization)가 일어나는 현상을 V8 로그로 추적합니다.
- Implement: GC 튜닝 파라미터를 조절하여 목표 지연 시간(99th percentile) 내 응답률을 달성한 런타임 메모리 최적화 보고서.
7. Terminology
8. References
Primary References
- [P1] CS2023: FPL — Foundational Programming Languages.
- [P1] CS2023: PLC — Programming Languages and Compilers.
- [P2] SWEBOK v4: Software Construction.
Secondary References
- [Dragon Book] Compilers: Principles, Techniques, and Tools — Aho, Lam, Sethi, Ullman (컴파일러학의 고전).
- [Types and Programming Languages] Benjamin C. Pierce — 타입 이론과 언어 설계의 필독서.
Industry References
- [LLVM Project] Conceptual Guide — 현대 산업계의 컴파일러 제작 표준 인프라.
- [V8 Engine Documentation] Design Elements — JavaScript 실행 효율을 극대화한 구글의 가상머신 설계.
9. Final Checklist
Primary Checklist
- 특정 프로그래밍 패러다임(OOP vs Functional)이 제공하는 추상화의 이점과 런타임 비용을 근거 있게 설명할 수 있는 있는가? (P1-FPL)
- Lexing에서 Code Generation에 이르는 컴파일 전 과정을 단계별 산출물(Token, AST, IR)과 연계하여 기술 가능한가? (P1-PLC-LC)
Secondary Checklist
- 정적 타입 언어와 동적 타입 언어의 트레이드오프를 '타입 안전성'과 '유연성' 관점에서 평가했는가?
- 꼬리 재귀 최적화(Tail Call Optimization)가 실행 시 스택 메모리 점유에 마치는 영향을 원리적으로 이해하고 있는가?
Industry Checklist
- 런타임 프로파일링을 통해 가비지 컬렉터의 동작 방식을 파악하고 Stop-the-world 지연을 최소화하는 설계를 제안했는가?
- LLVM IR과 같은 현대적 컴파일러 인프라가 언어 설계 및 다중 아키텍처 지원 생산성을 어떻게 높이는지 이해하고 있는가?