4

나는 이터레이터를 한동안 사용 해왔고, 나는 그들을 사랑한다.반복기를 인식하는 컴파일러는 어떻게 구현 될 수 있습니까?

그러나 나는 그것에 대해 열심히 생각했지만 "반복기를 인식하는 컴파일러가 어떻게 구현되는지"를 파악할 수 없었습니다. 나는 또한 그것에 대해 연구했지만 컴파일러 디자인 컨텍스트에서 상황을 설명하는 리소스를 찾을 수 없습니다.

반복자에 대한 대부분의 기사에는 원하는 동작을 구현하는 일종의 '마법'이 있음을 암시합니다. 그들은 컴파일러가 실행 상태 (마지막 '수익률 반환'이 표시되는 곳)를 수행하기 위해 상태 시스템을 유지 관리 할 것을 제안합니다. 저는 게으른 평가를 가능하게하는 반복자의이 속성에 특히 관심이 있습니다.

그런데, 나는 상태 머신이 무엇인지 알고, 이미 컴파일러 디자인 과정을 밟았으며, 드래곤 북을 공부했다. 그러나 분명히, 나는 내가 배운 것을 csc의 '마법'과 관련시킬 수 없다.

지식이나 차별화 된 의견을 보내 주시면 감사하겠습니다.

+0

조금 더 설명 할 수 있습니까? 예를 들어 컴파일러가 인식하기가 매우 어려울 것으로 생각되는 소스 코드 예를 들어 보겠습니다. – Thilo

+0

그리고 당신이 말하는 언어 - 예를 들어 "yeild"는 무엇을합니까? –

+0

C#에 "수익률 반환"구문이 있습니다. –

답변

5

더 간단합니다. 컴파일러는 반복자 함수를 개별 청크로 분해 할 수 있습니다. 청크는 yield 문장으로 나뉩니다.

상태 시스템은 현재 어떤 청크인지 추적해야하며 다음 반복기 호출시이 청크로 바로 이동합니다. 또한 모든 지역 변수를 추적해야합니다 (물론).

그런 다음 몇 가지 특별한 경우, 특히 yield을 포함하는 루프를 고려해야합니다. 다행히도 IL (그러나 C# 자체는 아님)은 goto루프로 이동하여 루프로 다시 시작하고 다시 시작할 수 있습니다.

매우 복잡한 가장자리 경우가 있음을 알 수 있습니다. C#은 yieldfinally 블럭에 허용하지 않습니다. (불가능합니까?) yield에 함수를 남겨두고 나중에 함수를 다시 시작하고 정리를 수행 한 다음 임의의 예외를 다시 throw합니다. 스택 추적을 보존합니다.

Eric Lippert가 in-depth description 프로세스를 게시했습니다. (그가 링크 한 기사도 읽어보십시오!)

1

C#에서 간단한 예제를 작성하고 컴파일 한 다음 반사판을 사용하는 것이 좋습니다. 이 "yield return"은 구문 설탕 일 뿐이므로 컴파일러가 디스어셈블러의 출력에서이를 어떻게 처리하는지 볼 수 있어야합니다.

하지만 사실 이런 것들에 대해 많이 알지 못해서 완전히 잘못되었습니다.

관련 문제