우리는 일상속에서 우리의 언어로 소통하고 상호작용한다. 하지만 우리의 언어로 컴퓨터와 소통을 시도한다면 아마 거의 불가능할 것이다. AI가 성행하고 있는 현재, 우리의 언어로 소통할 수 있는 거 아니야? 라고 생각할 수 있다. 하지만 실제로는 컴퓨터 안에서 어떠한 많은 과정이 있기 때문에 그것이 가능해 보이는 것이고, 실제 컴퓨터와 소통을 한다는 것과는 다른 의미이다. 사실 컴퓨터는 우리의 언어를 전혀 이해할 수 없다.
컴퓨터는 그들만의 언어인 기계어를 사용한다. 0과 1로 이루어진 단순한 형태의 기계로를 오롯이 이해할 수 있기 때문에 우리의 언어를 컴퓨터는 이해할 수 없다. 그로 인해 우리의 언어를 컴퓨터가 이해할 수 있도록 번역을 해주는 과정이 필요하다. 그 과정을 컴파일라고 하고 번역을 해주는 변역기가 바로 컴파일러이다.
오늘은 프로그래밍에서 가장 중요하고 기초적인 개념인 컴파일에 대해 알아볼 것이다.
컴파일이란
컴파일은 고급 프로그래밍언어로 작성된 소스코드 (C, C++, Java 등)을 기계어 또는 중간 코드로 변환하는 과정이다. 컴퓨터가 이해할 수 있는 언어는 숫자와 이진수로 구성된 기계어이기 때문에, 개발자가 작성한 코드를 직접 실행할 수 없고, 이를 컴파일러라는 도구를 사용하여 변환해야 한다.
이때, C나 Java 등으로 표현된 언어는 사람이 이해할 수 있는 언어로, 사람의 언어와 가까워 고급 언어(High-Level Language)라고 부른다. 그리고 컴퓨터가 이해할 수 있는 언어로 변환을 해주는데, 이러한 언어를 저급언어(Low-Level Language)라고 부른다. 컴파일러는 코드의 구문(Syntax)와 의미(Semantics)를 분석하여 고급 언어를 저급언어로 변환을 시켜주고 그 과정에서 최적화 작업을 통해 실행 효율성을 높이는 작업도 수행한다.
컴파일의 주요 역할
문법 분석 및 오류 검출
소스 코드에서 문법(Syntax)이나 논리적인 오류를 찾아낸다. 예를 들어, 괄호가 짝이 맞지 않거나 변수 선언이 누락된 경우 컴파일 오류를 발생시킨다.
중간 코드 생성
컴파일러는 소스 코드를 중간 표현(Intermeditate Representation) 형태로 변환한다. 이 중간 코드는 특정 플랫폼에 종속되지 않으며, Java의 경우에는 바이트 코드(ByteCode)를 생성한다.
목적 코드 생성
컴파일러는 중간 코드에서 최종적으로 기계어(Machine Code) 또는 어셈블리어(Assembly Code)로 변환된 목적 파일(Object File)을 생성한다.
최적화
컴파일러는 코드 실행 속도를 높이고, 메모리 사용량을 줄이는 등의 최적화를 수행한다.
컴파일 과정
1. 소스 코드 입력
사용자가 작성한 소스 코드 (.c, .java, .py 등)가 입력된다.
2. 어휘 분석(Lexical Analysis)
소스 코드를 토큰(Token)이라는 최소 단위로 분리한다.
int x = 5; // int, x, =, 5, ;로 나뉨
이 단계에서는 주석을 제거하고, 의미없는 공백을 무시한다.
3. 구문 분석(Syntax Analysis)
어휘 분석 결과를 바탕으로 코드의 구조와 문법이 올바른지 확인한다. 이 과정은 파싱 트리를 생성하는데, 이는 프로그램 구조를 시각적으로 표현한 트리 구조이다. 오류가 있다면, 이 단계에서 컴파일 오류(Complie Error)가 발생한다.
4. 의미 분석(Semantic Analysis)
프로그램의 의미를 검사한다. 예를 들어, 선언되지 않은 변수를 참조하거나 데이터 타입이 일치하지 않는 경우 오류를 보고한다.
5. 중간 코드 생성(Intermediate Code Generation)
소스 코드를 플랫폼 독립적인 중간 표현으로 변환한다.
6. 최적화(Optimization)
중간 코드 또는 최종 코드에서 불필요한 연산을 제거하거나, 반복 구조를 효율적으로 바꿔 실행 속도를 개선한다.
7. 목적 코드 생성(Object Code Generation)
중간 코드를 기계어 또는 어셈블리어로 변환하여 목적 파일(Object File)을 생성한다. 목적 파일은 직접 실행 할 수 없고, 링커(Linker)를 통해 실행 파일로 결합해야 한다.
목적 파일은 .o 또는 .obj 확장자를 가진 파일이다.
이렇듯, 컴파일은 모든 프로그래밍에서 중요한 역할을 한다. 각 언어들은 언어들의 컴파일러가 존재하고 각 컴파일러는 그에 맞는 산출물을 반환한다. 또한 Java 처럼 중간 코드가 존재하는 언어들이 있는 반면, C 처럼 중간 코드가 없는 언어들도 존재하기 때문에 어떠한 언어를 배울 때 그 언어의 컴파일 과정도 학습하는 것이 매우 중요하다.
'기본 개념' 카테고리의 다른 글
| 빌드(Build)란 - 컴파일에서 실행까지 (1) | 2025.01.17 |
|---|---|
| 링크(Link), 링킹(Linking)이란 (0) | 2025.01.14 |
| 파싱(Parsing) 이란 (0) | 2025.01.09 |
| 브라우저란 (0) | 2025.01.08 |