[Compiler] Introduction

노잼개발자·4일 전

Compiler

목록 보기
1/1

Compiler에 대해서 배우는 이유

학습 방법

현재 한양대학교 ERICA에서 오희국 교수님이 강의하시는 Compiler 강의를 수강하고 있다.
해당 강의는 Stanford University [CS143 Compilers]
내용에 기반하여서 해당 자료를 참고자료로 복습하고 있으며

영어 강의 참고자료는 다음과 같다
[Youtube]

Software 개발

AI, Agent, Model, Application, Program 등
다양한 목적에 의해 SW 개발이 이뤄지며
생산성이 향상되어 시장이 과열된 현재 시점에서도
수많은 수요에 의해 수많은 SW개발이 지속적으로 이루어지고 있다.

이 모든 SW는 모두 동일한 Programming Language라는
하나의 통상적으로 정의된 Interface를 통해 개발이 이뤄지고 있다.

이러한 Language들은 Compiler와 Interpreter를 통해
실제 Computer Processor의 명령어 및 레지스터 체계에 기반하여
binary 실행 파일로 변환 가능한 어쎔블리어로 변환된다.
즉, 현재 Programming Language들은 Compiler와 Interpreter를 통해 추상화가 이루어져있으며
이러한 추상화를 통해 객체지향 프로그래밍과 같이 컴퓨터아키텍처 자체에대한
이해를 크게 요구하지 않고 Language 자체 문법만 인지해도
SW 개발이 가능하도록 하였다.

Compiler를 이해하는 것의 목적

결국 Compiler를 이해하는 것은
현재 우리가 사용하는 Programming Language들이 실행 코드로 변환되는 과정을 이해한다는 것이다.
그 과정에서 메모리에 올라가 프로세스로 변환되기 위한 요구사항과
프로세서에서 하나의 thread로 실행되기 위한 요구사항을
반영할 것이고 이를 이해한다는 것이다.

이러한 지식이 추후 나에게 데려다줄 기대값을 생각하면 다음과 같다
1. Programming Language의 문법(Grammar)가
Compile 과정에서 적용되는지 Runtime 과정에서 적용되는지
이해하고 경계를 인지할 수 있게 된다.
이는 코드 분석에 있어서 정적 분석과 동적 분석의 경계의 기반 지식이 될 것이라 생각한다.
2. C와 같이 Compiler만 사용하는 언어와
Java와 같이 Compiler와 Interpreter를 모두 사용하는 언어의 차이를 인지하고 언어 사용시 해당 언어 설계(JVM)를 이해하는 기반이 될 것이라 생각한다.
3. CPU 기반 Architecture에서의 Compiler를 이해하는 것으로 보인다. 하지만 현대 Computer Architecture는 GPGPU, NPU, TPU, PIM, PNM과 같이 수많은 accelerator가 연산을 분담하는 구조이다. 이러한 변화되는 Computer Architecture에서 코드를 어떻게 적용할지 파악할지에 대한 시야 혹은 이를 넘어서 해당 Accelerator에 적합하게 Compiler를 변경할 수 있는 능력을 가질 수 있을지도 모른다 생각한다.

Compiler의 강의가 시사하는 점과 강의 접근 방식

Compiler라는 수업은 내게 Programming Language는 결국 하나의 Interface이자 개발자 대상 UI라는 점을 이야기한다.
컴퓨터 사용자의 다양한 요구사항과 컴퓨터 자체에 대한 이해를 기반으로 한 요구사항에 따라 적합한 Programming Language가 개발이 되었다.

지금까지 기술에 대한 이해 뿐만이 아닌 서비스 개발에 있어서도
유저 요구사항 분석만을 기반으로 진행하였고
해당 기술이 요구하는 요구사항에 대해서 명시적으로 명세한적이 없었던거 같다.
따라서 수업에서 이 두가지 관점의 요구사항을 기반으로 접근하는 방식을 이해하고 이에 맞게 정리를 해보려 한다.

Compiler Introduction

Pre-Notation

Code -> Execution

Compiler를 이해하기 위해서는
개발자가 작성한 소스코드가 어떠한 절차를 거쳐 실행되는지 이해해야 한다.
C/C++를 예시로 보면 다음과 같다
1. Preprocessing - Processor (Source Code -> Expanded Code)
gcc -E [소스파일.c] -o [출력파일.i]
2. Compilation - Compiler (Expanded Code -> Assembly Code)
gcc -S [소스파일.c] -o [출력파일.s]
3. Assemby - Assembler (Assembly Code -> Object Code)
gcc -c [소스파일.c] -o [출력파일.o]
4. Linking - Linker (Object Codes -> Executable Code)
gcc [소스파일.c] -o [실행파일]
5. Execution

The Role of Compiler

  • Translaction : High Langauge -> Low Language
    GCC의 경우 Assembly Language는 메모리 및 유한 register공간(L1 I-Cache, L1 D-Caceh 할당을 하며 정해진 명령어 규격에 맞게 변환을 한다.
  • Error Detection : Programming Language에서 제공하는 Grammar와 다르게 사용하는 경우 Semantic 해석 과정에서 문제가 되는 Token을 파악한다.
  • Code Optimization : Translation 과정에서 Language 설계자의 의도된 사항에 따라 변형하여 Low Language로 변환한다.
  • Portability : 여러 OS 혹은 Processor Architecture Type에 대해서 지원하도록 한다.

Compiler vs Interpreter

강의에서는 Interpreter에 대해서는 On-Line,
Compiler에 대해서는 Off-Line으로 설명한다.

Interpreter (On-Line)

Interpreter run Program.
Interpreter는 해당 Langauge로 만든 Program에 대해서
Program 실행 전까지 어떠한 전처리(Preprocessing) 없이
Program 실행과 함께 실행되며 Data와 Program이 Interpreter를 통해
직접적으로 Output을 만든다.

Compiler (Off-Line)

Compiler translate Program.
Compiler는 실행파일을 만들기 위해 한번만 실행되며
해당 실행 파일을 실행하여 Data를 입력 받아 Output(출력)을 만든다.

Classification of Language

  • Compile Language : C, C++, Go, Rust
  • Interpret Language : Python, Java Script
  • Both(Interpreter + JIT(Just In Time) Comiler) : Java, JavaScript, Web Assembly

History of Comiler and High Language

1954 - 704

  • 704 : IBM's Mass-produced Computer Hardware
  • All Programming Done in Assembly
    -> Software cost exceeded Hardware

Suggestion

1) Interpreter - Speed Coding

  • Runtime is 10-20 times slower than Assembly Code
    This Property is same with present Interpreter.

2) Compiler - FORTRAN (FORMULA TRANSLATE)

  • Translate High-level Language to Assembly Code
  • Performance close to Hand-written Assembly

Impact on Computer Science

  • Programming become easier
    -> an enormous body of theoritical and practical work
  • The Out Line of Modern Compiler
    -> Macro Structure of Compiler
    (Lexical Analysis, Parsing, Semantic Analysis, Optimization, Code Generation)

The Structure of a Compiler

  1. Lexical Analysis : Identify Keyword
  2. Parsing : Identify Sentence
  3. Semantic Analysis : Analyze Sentence
  4. Optimization : Editing
  5. Code Generation : Translating

1. Lexical Analysis

  • 주체 : Lexer
  • 하는 일 : Partition input string into substrings, where the substrings are called tokens.
  • Output : a Sequence of Tokens

전체 흐름상 뭔가 Parsing이 의미 자체가 직관적으로 String을 단어로 나누는 거 같지만 처리 단위(Unit)이 다르다
String은 A sequence of Characters 즉 character의 연속이다.
이러한 이론상 무작위적인 character들을 구분하는 기준을 통해 Token으로 분리하는 작업이
Lexical Analysis이다.
추후 다음장에서 배우지만 Toekn의 정의는 다음과 같다

  • Token : A lexeme labeled with its class - a pair <Token class, Lexeme>

2. Parsing

  • 주체 : Parser
  • 하는 일 : Lexer로 부터 받은 A sequence of Token을 통해 Sentence structure를 구성하는 작업
  • Output : Diagramming Sentence
    (The Diagram is a tree)

강의에서는 English Analogy를 통해 해당 부분을 설명한다.

article, noun, verb, adjective가 token class이며
token class를 종합하여 Grammar에 따른 Component(Subject, Object)를 파악하여
Diagramming Sentence를 구성한다.

실제 코드 if x == y then z = 1 else z = 2를 살펴보면 다음과 같다.

기타

요구사항에 의한 Language 분류

Scientific - 과학적 계산 목적

  • 대표 예 : Fortran

Business - 특정 작업 목적

  • 대표 예 : SQL

System - 컴퓨터 리소스 작업 목적

  • 대표 예 : C, Cpp

Programming Language Cost

  • Productivity > training cost => switch language
profile
기초만 깎는 노잼 개발자 기초 재미떠 재미떠

0개의 댓글