파서 오류 복구: 항목 단위로만 회복한다. 문 단위로 더 잘게 회복하려 하면 파서가 추측을 하게 되고, 틀린 추측은 없는 오류를 지어낸다. 한 항목에 오류 하나가 상한이라는 것은 정직한 한계다. 동기화 지점은 중괄호 깊이 0 + 줄 첫머리 + 선언 시작 토큰 — 셋 다 필요하다. 본문 안의 fn을 새 항목으로 오인하면 그 뒤가 전부 어긋난다. 샘플 08이 이제 오류 넷을 한 번에 보고한다. 두 lint (취향이 아니라 비용이다): - 미사용 import는 재검사 범위를 넓힌다. 쓰지 않는 모듈의 시그니처가 바뀌면 이 모듈이 재검사된다. - effect 과잉 선언은 호출자에게 없는 의무를 지운다. 시그니처는 실제보다 좁아도 안 되고 넓어도 안 된다. 과잉 선언은 effect 변수가 있거나 본문에 모르는 이름이 있으면 판정하지 않는다. 첫 구현이 샘플 03/06을 오탐으로 잡았는데, 원인이 외부 타입이었다 — 외부 capability의 메서드는 effect를 모르므로 "수행하지 않았다"고 말할 근거가 없다. saw_unknown으로 판정을 보류한다. Resolve.error에 blocking을 나눴다. 이름 해소 실패는 뒤 단계를 막지만 lint는 막지 않는다 — lint 하나가 진짜 타입 오류를 가리면 루프가 느려진다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
46 lines
1.9 KiB
Plaintext
46 lines
1.9 KiB
Plaintext
// 08. 파서가 거부해야 하는 코드
|
|
//
|
|
// 05와 목적이 다르다. 05는 구문은 맞지만 검사기가 거부해야 하는 파일이고,
|
|
// 이 파일은 파서가 거부해야 하는 파일이다.
|
|
// 파서는 항목 단위로 회복한다. 오류가 난 선언은 통째로 버리고 다음 선언에서
|
|
// 다시 시작하므로, 한 항목에 오류 하나가 상한이다. 이 파일은 항목마다 하나씩
|
|
// 심어 회복이 실제로 되는지 본다 — 아래 넷이 모두 보고되어야 한다.
|
|
|
|
// [E-syntax-effect-union] 파라미터 위치의 합집합은 문법에 존재하지 않는다.
|
|
// 검사기가 아니라 파서가 거부한다 (eff_param 프로덕션에 "|"가 없다).
|
|
pub fn peel[a, e: effects](
|
|
f: fn(a) effects e | {Logger.write},
|
|
) effects e -> fn(a)
|
|
// ERROR (parse): 파라미터 위치의 effects 절은 변수 단독 또는 리터럴 집합만 허용
|
|
|
|
// [E-syntax-match-guard] match 가드는 v0 문법에 없다
|
|
pub fn classify(e: PayError) -> String {
|
|
match e {
|
|
Network(r) if r.retryable => "retry",
|
|
// ERROR (parse): match 가드는 지원되지 않음. 분기 본문에서 if를 쓸 것
|
|
_ => "other",
|
|
}
|
|
}
|
|
|
|
// [E-syntax-trailing-comma] 다중 줄 목록에는 후행 콤마가 필요하다.
|
|
// 줄바꿈이 목록을 닫으려 하면 원인을 직접 말한다.
|
|
pub fn missing_comma(
|
|
a: Int,
|
|
b: Int
|
|
) -> Int
|
|
// ERROR (parse): 다중 줄 목록에는 후행 콤마가 필요합니다
|
|
|
|
// [E-syntax-scope-parent] 자식 scope는 부모를 명시해야 한다.
|
|
// 부모 없는 작업이 생기지 않게 하는 것은 문법의 일이다.
|
|
pub fn orphan(root: TaskScope) {
|
|
scope sc {
|
|
sc.spawn(fn() { })
|
|
}
|
|
}
|
|
// ERROR (parse): = (자식 scope의 부모를 명시해야 합니다)
|
|
|
|
// 회복이 되었다는 증거: 이 마지막 선언은 정상적으로 읽혀야 한다.
|
|
pub fn fine(n: Int) -> Int {
|
|
n + 1
|
|
}
|