[CS] Compiler Basic

컴파일러 란?

언어를 번역한다 = 번역기

 

 

컴파일러(번역기)의 종류
원시프로그램   ->   번역기   ->   목적프로그램

어셈블리어   ->   어셈블러   ->   기계어

고급언어   ->   컴파일러   ->   저급언어
C, C++, Java …

고급언어   ->   인터프리터   ->   실행결과
Python, Javascript …

고급언어   ->   프리프로세서   ->   고급언어

Typescript …

 

컴파일러(Compiler) 기법

  • 번역 후 실행
  • 효율적
  • C, C++, Java 등

 

인터프리터(Interpreter) 기법

  • 번역과 동시에 실행
  • 융통성
  • Python, Javascript, LISP 등

 

 

컴파일러의 논리적 구조 6단계

1. 어휘분석 (Lexical Analysis = Scan)

  • 어휘를 토큰으로 변환 
  • 의미있는 수식
  • 사용할 수 없는 토큰 발견 시 오류

 

2. 구문분석 (Syntax Analysis = Parse)

  • 분석결과를 파스트리로 출력
  • 올바른 토큰의 배치
  • 토큰 순서가 문법에 맞지 않을 시 오류

 

3. 의미분석 (Semantic Analysis)

  • 파스트리에 의미부여. 실행 전 사전작업
  • 논리가 맞는 지 확인
  • 연산의 의미가 부적절할 시 오류

 

4. 중간코드 (Intermediate Language)

  • 후위표현, 3 주소코드, U 코드, 구문지시적변환
  • 장점
1. 번역과정이 좀 더 쉽고 효율적
2. 기계와 독립적인 최적화 가능
3. 인터프리터를 이용하여 실행 가능
  • 단점
1. 목적코드로 직접 번역한 것보다 시간 소요
2. 비효율적인 코드 생산

 

5. 최적화 (Optimizer)

  • 효율화, 수행시간 최소화, 기억공간 최소화

 

6. 목적코드 생성 (Target Code Generation)

  • 사용할 레지스터의 수 결정, 계산과정 결정

 

 

 

Q1. 문자는 어떻게 연산하나?

A1. 인코딩을 한다.

 

 ASCII, Unicode (UTF-8) 등

 

 

 

언어별 컴파일러

1. C/C++

  • 컴파일러 언어
  • 사전 컴파일 (즉시 컴파일 단계 없음)
  • 컴파일 결과를 파일(바이너리 코드)로 저장
  • CPU로 코드(바이너리 코드)를 바로 실행 가능
  • 장점
1. 실행 파일 재활용 가능 (빠르다)
2. 실행 전 오류 발견 가능
  • 단점
1. 초기 실행이 오래걸린다

 

2. Python/Javascript

  • 인터프리터 언어
  • 코드를 한 줄씩 읽고 실행
  • 소스코드 해석 결과(바이트 코드)가 메모리 내에 저장
  • 사전 컴파일, 즉시 컴파일 단계 없음
1. 과거에는 없었으나 최근에는 즉시 컴파일 도입 (PyPy, V8 Engine)
2. PyPy 구현체에 JIT 컴파일러 내장
3. 구글 크롬 브라우저에 V8 Engine 내장
  • 장점
1. 메모리 효율이 좋다
2. 빌드 없이 바로 실행 가능
  • 단점
1. 실행 후에 오류 발견
2. 실행 속도가 느리다

 

3. Java

사전 컴파일(AOT, Ahead-Of-Time)

  • 빌드 시, (.class) 파일 생성
  • 바이트코드 저장

즉시 컴파일(JIT, Just-In-Time)

  • 런타임 시, JVM이 바이트코드를 실제 기계 코드(바이너리 코드)로 변환

 

 

 

Q2. 인터프리터 언어는 바이너리 코드로 변환되지 않으면 CPU가 읽을 수 없을 텐데, 어떻게 실행되는 건가?

A2. 인터프리터가 자기가 해석한 것을 토대로 CPU 에게 수행해야될 동작을 전달하기 때문이다.

 

 

 

Q3. JVM 위에서 동작하는 언어는 자바와 같은 특징을 가지고 있나?

A3. 맞다.

 

Kotlin과 Scala는 둘 다 Java Virtual Machine (JVM)을 기반으로 하는 언어이기 때문에 바이트코드로 컴파일하는 사전 컴파일 단계를 거치고, 이 바이트코드는 JVM에서 실행될 수 있다.

 

 

 

Q4. 파이썬도 Virtual Machine(PVM) 이 있던데 Java 와 무엇이 다른가?

A4. 바이트코드가 파일로 저장되는 시점이 다르다.

 

Java 는 빌드 시에 .class 파일로 바이트코드가 저장되지만, Python 은 런타임 시에 .pyc 파일로 바이트코드가 저장된다.

 

 

 

Q5. Java만 특별히 사전 컴파일과 즉시 컴파일 단계가 공존하는 이유는 무엇인가?

A5. 창시자의 철학이 Write Once, Run Anywhere 였기 때문이다.

 

Java 는 JVM 이라는 추상화 계층 덕분에 OS 에 직접 의존하지 않고, JVM 만 설치되어 있으면 어느 OS 에서든 동작한다. 그러나 C/C++ 은 OS 에 직접 의존하기 때문에 각 OS 에 맞는 컴파일러가 필요하다.

인터프리터도 웹 기반이 아니라면(웹 기반일 경우 브라우저를 공통으로 사용한다) OS 위에서 실행되는 인터프리터 프로그램이 필요하다. Python 은 CPython, Ruby 는 Ruby Interpreter 등 OS 에 맞는 것으로 설치해야 한다.