문제

나는 언어 부트스트래핑, 즉 언어 자체에 대한 컴파일러/인터프리터를 작성한다는 아이디어를 들었습니다.나는 이것이 어떻게 이루어질 수 있는지 궁금해서 조금 둘러보았고, 누군가가 두 사람 중 한 사람만이 이 일을 할 수 있다고 말하는 것을 보았습니다.

  • 다른 언어로 초기 컴파일러를 작성합니다.
  • 어셈블리에서 초기 컴파일러를 직접 코딩하는 것은 첫 번째 컴파일러의 특별한 경우처럼 보입니다.

내가 보기엔 둘 다 실제로는 아닌 것 같아 부트스트래핑 둘 다 외부 지원이 필요하다는 점에서 언어입니다.실제로 자신의 언어로 컴파일러를 작성하는 방법이 있습니까?

도움이 되었습니까?

해결책

실제로 자신의 언어로 컴파일러를 작성하는 방법이 있습니까?

가지다 새 컴파일러를 작성하기 위한 기존 언어가 있어야 합니다.새로운 C++ 컴파일러를 작성하는 경우 먼저 C++로 작성하고 기존 컴파일러로 컴파일하면 됩니다.반면에 Yazzleof라는 새로운 언어용 컴파일러를 만드는 경우 먼저 다른 언어로 새 컴파일러를 작성해야 합니다.일반적으로 이는 또 다른 프로그래밍 언어이지만 반드시 그럴 필요는 없습니다.어셈블리일 수도 있고 필요한 경우 기계어 코드일 수도 있습니다.

만약 너라면 ~이었다 Yazzleof용 컴파일러를 부트스트랩하려고 하면 일반적으로 처음에는 전체 언어에 대한 컴파일러를 작성하지 않을 것입니다.대신 Yazzleof의 가능한 가장 작은 하위 집합인 Yazzle-lite용 컴파일러를 작성하게 됩니다. 꽤 작다 적어도 하위 집합).그런 다음 Yazzle-lite에서 전체 언어에 대한 컴파일러를 작성합니다.(분명히 이것은 한 번 점프하는 대신 반복적으로 발생할 수 있습니다.) Yazzle-lite는 Yazzleof의 적절한 하위 집합이므로 이제 자체적으로 컴파일할 수 있는 컴파일러를 갖게 되었습니다.

이있다 정말 가능한 가장 낮은 수준(현대 기계에서는 기본적으로 16진수 편집기임)에서 컴파일러를 부트스트래핑하는 방법에 대한 좋은 글입니다. 무(無)에서 간단한 컴파일러 부트스트래핑.다음에서 찾을 수 있습니다. https://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html.

다른 팁

당신이 읽은 설명이 정확합니다.이에 대한 논의가 있습니다. 컴파일러:원리, 기술 및 도구 (드래곤북):

  • 언어 X에 대한 컴파일러 C1을 언어 Y로 작성합니다.
  • 컴파일러 C1을 사용하여 언어 X에 대한 컴파일러 C2를 언어 X로 작성합니다.
  • 이제 C2는 완전한 자체 호스팅 환경입니다.

매우 흥미로운 이것에 대한 토론 Unix 공동 제작자에 있습니다. 켄 톰슨'에스 튜링상 강의.

그는 다음과 같이 시작합니다.

내가 설명하려는 것은 컴파일러가 자신의 언어로 작성될 때 발생하는 많은 "닭과 달걀" 문제 중 하나입니다.이러한 편의를 위해 C 컴파일러의 특정 예를 사용하겠습니다.

C 컴파일러가 로그인 프로그램을 인식하고 특수 코드를 추가하기 때문에 항상 비밀번호 없이 로그인할 수 있는 Unix C 컴파일러 버전을 어떻게 작성했는지 보여줍니다.

두 번째 패턴은 C 컴파일러를 대상으로 합니다.대체 코드는 두 트로이 목마를 모두 컴파일러에 삽입하는 1단계 자체 복제 프로그램입니다.이를 위해서는 2단계 예시와 같은 학습 단계가 필요합니다.먼저 수정된 소스를 일반 C 컴파일러로 컴파일하여 버그가 있는 바이너리를 생성합니다.우리는 이 바이너리를 공식 C로 설치합니다.이제 컴파일러 소스에서 버그를 제거할 수 있으며 새 바이너리는 컴파일될 때마다 버그를 다시 삽입합니다.물론 로그인 명령은 소스 어디에서도 추적되지 않고 버그가 있는 상태로 유지됩니다.

내가 들어본 방법은 극도로 제한된 컴파일러를 다른 언어로 작성한 다음 이를 사용하여 새 언어로 작성된 더 복잡한 버전을 컴파일하는 것입니다.그런 다음 이 두 번째 버전을 사용하여 자체 컴파일하고 다음 버전을 컴파일할 수 있습니다.컴파일될 때마다 마지막 버전이 사용됩니다.

이것이 정의이다 부트스트래핑:

동일한 목적을 수행하는 더 복잡한 시스템을 활성화하는 간단한 시스템의 프로세스입니다.

편집하다:그만큼 컴파일러 부트스트래핑에 관한 Wikipedia 기사 나보다 개념을 더 잘 다룬다.

팟캐스트를 확인하세요 소프트웨어 엔지니어링 라디오 61회 (2007-07-06) GCC 컴파일러 내부와 GCC 부트스트랩 프로세스를 논의합니다.

도널드 E.크누스 실제로 지어진 편물 컴파일러를 작성한 다음 어셈블리나 기계어 코드로 직접 컴파일합니다.

제가 이해한 바로는 첫 번째 리스프 인터프리터는 생성자 함수와 토큰 판독기를 직접 컴파일하여 부트스트랩되었습니다.그런 다음 통역사의 나머지 부분을 소스에서 읽어 들였습니다.

McCarthy 논문 원본을 읽어보시면 직접 확인하실 수 있습니다. 기호 표현식의 재귀적 기능과 기계에 의한 계산, 1부.

또 다른 대안은 귀하의 언어에 대한 바이트코드 기계를 생성하고(또는 기능이 그다지 특이하지 않은 경우 기존 기계를 사용함) 바이트코드 또는 다른 중간체(예: AST를 XML로 출력하는 파서 툴킷을 사용하고 XSLT(또는 다른 패턴 일치 언어 및 트리 기반 표현)를 사용하여 XML을 바이트코드로 컴파일합니다.다른 언어에 대한 종속성을 제거하지는 않지만 더 많은 부트스트래핑 작업이 최종 시스템에서 종료된다는 의미일 수 있습니다.

이는 닭고기와 달걀의 역설을 컴퓨터 과학으로 표현한 것입니다.초기 컴파일러를 어셈블러나 다른 언어로 작성하지 않는 방법은 생각나지 않습니다.그것이 가능했다면 Lisp도 그렇게 할 수 있었을 것입니다.

사실, 나는 Lisp가 거의 자격이 있다고 생각합니다.확인해 보세요 Wikipedia 항목.기사에 따르면 Lisp 평가 기능은 다음에서 구현될 수 있습니다. IBM 704 1962년에 완전한 컴파일러(Lisp 자체로 작성됨)가 등장하면서 기계어 코드로 MIT.

내가 생각할 수 있는 언어 부트스트래핑의 모든 예(, 파이파이)은 작동하는 컴파일러가 있는 후에 수행되었습니다.어딘가에서 시작해야 하며, 언어 자체를 다시 구현하려면 먼저 다른 언어로 컴파일러를 작성해야 합니다.

또 어떻게 작동할까요?그렇지 않으면 개념적으로는 불가능하다고 생각합니다.

일부 부트스트랩 컴파일러 또는 시스템은 저장소에 소스 형식과 개체 형식을 모두 유지합니다.

  • ocaml 바이트코드 해석기(예:Ocaml 바이트코드에 대한 컴파일러) 및 기본 컴파일러(x86-64 또는 ARM 등에 대한 컴파일러)어셈블러).svn 저장소에는 소스 코드(파일 */*.{ml,mli}) 및 바이트코드(파일 boot/ocamlc) 컴파일러의 형태.따라서 빌드할 때 먼저 바이트코드(이전 버전의 컴파일러)를 사용하여 자체 컴파일합니다.나중에 새로 컴파일된 바이트코드는 네이티브 컴파일러를 컴파일할 수 있습니다.따라서 Ocaml svn 저장소에는 두 가지가 모두 포함되어 있습니다. *.ml[i] 소스 파일과 boot/ocamlc 바이트코드 파일.

  • 그만큼 컴파일러 다운로드(사용 wget, 따라서 작동하는 인터넷 연결이 필요합니다) 자체적으로 컴파일하려면 이전 버전의 바이너리가 필요합니다.

  • 녹다 사용자 정의하고 확장할 수 있는 Lisp와 유사한 언어입니다. GCC.이는 부트스트랩 변환기에 의해 C++ 코드로 변환됩니다.생성된 변환기의 C++ 코드는 배포되므로 svn 저장소에는 두 가지가 모두 포함됩니다. *.melt 소스 파일과 melt/generated/*.cc 번역기의 "객체" 파일.

  • J.피트랏의 CAIA 인공지능 시스템은 전적으로 스스로 생성됩니다.수천 개의 컬렉션으로 제공됩니다. [A-Z]*.c 생성된 파일(생성된 파일도 포함) dx.h 헤더 파일)에 수천 개의 컬렉션이 포함되어 있습니다. _[0-9]* 데이터 파일.

  • 여러 Scheme 컴파일러도 부트스트랩됩니다.Scheme48, 치킨 스킴, ...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top