컴파일러 디자인이란 무엇입니까? 유형, 건설 도구, 예
⚡ 스마트 요약
컴파일러 단계는 소스 코드를 기계어로 변환하는 6단계, 즉 어휘 분석, 구문 분석, 의미 분석, 중간 코드 생성, 코드 최적화 및 코드 생성을 설명하며, 기호 테이블 관리 및 오류 처리가 이를 지원합니다.
컴파일러 디자인의 단계는 무엇입니까?
A 컴파일러 컴파일러는 여러 단계를 거쳐 작동하며, 각 단계는 소스 프로그램을 한 표현 방식에서 다른 표현 방식으로 변환합니다. 모든 단계는 이전 단계의 입력을 받아 다음 단계로 출력을 전달합니다. 컴파일러는 총 6단계로 구성되어 있으며, 각 단계는 고급 언어를 기계어로 변환하는 데 도움을 줍니다. 컴파일러의 단계는 다음과 같습니다.
- 어휘 분석
- 구문 분석
- 의미 분석
- 중간 코드 생성기
- Code 옵티 마이저
- Code 발전기
컴파일러의 단계
이 모든 단계는 소스 코드를 토큰으로 나누고, 구문 분석 트리를 생성하고, 다양한 단계를 통해 소스 코드를 최적화함으로써 소스 코드를 변환합니다.
1단계: 어휘 분석
어휘 분석은 컴파일러가 소스 코드를 스캔하는 첫 번째 단계입니다. 이 과정은 왼쪽에서 오른쪽으로, 문자 단위로 진행되며, 이러한 문자들을 토큰으로 그룹화합니다.
여기서는 소스 프로그램의 문자 스트림을 토큰을 식별하여 의미 있는 순서로 그룹화합니다. 그런 다음 해당 토큰을 심볼 테이블에 입력하고 다음 단계로 전달합니다.
이 단계의 주요 기능은 다음과 같습니다.
- 소스 코드에서 어휘 단위를 식별하십시오.
- 어휘 단위를 상수, 예약어와 같은 범주로 분류하여 각각 다른 표에 입력합니다. 소스 프로그램의 주석은 무시됩니다.
- 언어의 일부가 아닌 토큰을 식별합니다.
예: x = y + 10
| Token | 타입 |
|---|---|
| X | 식별자 |
| = | 할당 연산자 |
| Y | 식별자 |
| + | 덧셈 연산자 |
| 10 | 번호 |
2단계: 구문 분석
구문 분석은 코드의 구조를 파악하는 작업입니다. 텍스트가 예상되는 형식을 따르는지 여부를 판단합니다. 이 단계의 주요 목적은 프로그래머가 작성한 소스 코드가 올바른지 확인하는 것입니다.
구문 분석은 특정 프로그래밍 언어의 규칙에 따라 토큰을 이용하여 구문 트리를 구성하는 방식입니다. 이를 통해 소스 언어의 구조와 문법 또는 구문을 파악할 수 있습니다.
이 단계에서 수행된 작업 목록은 다음과 같습니다.
- 어휘 분석기에서 토큰을 가져옵니다.
- 표현이 문법적으로 올바른지 확인하십시오.
- 구문 오류를 모두 보고하십시오.
- 구문 트리라고 알려진 계층 구조를 구성합니다.
예시
모든 식별자/숫자는 표현식입니다. 만약 x가 식별자이고 y+10이 표현식이라면, x = y+10은 문장입니다. 다음 예제의 구문 분석 트리를 살펴보세요.
(a+b)*c
구문 분석 트리에서:
- 내부 노드: 연산자 필드와 자식 노드용 필드 두 개를 가진 레코드.
- 리프 레코드: 토큰을 나타내는 필드 하나와 토큰에 대한 기타 정보를 나타내는 필드 하나, 총 두 개 이상의 필드를 가진 레코드.
- 프로그램의 구성 요소들이 의미 있게 서로 연계되도록 하십시오.
- 타입 정보를 수집하고 타입 호환성을 확인합니다.
- 검사 피연산자는 소스 언어에서 허용되는지 확인합니다.
3단계: 의미 분석
의미론적 분석은 코드의 의미론적 일관성을 확인합니다. 이는 기호 테이블과 함께 이전 단계의 구문 트리를 사용하여 주어진 소스 코드가 의미상 일관성이 있는지 확인합니다. 또한 코드가 적절한 의미를 전달하는지 여부도 확인합니다.
의미 분석기는 타입 불일치, 호환되지 않는 피연산자, 부적절한 인수로 호출된 함수, 선언되지 않은 변수 등을 검사합니다.
의미 분석 단계의 기능은 다음과 같습니다.
- 수집된 형식 정보를 저장하고 이를 심볼 테이블이나 구문 트리에 저장하는 데 도움이 됩니다.
- 타입 검사를 수행할 수 있습니다.
- 타입 불일치가 발생하여 원하는 연산을 만족하는 정확한 타입 수정 규칙이 없는 경우, 의미 오류가 표시됩니다.
- 타입 정보를 수집하고 타입 호환성을 확인합니다.
- 소스 언어가 피연산자를 허용하는지 여부를 확인합니다.
예시
float x = 20.2; float y = x*30;
위 코드에서 의미 분석기는 곱셈을 하기 전에 정수 30을 부동 소수점 30.0으로 형변환합니다.
4단계: 중급 Code 세대
의미 분석 단계가 완료되면 컴파일러는 대상 머신용 중간 코드를 생성합니다. 이 코드는 특정 절대값에 대한 프로그램을 나타냅니다.tract 기계.
중간 코드는 고급 언어와 기계어 사이의 코드입니다. 이 중간 코드는 목표 기계어로 쉽게 변환할 수 있도록 생성되어야 합니다.
중간자의 기능 Code 세대:
- 이는 소스 프로그램의 의미 표현으로부터 생성되어야 합니다.
- 번역 과정 중에 계산된 값을 저장합니다.
- 중간 코드를 대상 언어로 번역하는 데 도움이 됩니다.
- 소스 언어의 우선순위 순서를 유지할 수 있습니다.
- 명령어에 필요한 피연산자의 개수를 정확하게 담고 있습니다.
예시
예 :
total = count + rate * 5
주소 코드화 방법을 이용한 중간 코드는 다음과 같습니다.
t1 := int_to_float(5)
t2 := rate * t1
t3 := count + t2
total := t3
위상 5 : Code 최적화
다음 단계는 중간 코드의 최적화입니다. 이 단계에서는 불필요한 코드 줄을 제거하고 명령문의 순서를 재배열하여 리소스 낭비 없이 프로그램 실행 속도를 향상시킵니다. 이 단계의 주요 목표는 중간 코드를 개선하여 더 빠르게 실행되고 더 적은 공간을 차지하는 코드를 생성하는 것입니다.
이 단계의 주요 기능은 다음과 같습니다.
- 이를 통해 실행 속도와 컴파일 속도 사이의 균형점을 찾을 수 있습니다.
- 대상 프로그램의 실행 시간을 개선합니다.
- 중간 표현 형식으로 간소화된 코드를 생성합니다.
- 접근할 수 없는 코드를 제거하고 사용하지 않는 변수를 없앱니다.
- 반복문에서 변경되지 않는 문장을 제거합니다.
예: 다음 코드를 고려하십시오.
a = intofloat(10)
b = c * a
d = e + b
f = d
다음과 같이 될 수 있습니다:
b = c * 10.0
f = e + b
위상 6 : Code 세대
Code 생성 단계는 컴파일러의 마지막 단계입니다. 코드 최적화 단계에서 입력을 받아 페이지 코드 또는 목적 코드를 생성합니다. 이 단계의 목적은 저장 공간을 할당하고 재배치 가능한 기계어 코드를 생성하는 것입니다.
또한 변수를 위한 메모리 위치를 할당합니다. 중간 코드의 명령어는 기계어 명령어로 변환됩니다. 이 단계에서는 최적화된 또는 중간 코드가 대상 언어로 변환됩니다.
목표 언어는 기계어 코드입니다. 따라서 모든 메모리 위치와 레지스터도 이 단계에서 선택 및 할당됩니다. 이 단계에서 생성된 코드는 입력을 받아 예상되는 출력을 생성하도록 실행됩니다.
예시
a = b + 60.0은 레지스터로 다음과 같이 변환될 수 있습니다:
MOVF a, R1 MULF #60.0, R2 ADDF R1, R2
심볼 테이블 관리
심볼 테이블은 각 식별자에 대한 레코드를 포함하며, 각 레코드에는 식별자의 속성 필드가 있습니다. 이 구성 요소를 통해 컴파일러는 식별자 레코드를 더 쉽게 검색하고 빠르게 가져올 수 있습니다. 또한 심볼 테이블은 스코프 관리에도 도움이 됩니다. 심볼 테이블과 오류 처리기는 모든 단계와 상호 작용하며, 심볼 테이블은 그에 따라 업데이트됩니다.
오류 처리 루틴
컴파일러 설계 과정에서 다음과 같은 모든 단계에서 오류가 발생할 수 있습니다.
- 어휘 분석기: 철자가 틀린 토큰입니다.
- 구문 분석기: 괄호가 빠져 있습니다.
- 중간 코드 생성기: 연산자의 피연산자가 일치하지 않습니다.
- Code 최적화 : 해당 문장에 접근할 수 없을 때.
- Code Generator: 메모리가 가득 찼거나 적절한 레지스터가 할당되지 않은 경우.
- 심볼 표: 식별자가 중복 선언되어 오류가 발생했습니다.
가장 흔한 오류는 스캐닝 시 잘못된 문자 시퀀스, 유형에서 잘못된 토큰 시퀀스, 범위 오류 및 의미 분석 시 구문 분석 오류입니다.
오류는 위의 어느 단계에서든 발생할 수 있습니다. 오류를 발견한 후에는 컴파일 프로세스를 계속 진행하기 위해 오류를 처리해야 합니다. 이러한 오류는 오류 처리기에 보고되어야 하며, 오류 처리기는 오류를 처리하여 컴파일 프로세스를 계속 수행합니다. 일반적으로 오류는 메시지 형태로 보고됩니다.



