컴파일러
컴파일러(Compiler)는 특정한 형식으로 작성된 프로그램을 의미가 대응되는 다른 형식의 프로그램으로 변환하는 소프트웨어이다. 일반적으로 프로그래밍 언어로 작성된 소스 코드를 기계어, 목적 코드, 바이트코드 또는 다른 프로그래밍 언어로 변환한다. 이 과정을 컴파일(Compilation...
| 분류 | 시스템 소프트웨어, 프로그래밍 언어 구현 |
|---|---|
| 입력 | 소스 코드, 중간 표현 |
| 출력 | 기계어, 목적 코드, 바이트코드, 다른 프로그래밍 언어 |
| 주요 구성 | 프런트엔드, 중간 표현, 최적화기, 백엔드 |
| 관련 기술 | 어셈블러, 링커, 로더, 인터프리터, 가상 머신 |
| 대표 구현체 | GCC, LLVM, Clang, javac, rustc |
컴파일러(Compiler)는 특정한 형식으로 작성된 프로그램을 의미가 대응되는 다른 형식의 프로그램으로 변환하는 소프트웨어이다. 일반적으로 프로그래밍 언어로 작성된 소스 코드를 기계어, 목적 코드, 바이트코드 또는 다른 프로그래밍 언어로 변환한다. 이 과정을 컴파일(Compilation)이라고 한다.
컴파일러는 단순히 명령어의 표기를 바꾸는 변환기가 아니다. 입력 프로그램의 구조를 분석하고, 이름과 타입의 사용이 언어 규칙에 맞는지 검사하며, 프로그램의 의미를 보존하는 중간 표현을 만든 뒤 이를 분석하고 변환한다. 이후 대상 명령어 집합 아키텍처나 가상 머신이 실행할 수 있는 코드를 생성한다.
전형적인 컴파일러는 어휘 분석과 구문 분석을 수행하는 프런트엔드, 프로그램을 언어와 하드웨어로부터 부분적으로 분리해 표현하는 중간 표현, 코드를 개선하는 최적화 단계, 대상 시스템의 명령어와 호출 규약에 맞는 코드를 생성하는 백엔드로 구성된다. 그러나 모든 컴파일러가 이 구분을 동일하게 따르는 것은 아니다. 작은 컴파일러는 여러 단계를 하나로 통합할 수 있고, 대규모 컴파일러 기반은 프런트엔드와 최적화기, 코드 생성기를 독립된 구성 요소로 제공할 수 있다.[1]
컴파일 결과가 항상 독립적인 실행 파일인 것은 아니다. Java 컴파일러인 javac는 Java 소스 코드를 JVM에서 실행되는 클래스 파일로 변환하며, 다른 컴파일러는 웹 브라우저나 언어 런타임에서 실행되는 바이트코드를 생성할 수 있다.[2] 한 프로그래밍 언어를 다른 고수준 언어로 변환하는 소스 대 소스 컴파일러도 있으며, 프로그램 실행 중 필요한 부분을 컴파일하는 JIT 컴파일과 실행 전에 전체 또는 일부를 변환하는 AOT 컴파일도 사용된다.
현대의 컴파일러는 언어 구현뿐 아니라 정적 분석, 프로그램 최적화, 코드 계측, 디버깅 정보 생성, 자동 완성, 리팩터링과 같은 개발 도구의 기반으로도 활용된다. LLVM과 같은 컴파일러 기반은 여러 언어의 프런트엔드와 여러 하드웨어의 백엔드가 중간 표현을 중심으로 기능을 공유할 수 있도록 구성된다. LLVM IR은 정적 단일 할당 형식에 기반한 공통 코드 표현으로 사용된다.[3]
컴파일러는 보통 어셈블러, 링커, 로더, 표준 라이브러리, 런타임 시스템, 디버거와 함께 하나의 도구 체인을 구성한다. 컴파일러 드라이버는 이러한 프로그램을 순서대로 호출하여 소스 파일에서 실행 파일이나 라이브러리를 만드는 전체 빌드 과정을 조정하기도 한다. 따라서 일상적으로 “컴파일러”라고 부르는 명령은 실제 언어 변환기뿐 아니라 전처리, 어셈블, 링크 단계를 제어하는 드라이버를 의미할 수 있다.