- 1988~1995년에 발표된 Jack Crenshaw의 ‘Let’s Build a Compiler’ 튜토리얼을 Python과 WebAssembly로 재구현한 프로젝트
- 원본은 Pascal과 Motorola 68000 어셈블리를 사용했지만, 이번 작업에서는 현대적 환경에서 실행 가능한 코드로 변환
- 튜토리얼의 핵심은 재귀 하강 파서(recursive-descent parser) 를 직접 구현하고, 초기 단계부터 실제 어셈블리 코드를 생성하는 접근
- Crenshaw의 방식은 문법 지시적 번역(syntax-directed translation) 을 사용하지만, 타입 처리 단계에서 한계를 드러냄
- 이번 재구현은 고전 튜토리얼을 현대 개발자들이 직접 실행하고 실험할 수 있는 형태로 복원한 점에서 의의가 있음
고전 튜토리얼의 배경
- Jack Crenshaw의 ‘Let’s Build a Compiler’ 는 1988~1995년 사이에 발표된 컴파일러 제작 입문서로, 지금도 자주 언급되는 자료
- 원문은 Pascal로 작성되었고, Motorola 68000 어셈블리 코드를 출력
- 35년이 지난 2025년에도 Hacker News 등에서 꾸준히 회자됨
- 글 작성자는 2003년에 이 튜토리얼을 처음 접하고 깊은 인상을 받았으며, 2025년에 다시 이를 Python과 WebAssembly로 옮김
Python 및 WebAssembly로의 재구현
- 단순히 읽는 것에 그치지 않고, 튜토리얼의 컴파일러를 Python으로 번역하고 WebAssembly(WASM) 를 출력하도록 구현
- 결과물은 GitHub 저장소(eliben/letsbuildacompiler)에 공개
-
TUTORIAL.md 파일에서 원본 각 파트가 Python 코드로 어떻게 매핑되는지 설명
- 사용자는 원본 튜토리얼을 읽으며 직접 실행 가능한 코드를 실험 가능
KISS 언어 예제와 WASM 출력
- Crenshaw가 설계한 KISS 언어의 예제 프로그램을 Python 버전 컴파일러로 컴파일한 결과를 제시
- 예제는 procedure, while 루프, 값 전달 및 참조 전달을 포함
- 출력된 WASM 텍스트는 참조 매개변수(by-reference parameter) 처리 로직을 포함하며, 최적화는 거의 적용되지 않음
- 전역 변수 X가 main 함수에서 암묵적으로 반환되는 부분은 테스트 편의를 위한 장치
- 생성된 WASM 코드는 실제 실행을 통해 예상 결과를 검증하는 테스트에 사용됨
튜토리얼의 강점
- Crenshaw의 튜토리얼은 재귀 하강 파서를 단계적으로 구축하며, 복잡한 이론보다 직접 작동하는 코드 생성에 초점을 맞춤
- 당시에는 lex와 yacc가 표준으로 여겨졌으나, 직접 작성한 파서의 단순성과 명료함이 큰 영향을 줌
- 이후 20년간 작성자는 수동 재귀 하강 파서를 선호하게 됨
- 또한 대부분의 강의가 구문 분석에 치중하던 시절, Crenshaw는 초기 단계부터 어셈블리 코드 생성을 다룸
한계와 개선 가능성
- 튜토리얼은 문법 지시적 번역(syntax-directed translation) 방식을 사용해 파싱 중 바로 코드를 생성
- 이 접근은 학습에는 유용하지만, 타입 정보를 사전에 알 수 없어 최적화가 어렵다는 한계 존재
- 특히 타입이 도입되는 14부 이후에는 중간 표현(IR)이나 AST를 활용한 구조적 접근이 필요함이 드러남
- Crenshaw가 14부 이후 튜토리얼을 중단한 이유는 명시되지 않았으나, 이 한계와 관련이 있을 가능성 언급
- 작성자는 14부를 전환점으로 삼아 AST 생성 후 타입 검사 및 코드 생성을 수행하는 접근이 더 적합하다고 평가
결론
- 원본 튜토리얼은 여전히 컴파일러 제작 입문서로서 탁월한 가독성과 실용성을 유지
- 이번 Python·WASM 버전은 현대 개발자들이 구식 기술 없이 학습할 수 있도록 보완한 구현
- GitHub 저장소를 통해 누구나 실험 가능하며, 컴파일러 구조를 직접 체험할 수 있는 현대적 재해석으로 평가됨