본문 바로가기
프로그래밍언어론

[프로그래밍언어론] 6. 컴파일러와 인터프리터

by 파스텔코랄 2023. 9. 11.
컴파일러인터프리터는 모두 사람이 작성한 코드를 기계가 실행할 수 있는 하위 수준 코드로 변환한다.

 


 

컴파일러 vs 인터프리터

컴파일러 인터프리터
완전한 코드 → 실행 가능한 프로그램
생성된 실행 프로그램의 실행 성능과 효율성에 중점
코드와 실행을 연결하는 것이 상대적으로 어렵다.
컴파일 시간에 오류를 찾는다.
C++
표현식 읽고 평가 → 명령 실행
구현하기는 쉽지만 속도가 느리다.
런타임 오류 → 코드에 직접 연결
부분 코드를 실행 가능(일부 표현식)
Python



컴파일러

  • 고급 언어 코드 → 컴퓨터에서 실행 가능한 기계 명령어
  • 인간과 기계 사이의 번역기
  • object file : 컴파일러는 객체(대상) 언어로 코드를 생성
  • 그런 다음 이러한 개체 파일은 하나의 실행 가능한 프로그램으로 결합

 

컴파일 단계

  1. 어휘 분석(Lexical Analysis)
  2. 구문 분석(Syntax Analysis)
  3. 의미 분석(Semantic Analysis)
  4. 중간 코드 생성(Intermediate Code Generation)
  5. 코드 최적화(Code Optimization)
  6. 코드 생성(Code Generation)

 

어휘 분석(Lexical Analysis)

  • 소스 코드를 일련의 토큰으로 변환
    예) 키워드, 리터럴, 식별자, 숫자, 연산자 등.
    int a = 10; → int (keyword), a (identifier), = (operator), 10 (number literal), ; (symbol)
  • 공백과 주석을 제거
  • 토큰이 유효하지 않으면 오류가 발생

 

구문 분석(Syntax Analysis)

  • 구문 분석 단계에서는 토큰의 순서가 올바른 구문을 따르는지 확인한다.
  • "파싱(Parsing)" 단계라고 한다.
  • 소스 코드의 구문 구조를 나타내는 구체적인 구문 트리(Concrete Syntax Tree) / 구문 분석 트리(Parse Tree) / 파생 트리(Derivation Tree) 생성
  • 구문 분석할 수 없는 코드 → 구문이 올바르지 않습니다!

의미 분석(Semantic Analysis)

  • 구문 분석 트리(Parse Tree)는 의미 분석을 통해 "주석 추가(annotated)", "decorated".
  • 이 단계에서 수집된 정보는 코드 생성에 사용
  • 구문 분석코드의 의미에 대해 아무것도 제공하지 않는다.
  • 따라서 우리는 코드의 의미를 파악해야 한다. 코드를 평가
  • 종종 구문 분석과 결합

중간 코드 생성(Intermediate Code Generation)

  • 컴파일러의 최종 결과는 기계에 따라 달라지는 경우가 많다.
  • 따라서 기계어 코드는 기계 독립적인 코드 최적화를 적용하는 데 바람직한 오브젝트가 아니다.
  • 대신 컴파일러는 오브젝트 시스템에 독립적인 중간 코드를 생성
  • 그런 다음 먼저 코드를 최적화하고 추가로 오브젝트 시스템에 대한 명령으로 변환

 

코드 최적화(Code Optimization)

  • 컴파일러는 실행 가능한 프로그램을 생성하기 전에 자동으로 코드 최적화 수행
    예) 데드 코드 제거, 공통 하위 표현식 제거, 복사 전파, 루프 최적화 등.
          a=i*j+k; b=i*j*k; → tmp=i*j; a=tmp+k; b=tmp*k;
  • 최적화를 통해 코드가 크게 향상
  • 인터프리터에 없는 중요한 장점

 

코드 생성(Code Generation)

  • 중간 코드를 입력으로 사용하여 동등한 오브젝트 프로그램을 생성한다.
  • 요구사항
  • 출력 코드가 정확
  • 출력 코드는 오브젝트 머신의 리소스를 효율적으로 사용
  • 코드 생성기 자체가 효율적으로 실행

 


 

인터프리터

  • 소스 코드를 직접 읽고 코드를 평가하여 결과를 얻는다.
  • 때로는 실제 컴퓨터에서 실행되는 가상 컴퓨터를 구현한 다음 가상 컴퓨터에서 코드를 실행
  • 구현하기가 더 쉽고 컴파일러보다 메모리를 적게 차지하지만 속도가 느리다.
    예) Python, ML, Scheme, Prolog 등

 

REPL

  • Read-Eval-Print Loop(읽기-평가-인쇄 루프)
  • 인터프리터는 실제로 위의 세 가지 작업을 반복
  • 전체 프로그램이 필요하지 않으며 단순히 읽은 내용을 평가
  • 런타임에 코드를 작성 가능 → 사용이 쉽다.

댓글