관리 메뉴

c0smicb0y

[컴파일러] Introduction (소개) 본문

프로그래밍/컴파일러

[컴파일러] Introduction (소개)

2015. 1. 25. 23:53
컴파일러
정의 : 특정 프로그래밍 언어로 쓰여 있는 문서를 다른 프로그래밍 언어로 번역하는 컴퓨터 프로그램.

원시 언어(Source Language)로 작성된 프로그램을 입력받아서, 목적 언어(Target Language)로 작성된 동일한 의미의 프로그램을 출력으로 가진다.

원시언어란 C나 C++같은 사람이 이해하기 쉬운 고급 언어(High-Level Language)이고, 목적 언어란 목적 컴퓨터에서 실행되는 기계 명령들로 작성된 코드인 목적 코드(Object Code) 또는 기계 코드(Machine Code)이다.




역사
초기 컴퓨터 프로그램들은 기계에 의해서 실제로 수행될 연산을 표현하는 숫자로 된 코드인 기계어로 작성되었다. 하지만 기계어는 작성하는데 시간이 많이 걸리고 지루하기 때문에, 명령과 메모리 주소를 기호로 표시하는 어셈블리어가 탄생하였다. 어셈블리어는 프로그램의 작성 속도와 정확성을 크게 증대시켰다. 하지만 어셈블리어도 단순히 기계어를 1대 1로 대응시켜 만든 언어이기 때문에. 여전히 프로그램 작성이 쉽지 않았고, 컴퓨터에 종속적이라서 종류가 다른 컴퓨터에서 프로그램을 쓸려면 그 컴퓨터에 맞춰서 다시 작성해야 했다. 그래서 프로그램이 특정 컴퓨터와는 독립적이게 만들기 위해, 독립적인 언어를 만들었고, 이 언어를 실행가능한 코드로 변환 시키는 프로그램이 컴파일러이다.




컴파일러 관련 프로그램
해석기 (Interpreter)

해석기는 컴파일러와 마찬가지로 언어 번역기이다. 번역이 완료된 후에 원시 프로그램을 바로 실행한다는 점이 컴파일러와 다르다. 컴파일러에 의해 컴파일된 목적 코드가 해석기에 의해 해석된 원시 코드보다 보통 10배 이상 빠르기 때문에, 실행속도가 최우선되는 상황에서는 컴파일러를 선호한다. 하지만 사용하는 언어와 번역이 이루어지는 상황에 따라서 컴파일러보다 해석기가 더 좋을 수 있다(속도의 측면만 본 것이 아니다).


어셈블러 (Assembler)

특정 컴퓨터의 어셈블리용 번역기이다. 때로는 컴파일러는 목적어로 어셈블리어를 생성하고, 목적 코드로의 번역은 어셈블러에 의존하기도 한다.


링커 (Linker)

링커는 따로 컴파일되거나 어셈블되어서 서로 다른 목적 파일에 저장되어 있는 코드들을 바로 실행할 수 있는 하나의 파일로 모아주는 프로그램이다. 컴파일러와 어셈블러는 모두 링커에 의존한다.


로더 (Loader)

컴파일러, 어셈블러, 링커는 아직 완전히 고정되지도 않고 실행 준비가 되지도 않은 코드를 생성하지만, 주요 메모리 참조는 메모리의 어디에서나 가능한 미결정된 시작 주소와 항상 관련되어 이루어진다. 이러한 코드를 재배치가능(relocatable)하다고 하고, 로더는 주어진 기준 주소, 혹은 시작 주소와 관련된 모든 재배치가능한 주소를 해결한다.


전처리기 (Preprocessor)

전처리기는 실제 번역이 시작되기 전에 컴파일러가 호출하는 독립 프로그램이다. 주석 지우기, 다른 파일 포함시키기, 매크로 치환하기를 한다.


편집기 (Editor)

말 그대로 프로그램을 편집하는 프로그램이다. 최근에 들어와서는 컴파일러는 편집기와 다른 프로그램들과 함께 묶어져서 IDE라고 부른다.


디버거 (Debugger)

디버거는 컴파일된 프로그램에서 실행오류는 찾는데 사용할 수 있는 프로그램이다.


프로파일러 (Profiler)

프로파일러는 실행 중에 목적 프로그램의 실행에 관한 통계를 모으는 프로그램이다.


프로젝트 관리기(Project Manager)

현대 소프트웨어 프로젝트는 규모가 방대하여 여러 프로그래머가 그룹지어 개발을 하게 된다. 이러한 경우에 버전을 관리해주고 여러사람이 작업한 파일을 조정하는 일이 필요한데, 이러한 작업을 쉽게 해주는 것이 프로젝트 관리기라고 한다. 요즘에는 버전관리시스템이라고 부르기도 한다. git이 대표적이다.





번역 절차


컴파일러는 리터럴 테이블, 심볼 테이블, 오류 취급기와 상호 작용하면서 위와 같은 순서에 따라 실행된다.


스캐너 (Scanner)

연속된 문자들로 이루어진 원시 코드를 읽어서 단어와 같은 토큰(token)이라고 하는 의미 있는 단위를 골라내는 어휘 분석(lexical analysis)을 실시한다.


예를 들어 다음과 같은 코드를 어휘 분석해보자.

1
list[i] = 3 + 5
cs

이 코드는 공백 문자를 제외하고 문자가 11개이지만, 토큰은 다음과 같이 8개이다.


list 식별자

[   왼쪽 대괄호

i   식별자

]   오른쪽 대괄호

=  할당

3  숫자

+  덧셈기호

5  숫자


스캐너는 토큰의 인식과 같이 식별자를 심볼 테이블에 넣는 작업을 하거나, 리터럴(literal)을 리터럴 테이블에 넣는 작업을 할 수 있다(리터럴이란 3.1415926와 같은 상수와 "Hello, World!"같은 인용 문자열을 가리킨다).



파서 (Parser)

파서는 스캐너로부터 토큰으로 나눠진 원시 코드를 받아서 프로그램의 구조를 결정짓는 구문 분석을 수행한다. 구문 분석의 결과는 파스 트리 또는 구문 트리로 나타낸다.



이것이 list[i] = 3 + 5의 파스 트리이다.


코드의 구조적 요소는 표현식(exprssion)이라고 하며, 왼쪽은 인덱스를 포함한 표현식(subscript-exprssion)이고 오른쪽은 산술 표현식(additive-expression)으로 구성된 할당 표현식(assign-exprssion)이다.


구문 트리는 추상 구문 트리라고도 불리며, 파스 트리가 좀 더 추상화 된 형태이다.





의미 분석기 (Semantics Analyzer)

프로그램의 의미(semantics)는 구문 또는 구조와는 달리 프로그램의 뜻(meaning)을 나타낸다. 의미 분석기는 실행에 앞서 결정할 수 는 있지만 구문으로 표현하거나 파서로 분석할 수 없는 부분인 정적 의미(static semantic)를 분석한다. 전형적으로 정적 의미라고 하는 부분은 선언과 타입 검사이다. 의미 분석기가 계산하는 추가적인 정보를 속성(attribute)라고 하고, 보통 트리에 장식으로 추가된다.





원시코드 최적화기 (Source Code Optimizer)

원시수준 최적화 기회가 존재할 때 최적화를 하는 프로그램이다. 3 + 5는 컴파일러가 미리 계산하여 8의 결과를 줄 수 있다(이 기법을 상수 폴딩(constant folding)이라고한다).




코드 생성기 (Code Generator)

중간코드를 받아서 목적 컴퓨터용 코드를 생선하는 프로그램이다.



목적코드 최적화기 (Target Code Optimizer)

컴파일러가 생성한 목적 코드의 성능향상을 시도하는 프로그램이다.





부트스트래핑(Bootstrapping)과 이식(Porting)

컴파일러는 A라는 언어를 B언어로 바꾸는 프로그램이다. 그런데 이 컴파일러가 무슨 언어로 작성되었는지에 대해서는 언급하지 않았다. A를 원시 언어라고하고, B를 목적 언어라고 하고 컴파일러를 작성한 언어를 호스트 언어라고 한다. 이를 다음과 같이 T의 모양을 본따서 만든 T-다이어그램으로 나타낼 수 있다.


S가 원시 언어이고 T가 목적 언어, H가 호스트언어이다.


T-다이어그램을 결합하는 방법은 두가지가 있다. 

먼저 같은 호스트 언어로 작동하는 컴파일러의 출력과 입력이 같을 경우에 이 둘을 결합할 수 있다.



다음으로 호스트 언어를 다른 언어로 컴파일하는 것을 결합할 수 있다.




컴파일러를 작성할 때 컴파일하는 언어와 같은 언어로 작성하는 것은 흔한 일이다.


하지만 이러면 어떻게 첫번째 컴파일러가 작성될 수 있는가에 대한 문제가 생긴다. 이 닭이 먼저냐, 달걀이 먼저냐 문제를 해결하기 위해서 부트스트래핑이 사용된다.


먼저 어셈블리어나 기계어로 좀 미숙한 컴파일러를 제작한다. 이 컴파일러는 상당히 비효율적인 코드를 생산해 낼 수도 있다. 일단 이 미숙한 컴파일러가 돌아가기만 하면, 그 컴파일러를 진짜 컴파일러를 컴파일하는데 사용하여 최종 컴파일러를 만들어낼 수 있다. 이러한 과정을 부트스트래핑이라고 한다.




이것을 활용하여 컴파일러를 새로운 호스트 컴퓨터에 이식할 수 있다.









Comments