13. 에러 처리

Download Report

Transcript 13. 에러 처리

13. 에러 처리
13-1. 에러의 종류
13-2. 에러 탐지 및 보고
13-3. 단계별 에러 처리
1
13-1. 에러의 종류
• 에러발생 원인
– 프로그램의 설계 명세서의 모순
– 프로그램의 설계 시 부적합한 알고리즘이 사용되었을 경우
– 프로그래머가 알고리즘을 잘못 구현했거나 언어를 부적합하게
사용한 경우
– 프로그램의 입력 에러(타이핑 에러)
– 프로그램이 컴파일러나 기계의 한계를 초과했을 때
– 마지막으로 거의 발생하지 않는 컴파일러 자체 에러를 들 수 있다.
2
• 에러의 종류
– 구문에러
• 어휘 분석이나 구문 분석 단계에서 일어나는 에러
• 에러 발생 예
– 괄호가 빠진 경우 : 삭제 에러
– 불필요한 콤마가 존재하는 경우 : 삽입 에러
– 세미콜론을 콜론으로 잘못 나타낸 경우 : 대치 에러
– 지정어를 틀리게 쓴 경우 : 전치 에러
– 여분의 빈칸이 들어간 경우 : 삽입 에러
3
– 시맨틱 에러
• 컴파일 시간과 실행 시간에서 발생할 수 있다. 컴파일 시간에서 발견 될 수
있는 시멘틱 에러는 대부분 선언과 스코프 에러들이다.
즉, 명칭이 선언되지 않았거나 하나의 명칭이 여러 번 선언된 경우이다.
명칭이 선언되지 않았을 경우, 특별한 조치를 취하지 않는다면 이 명칭을
사용할 때마다 같은 에러 메시지를 출력할 것이다. 그리고, 연산자와 피연
산자들 사이의 형의 모순, 내부 부프로그램의 형식 매개변수와 실매개 변수
사이의 모순 등도 컴파일 시에 발견 할 수 있는 에러이다.
– 동적 에러
• 실행 시간에 변수의 형을 바꿀 수 있다. 이런 경우 형 검사는 실행 시간
까지 연기해야 한다. 또한 배열의 첨자를 계산했을 때 제한된 영역을 넘어
가는 경우와 case문의 값이 정의 되지 않은 곳으로 분기 했을 경우
4
13-2. 에러 탐지 및 보고
• 에러 탐지
– 파서는 현재 형태, 즉 상태와 스택 내용, 그리고 현재의 입력
심벌에 대하여 적당한 파싱 행동을 가지지 않을 때 에러가
발생했음을 인식
• 에러 메시지의 속성
– 메신지는 내부 표현보다는 원시프로그램 입장에서 에러를
지적해야 한다.
– 사용자가 이해할 수 있도록 쓰여져야 한다.
– 문제를 국소화 하여 자세히 나타내어야 한다.
– 중복된 에러를 출력해서는 안 된다.
5
• Valid prefix property 방법
– LL(1)과 LR(1) 파서에서 입력의 prefix에 틀린 문자가 나오는
순간 에러를 인지
– 장점은 가능한 한 빠른 시간 내에 에러의 발생을 알 수 있고,
다음 단계에 넘겨질 에러가 있는 내용을 제한할 수 있다.
• Minimum Hamming distance
– 일련의 에러 변환을 정의하고 에러가 있는 프로그램을 올바른
프로그램으로 바꾸는데 필요한 가장 짧은 에러 변환의 과정이
길이 k를 갖는다면, 이 프로그램은 k개의 에러를 갖고 있다고
말하는 방법
6
13-3. 단계별 에러 처리
• 에러 처리 과정
에러 메시지
출력
어휘 복구기
원시코드
어휘 분석기
심벌 테이블
구문 복구기
토큰
파서
중간 코드
시멘틱 검사
 에러 처리
7
• 어휘 분석 단계 에러
– 이 과정이 수행되는 도중에 남은 입력의 prefix가 어떠한 토론
그룹과도 일치하지 않을 때 에러가 발생함을 알고 에러 복구
루틴을 부른다.
– 에러 복구 방법 중 어휘 분석기가 다른 토큰을 찾을 때까지 입력
문자를 버림으로써 처리 할 수 있지만, 이로 인하여 구문 분석
단계에서 삭제 에러를 유발시킬 수 있다.
– 원시 프로그램으로부터 무분별한 문자 삭제는 컴파일러의 남은
단계에서 더욱 큰 혼란을 야기시킬 수 있다. 어휘 분석기의 에러
복구 능력을 개선시키는 한 방법으로 파서가 현재의 상태에서
나타날 수 있는 토큰의 리스트를 어휘 에러 복구 루틴이 이용할
수 있도록 만들어 준다.
– 토큰의 철자가 틀린 경우, 최단 거리 매칭 방법을 이용하여
토큰의 철자를 수정함으로써 부가되는 에러를 피할 수 있다.
8
• 구문 단계 에러
– 프로그래밍 언어의 구문은 context-free 문법으로 표현되기
때문에 높은 정확도를 가진다. 그러므로 대부분 컴파일러의
에러 검출과 복구는 구문 분석에 집중된다. 다시 말해서 문법에
의해 정의된 언어를 정확히 인식할 수 있는 파서를 만들 수 있기
때문에 구문 에러는 파서에 의해 자동적으로 발견될 수 있다.
그리고 파서는 발견된 에러를 복구하기 위하여 에러를 수정하고
현재의 형태를 바꾼 후, 파싱을 계속 수행한다. 그러나 이와 같이
진행하여 모든 복구 방법은 파싱을 계속하게 하지만 에러가 성공
적으로 수정되었는지 확신할 수 없다. 또한 구문 에러의 복구나
수정을 위해 이론적으로나 실용적으로 많은 노력을 했지만
최적안은 아직 만들지 못하고 있다.
9
– Panic mode
• 에러가 발생을 했을 경우 파서는 세미콜론이나 end와 같은
문장 구분자 혹은 에러 처리를 위해 문법 정의에서 사용한
synchronizing 토큰을 만날 때 까지 입력 심벌을 버린다.
그리고, 파싱을 계속할 수 있도록 스택의 내용을 조정한다.
• 무한 루프에는 결코 빠지지 않는 장점을 갖는다.
• 모든 에러 방법에 사용 가능하다.
– LL파싱
• 에러수정 방법에는 크게 synchronizing 토큰을 이용하여 처리
하는 panic mode와 LL파싱 테이블의 에러 엔트리에 에러 복구
루틴을 가리키는 포인터를 채워넣는 방법이다.
10
• Panic mode
-LL파싱에서 사용되는 panic mode는 에러를 발견하는 순간 세미콜론과
같은 synchronizing 토큰들의 다음 내용들을 위하여 입력을 버린다.
그리고synchronizing 토큰을 유도하는 심벌 X(보통 X 자신이 됨)가 스택
의 top에서 나타날 때까지 제거한다. 만약 X가 synchronizing 토큰이
아닐 경우 X는 확장된 후, 같은 방법으로 스택의 top에 synchronizing
토큰이 나타날 때까지 심벌들을 제거한다. 그리고 synchronizing 심벌
다음에 나올 수 있는 심벌이 나올 때까지 입력 심벌을 버린다.
• LL 파싱 테이블의 빈 곳에 에러 복구 루틴을 가리키는 포인터를 채워넣는
방법
-이 루틴이 행하는 일은 입력 심벌을 삭제, 삽입 혹은 변형하는 것이다.
또한, 스택으로부터 내용을 조정하는 일도 포함된다. 그런데 파서에
의해 진행되는 과정이 언어에서 스트링을 유도 과정과 전혀 대응되지
않기 때문에 스택에 심벌을 삽입하거나 변환해도 되는지는 문제이며,
어떤 상황에서도 무한 루프의 발생 가능성이 없음을 확신할 수 있어야
한다.
11
- LR 파싱
• Panic mode
- 초창기에 사용되었던 에러 복구 방법의 하나로 panic mode 가 있다.
Panic mode는 매우 간단하게 실행 할 수 있으며, 자동 파서 생성기에
적합하고, 파서 생성기에 의해 생성된 파서에 쉽게 포함 시킬 수 있기
때문에 널리 사용되어 왔다. Panic mode를 실행하기 위하여
synchronizing 심벌을 정의하는 Pascal에서 세미콜론이나 지정의
end 같은 것이며, 대부분의 언어에서도 쉽게 synchronizing 심벌로
정의 할 수 있다.
- 빠르고 간단하지만 입력 심벌을 버리기 때문에 프로그램에서 모든
에러를 한 번에 찾을 수 없으며, 따라서 모든 에러를 찾기 위해서
여러 번의 실행이 피요하게 된다. 또한 에러가 일어난 이유를 정확히
규명할 수 없기 때문에 좋은 에러 메시지를 제공하지 못하는 단점이
있다.
12
– 파싱 테이블의 에러 엔트리에 에러 복구 루틴을 첨가 함으로써
파서가 이 엔트리를 참조했을 때 적절한 에러 처리 루틴이 호출
되어 에러를 처리하는 방법
• 컴파일러 설계자에 의해 에러의 성질에 따라 입력 스트림과 스택을
처리하게끔 작성된다.
• 스택의 상태 뒤에 나올 수 있는 심벌을 예측함으로써 입력 스트링을
삭제 또는 삽입하여 파싱을 계속 진행하는데 필요한 행동을 한다.
– YACC에서 사용되는 자동적 에러 복구 방법
• 주요 nonterminal을 정의하여 이용한다. 보통 주요 nonterminal은
program, block 혹은 statement와 같은 것이다. 그리고 사용자는
주요 nonterminal A에 대해 다음와 같은 형태의 생성 규칙을 문법에
첨가한다.
A error 
13
• 여기서 는 보통 empty 스트링이다. 그리하여 에러가 발견되었
을 때 에러 루틴은 위의 생성 규칙과 관련 있는 상태가 나올 때
까지 스택의 상태를 제거하고, 입력으로 error을 읽는 것처럼 스
택에 특별한 토큰 error를 shift 한다. 그 다음에 타당한 심벌이
나올 때까지 입력 심벌을 버린 후에 파싱을 계속한다.
• 시맨틱 에러
– 문법적으로는 올바르지만 의미적으로 틀린 에러
– 선언되지 않은 명칭의 경우
• 제일 처음 만났을 때 간단히 심벌 테이블에 적당한 속성과 그
이름을 기입한다. 속성은 사용된 이름의 내용에 유추할 수 있다.
14
– 선언되지 않거나 잘못 선언된 명칭에 대하여 잘못 사용된 원인과
위치의 리스트를 만들어 명칭이 잘못 사용되었을 경우
• 잘못 사용된 이름이 리스트에 존재한다면 에러 메시지의 출력은 중복
되지 않게 처리되며, 만약 리스트에 없을 경우 에러 메시지는 출력되고
이 리스트에 잘못 사용된 명칭을 첨가한다.
• 변수, 특히 배열이나 자료 구조 혹은 프로시저 이름의 철자가 틀린 경우
에는 사전에 주의하지 않으면 이와 무관한 에러 메시지를 발생할 수
있다.
15