부트 스트랩에는 여전히 외부 지원이 필요합니다.


96

나는 언어를 부트 스트랩하는 아이디어, 즉 언어 자체에 대한 컴파일러 / 인터프리터를 작성한다는 생각을 들었습니다. 나는 이것이 어떻게 이루어 질 수 있는지 궁금해하고 약간 둘러 보았고 누군가가 그것을 할 수 있다고 말하는 것을 보았습니다.

  • 다른 언어로 초기 컴파일러 작성.
  • 처음의 특별한 경우처럼 보이는 Assembly에서 초기 컴파일러를 직접 코딩

나에게 이들 중 어느 것도 외부 지원이 필요하다는 의미에서 실제로 언어를 부트 스트랩 하는 것처럼 보이지 않습니다 . 실제로 자체 언어로 컴파일러를 작성하는 방법이 있습니까?


나는 그런 것들에 대해 그다지 경험이 없지만 초기 컴파일러는 다른 언어로 작성되어야 한다고 가정 할 것입니다. 나는 컴파일러 참조에서 "부트 스트랩은"단순히 기록을 의미하는 것이 매우 확신 가 작성되지 컴파일을 의미있어 언어의 언어 컴파일러를 첫 번째 가 컴파일 의미있어 언어의 언어에 대한 컴파일러.
JDD

1
정보 주셔서 감사합니다. 처음에는 제한된 컴파일러를 작성하고 그 위에 빌드하는 아이디어로 설명 할 때 부트 스트랩의 아이디어가 더 합리적입니다. 이번 학기에 Compilers 수업을 듣고 있는데, 이는 Steve Yegge의 Compilers에서 수업이 얼마나 중요한지에 대한 게시물의 영향을 많이 받았으며 , 방금 Amazon 링크에서 Dragon 책을 구입했습니다.
pbh101 2008-08-17

1
유사한 질문도 참조하십시오 : 컴파일러 자체 구현
Urban Vagabond 2013

답변:


107

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

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

당신이 경우 Yazzleof위한 컴파일러를 부트 스트랩 것, 당신은 일반적으로 초기에 전체 언어의 컴파일러를 쓸 것입니다. 대신 당신은 Yazzle 라이트의 Yazzleof의 가장 작은 부분 집합 (음,에 대한 컴파일러 작성합니다 아주 작은을 적어도 하위 집합). 그런 다음 Yazzle-lite에서 전체 언어에 대한 컴파일러를 작성합니다. (분명히 이것은 한 번의 점프 대신 반복적으로 발생할 수 있습니다.) Yazzle-lite는 Yazzleof의 적절한 하위 집합이므로 이제 자체적으로 컴파일 할 수있는 컴파일러가 있습니다.

정말 제목 (현대 컴퓨터에 기본적으로 16 진수 편집기입니다) 가능한 한 가장 낮은 수준에서 컴파일러를 부트 스트랩에 대한 좋은 작성자 아무것도에서 간단한 컴파일러 부트 스트랩은 . https://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html 에서 찾을 수 있습니다 .


19

읽은 설명이 정확합니다. Compilers : Principles, Techniques and Tools (the Dragon Book) 에서 이에 대한 논의가 있습니다 .

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

7

이것에 대한 매우 흥미로운 토론은 Unix 공동 제작자 Ken ThompsonTuring Award 강의입니다.

그는 다음으로 시작합니다.

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

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

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


9
이것은 주제에서 벗어난 것입니다 .. 흥미롭지 만 혼란스럽고 질문에 대한 대답이 아닙니다.
blueshift 2012 년

5

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

이것이 부트 스트랩 의 정의입니다 .

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

편집 : 컴파일러 부트 스트랩에 대한 Wikipedia 기사 는 저보다 개념을 더 잘 다루고 있습니다.



4

Donald E. Knuth는 실제로 그 안에 컴파일러를 작성하여 WEB 을 구축 한 다음이를 어셈블리 또는 기계 코드로 직접 컴파일했습니다.


3

내가 알기로 첫 번째 Lisp 인터프리터는 생성자 함수와 토큰 리더를 직접 컴파일하여 부트 스트랩되었습니다. 나머지 통역사는 소스에서 읽어 들였습니다.

원본 McCarthy 논문, 기호 표현의 재귀 함수 및 기계에 의한 계산, Part I 을 읽고 직접 확인할 수 있습니다 .


파트 2와 3은 어떻게 되었나요? ... @Wing이 나보다 3 년 전에 똑같은 글을 올린 것을 어떻게 알지 못했습니까? 나는 바보입니다. 적어도 나는 (도움으로) 논문을 연결했습니다.
LUSER는 droog

2

또 다른 대안은 해당 언어에 대한 바이트 코드 머신을 생성하고 (또는 기능이 매우 드물지 않은 경우 기존 머신을 사용) 바이트 코드 또는 다른 중간 언어를 사용하여 원하는 언어로 컴파일러를 작성하는 것입니다. AST를 XML로 출력 한 다음 XSLT (또는 다른 패턴 일치 언어 및 트리 기반 표현)를 사용하여 XML을 바이트 코드로 컴파일하는 파서 툴킷. 다른 언어에 대한 종속성을 제거하지는 않지만 더 많은 부트 스트랩 작업이 최종 시스템에서 끝날 수 있음을 의미 할 수 있습니다.


2

그것은 닭과 달걀의 역설의 컴퓨터 과학 버전입니다. 어셈블러 나 다른 언어로 초기 컴파일러를 작성하지 않는 방법을 생각할 수 없습니다. 할 수 있었다면 Lisp가 할 수 있었어야 했어요.

사실 Lisp가 거의 자격이 있다고 생각합니다. Wikipedia 항목을 확인하십시오 . 기사에 따르면 Lisp eval 함수는 기계 코드 로 IBM 704 에서 구현 될 수 있으며 완전한 컴파일러 (Lisp 자체로 작성 됨)가 1962 년에 MIT에서 제공 됩니다.


2

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

어떻게 작동할까요? 다른 방법으로는 개념적으로도 가능하지 않다고 생각합니다.


4
적어도 첫 번째 Lisp 컴파일러는 기존 Lisp 인터프리터를 사용하여 부트 스트랩되었습니다 . 따라서 의미 상 다른 언어가 아니라 다른 언어 구현입니다.
Ken

0

일부 부트 스트랩 컴파일러 또는 시스템은 소스 양식과 객체 양식을 저장소에 모두 보관합니다.

  • ocaml 은 바이트 코드 인터프리터 (즉, Ocaml 바이트 코드에 대한 컴파일러)와 네이티브 컴파일러 (x86-64 또는 ARM 등 ... 어셈블러)를 모두 가진 언어입니다. svn 저장소에는 컴파일러 의 소스 코드 (files */*.{ml,mli})와 바이트 코드 (file boot/ocamlc) 형식이 모두 포함되어 있습니다 . 따라서 빌드 할 때 먼저 (이전 버전의 컴파일러의) 바이트 코드를 사용하여 자체적으로 컴파일합니다. 나중에 새로 컴파일 된 바이트 코드는 네이티브 컴파일러를 컴파일 할 수 있습니다. 따라서 Ocaml svn 저장소에는 *.ml[i]소스 파일과 boot/ocamlc바이트 코드 파일 이 모두 포함되어 있습니다 .

  • (사용 컴파일러 다운로드 wget이진의 이전 버전을 사용하면 작업 인터넷 연결이 필요하므로이) 자체를 컴파일합니다.

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

  • J.Pitrat의 CAIA 인공 지능 시스템은 완전히 자체 생성됩니다. 수천 개의 데이터 파일 모음과 함께 [A-Z]*.c생성 된 수천 개의 파일 모음 (생성 된 dx.h헤더 파일 포함)으로 사용할 _[0-9]*수 있습니다.

  • 여러 Scheme 컴파일러도 부트 스트랩됩니다. 구성표 48, 치킨 구성표, ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.