컴파일러의 정의와 역할
- 컴파일러: 고급 언어(C/C++, Pascal 등)로 작성된 프로그램을 기계어 코드로 번역.
- 인터프리터: 실행할 때마다 원시 프로그램을 읽고 결과를 생성.
주요 번역기 종류
- 전처리기(Preprocessor): 원시 프로그램을 확장.
- 어셈블러: 어셈블리 코드를 기계어로 변환.
- 로더/링커: 여러 기계어 코드를 하나로 결합.
컴파일 프로세스 과정
프리프로세서 -> 컴파일러 -> 어셈블러 -> 로더 링커 -> 목적 프로그램
- 프리프로세서: 확장된 원시 프로그램 생성.
- 어셈블러: 어셈블리어로 변환.
- 로더/링커: 최종 기계어 코드 생성 및 재배치.
컴파일러의 구조
분석-통합 모델
소스 코드 -> 분석 -> 중간 코드 -> 통합 -> 목적 코드
- 분석(Front-End): 코드 분석, 오류 검출 및 중간 코드 생성.
- 통합(Back-End): 중간 코드를 목적 코드로 변환 및 최적화.
" 원시 코드 -> 어휘 분석 -> 구문 분석 -> 의미 분석 -> 중간 코드 생성 -> 코드 최적화 -> 목적 코드 생성 "
어휘 분석(Lexical Analysis)
- 역할: 프로그램을 키워드, 식별자, 연산자 등으로 구분. (의미 있는 단위로 나눈다.)
- 어휘 구조: 어휘의 형태 -> 정규 표현
- 예: position := initial + rate * 60; → id1 := id2 + id3 * num60
- 어휘 분석기: scanner
- 어휘 분석기 생성기: lex, scangen
구문 분석(Syntax Analysis)
- 역할: 문법 구조를 확인하고 구문 오류를 검출.
- 구조: 파스 트리(Parse Tree)나 유도 트리(Derivation tree), 구문 트리(AST) 생성.
- 문법 구조: 올바른 구조란 어떤 것인가 -> 문맥 무관 문법
- 구문 분석기: parser
- 구문 분석기 생성기: yacc
오류 발생 위치
어휘 분석 시
- 어휘 오류: 허용되지 않는 문자의 입력구문 분석 시
- 구문 오류: 문법에 맞지 않는 문장실행 시
- 논리 오류: 의도한 대로 계산되지 않음의미 분석 시
- 정의되지 않는 연산
의미 분석(Semantic Analysis)
- 역할: 문법적으로 맞지만 의미가 정의되지 않은 문장 검출.
- 예: 선언되지 않은 변수 사용, 자료형 불일치, 매개변수의 개수와 형의 불일치 등.
중간 코드 생성 및 최적화
- 중간 코드: 목적 코드 생성 전의 중간 단계 코드. 전단부에서 파스트리를 순회하면서 생성함.
- 예시
temp1 = inttoreal(60) temp2 = id3 * temp1 temp3 = id2 + temp2 id1 = temp3
최적화
- 정의: 효율적인 코드의 생성. 크기가 작고 빠르고 기억장소 요구량이 작은 코드.
- 중요성: 컴파일은 한번, 컴파일된 목적 코드의 실행은 무한대. 컴파일 시 많은 시간이 소요되어도 무방.
최적화 종류
- 지역 최적화: 공통 부분식 제거, 상수 계산 등.
- 전역 최적화: 도달할 수 없는 코드 제거, 공통 부분식의 제거.
- 루프 최적화: 루프 풀어 헤치기, 루프 붙이기 등.
목적 코드 생성 및 최적화
- 목적 코드: 실행 가능한 최종 기계어 코드. 효율적인 레지스터 할당.
- 목적 코드 생성 예시
MOVF id3, R2 MULF #60.0, R2 MOVF id2, R1 ADDF R2, R1 MOVF R1, id1