programing

간단한 (아마도 가장 간단한) C 컴파일러를 시작하는 것입니까?

css3 2023. 6. 14. 22:05

간단한 (아마도 가장 간단한) C 컴파일러를 시작하는 것입니까?

우연히 발견한 것은 다음과 같습니다.Turbo Pascal을 사용하여 컴파일러 작성

간단한 C 컴파일러를 만드는 방법을 설명하는 튜토리얼이나 참고 자료가 있는지 궁금합니다.제 말은, 제가 산술 연산을 이해할 수 있게 해준다면 충분하다는 것입니다.는 켄 톰슨의 이 기사를 읽고 정말 궁금증이 생겼습니다.그 자체를 이해할 수 있는 것을 쓴다는 생각은 신나는 것 같습니다.

왜 구글에 묻지 않고 이런 질문을 던졌을까요?저는 구글을 사용해봤는데 파스칼이 첫 번째 링크였습니다.나머지는 관련이 없어 보였고 거기에 더해...저는 CS 전공자가 아닙니다(그래서 저는 여전히 yacc와 같은 모든 도구들이 무엇을 하는지 배워야 합니다). 저는 이것을 하면서 배우고 싶고 더 많은 경험을 가진 사람들이 항상 구글보다 이러한 것들을 더 잘하기를 바랍니다.저는 제가 위에 나열한 것과 같은 정신으로 작성된 기사를 읽고 싶지만, 최소한 간단한 C 컴파일러를 구축하는 부트스트래핑 단계를 강조하는 기사를 읽고 싶습니다.

또한, 저는 배우는 가장 좋은 방법을 모릅니다.C 컴파일러를 C나 다른 언어로 빌드하는 것을 시작해야 합니까?제가 C 컴파일러를 쓰나요 아니면 다른 언어를 쓰나요?이런 질문들은 제가 탐구할 방향이 정해지면 더 잘 답할 수 있을 것 같습니다.좋은 의견이라도 있나?

좋은 의견이라도 있나?

컴파일러는 세 개의 조각으로 구성됩니다.

  1. 파서
  2. 추상 구문 트리(AST)
  3. 어셈블리 코드 생성기

언어 문법으로 시작하는 훌륭한 파서 생성자들이 많이 있습니다.ANTLR은 당신이 시작하기에 좋은 장소일 것입니다.C 루트를 고수하려면 lex/yacc 또는 bison을 사용해 보십시오.

C에 대한 문법이 있지만, 저는 C 전체가 복잡하다고 생각합니다.당신은 언어의 부분 집합으로 시작해서 당신의 발전을 위해 노력하는 것이 좋을 것입니다.

AST가 있으면 이를 사용하여 실행할 기계 코드를 생성합니다.

그것은 할 수 있지만, 사소한 것은 아닙니다.

저는 또한 아마존에서 컴파일러 쓰기에 대한 책을 확인할 것입니다.드래곤 북은 고전이지만, 더 현대적인 것들이 있습니다.

업데이트: 스택 오버플로에 대해 와 같은 유사한 질문이 있습니다.이러한 리소스도 확인하십시오.

이 튜토리얼을 추천합니다.

이것은 "작은 언어" 컴파일러를 구현하는 방법에 대한 작은 예시입니다.소스 코드는 매우 작고 단계별로 설명됩니다.

LLVM(프로그램의 내부 구조를 나타내는 Low Level Virtual Machine) 라이브러리를 위한 C 프런트엔드 라이브러리도 있습니다.

Tiny C 컴파일러는 상대적으로 작은 소스 패키지에 있는 꽤 완전한 기능을 갖춘 C 컴파일러입니다.예를 들어, GCC의 모든 소스 기반을 이해하는 것보다 훨씬 이해하기 쉬우므로 해당 소스를 연구하는 것이 도움이 될 수 있습니다.

이것은 제 생각입니다. (그리고 추측) 일반적으로 학부 컴퓨터 과학 수업에서 다루는 데이터 구조를 이해하지 않고 컴파일러를 작성하는 것은 어려울 것입니다.이는 링크된 목록 및 트리와 같은 필수 데이터 구조를 알아야 한다는 것을 의미하지는 않습니다.

(적어도 처음부터) 전체 또는 표준 준수 C 언어 컴파일러를 작성하는 대신 공통 연산자, 정수만 지원, 기본 함수 및 포인터와 같은 언어의 기본 하위 집합으로 제한하는 것을 제안합니다.이것의 한 고전적인 예는 1980년대에 Dr. Dobbs Journal에 쓰여진 일련의 기사들로 유명해진 Ron Cain의 Small-C였습니다.그들은 제임스 헨드릭스의 절판된 책인 A Small-C Compiler로 CD를 출판합니다.

제가 제안하고 싶은 것은 Crenshaw의 튜토리얼을 따르는 것이지만, C와 같은 언어 컴파일러와 당신이 목표로 삼고 싶은 CPU 대상(Crenshaw는 Motorola 68000 CPU를 대상으로 합니다.이렇게 하려면 컴파일된 프로그램을 실행할 대상의 기본 어셈블리를 알아야 합니다.여기에는 인텔 x86(16/32비트)의 CISC 명령어 집합보다 더 나은 어셈블리 명령어 집합인 68000 또는 MIPS용 에뮬레이터가 포함될 수 있습니다.

컴파일러/번역기 이론(및 실습)을 배우는 출발점으로 사용할 수 있는 많은 잠재적인 책들이 있습니다.comp.compilers FAQ와 다양한 온라인 책 판매자의 리뷰를 읽으십시오.대부분의 입문서들은 2학년부터 4학년까지 학부 컴퓨터 과학 수업을 위한 교재로 쓰여져 있기 때문에 CS 배경 없이 천천히 읽을 수 있습니다."드래곤"보다 더 소개적이지만 읽기 쉬운 오래된 책은 토마스 파슨스의 "컴파일러 구성 입문"입니다.그것은 오래된 것이기 때문에, 당신은 합리적인 가격에 당신이 선택한 온라인 책 판매자들로부터 중고 사본을 찾을 수 있을 것입니다.

그래서 저는 잭 크렌쇼의 "컴파일러를 만들자" 튜토리얼로 시작해서, 당신만의 것을 쓰고, 그의 예를 참고해서, 간단한 컴파일러의 기초를 만들어보세요.작업이 완료되면 해당 시점에서 작업할 위치를 더 잘 결정할 수 있습니다.

추가됨:

부트스트래핑 프로세스와 관련하여.기존 C 컴파일러를 무료로 사용할 수 있기 때문에 부트스트래핑에 대해 걱정할 필요가 없습니다.별도의 기존 도구(GCC, Visual C++ Express, Mingw / djpg, tcc)로 컴파일러를 작성하면 훨씬 더 늦은 단계에서 프로젝트 자체 컴파일에 대해 걱정할 수 있습니다.저는 이 질문의 이 부분에 놀랐습니다. 저는 당신이 컴파일러 부트스트래핑 과정으로 들어가는 켄 토마스의 ACM 튜링 상 수상 연설인 "신뢰에 대한 성찰"을 읽고 당신만의 컴파일러를 쓰는 아이디어를 얻었다는 것을 깨닫기 전까지요.이것은 절제된 고급 주제이며, 또한 매우 번거롭습니다.저는 C 컴파일러가 포함된 오래된 Unix 시스템(64비트 Alpha의 Digital OSF/1)에서 GCCC 컴파일러를 부트스트랩하는 것조차 느리고 시간이 많이 걸리고 오류가 발생하기 쉬운 프로세스라는 것을 알게 되었습니다.

다른 종류의 질문은 Yacc와 같은 컴파일러 도구가 실제로 무엇을 하는지였습니다.Yacc(GNU의 또 다른 컴파일러 컴파일러 또는 바이슨)는 컴파일러(또는 번역기) 파서를 더 쉽게 작성할 수 있도록 설계된 도구입니다.yacc에 입력한 대상 언어의 형식 문법을 기반으로 컴파일러 전체 설계의 한 부분인 파서를 생성합니다.다음은 어휘 분석기 또는 스캐너를 생성하는 데 사용되는 렉스(또는 GNU의 플렉스)로, 종종 yacc 생성 파서와 함께 사용되어 컴파일러 프런트 엔드의 골격을 형성합니다.이러한 도구를 통해 작성자는 어휘 분석기 및 구문 분석기를 직접 작성하는 것보다 프런트 엔드를 쉽게 사용할 수 있습니다.Crenshaw의 튜토리얼은 이러한 도구를 사용하지 않으며, 당신도 그럴 필요가 없습니다. 많은 컴파일러 작성자들이 항상 사용하는 것은 아닙니다.물론 크렌쇼는 튜토리얼의 파서가 상당히 기본적이라는 것을 인정합니다.

Crenshaw의 튜토리얼은 또한 AST(추상 구문 트리)를 생성하는 것을 건너뛰어 튜토리얼 컴파일러를 단순화하지만 제한하기도 합니다.모든 최적화는 아니지만 대부분 부족하며 컴파일러의 "백엔드"에 의해 방출되는 특정 프로그래밍 언어 및 특정 어셈블리 언어와 매우 관련이 있습니다.일반적으로 AST는 일부 최적화를 수행할 수 있는 중간 부분이며 설계에서 컴파일러 프런트엔드와 백엔드를 분리하는 역할을 합니다.컴퓨터 과학 경력이 없는 초보자의 경우, 첫 번째 컴파일러(또는 적어도 첫 번째 버전의 AST)에 대한 AST가 없는 것에 대해 걱정하지 않는 것이 좋습니다.작고 단순하게 유지하는 것이 컴파일러를 처음 버전으로 작성하는 데 도움이 될 것이며, 거기서 어떻게 진행할지 결정할 수 있습니다.

여러분은 아마도 The Elements of Computing Systems:라는 책/과정에 관심이 있을 것입니다.첫 번째 원칙에서 현대 컴퓨터 구축.

이것은 당신이 새로운 달걀에서 산 물건으로 "PC"를 만드는 것이 아닙니다.부울 논리 기초에 대한 설명으로 시작하여 가장 낮은 수준의 추상화에서 점진적으로 더 높은 수준의 추상화로 가상 컴퓨터를 구축합니다.강의 자료는 모두 온라인이며, 책 자체는 아마존에서 꽤 저렴합니다.

이 과정에서는 "하드웨어 구축" 외에도 어셈블러, 가상 머신, 컴파일러 및 기본 OS를 단계적으로 구현할 수 있습니다.이를 통해 다른 답변에 나열된 보다 일반적으로 권장되는 리소스 중 일부를 사용하여 주제 영역을 더 깊이 탐구할 수 있는 충분한 배경을 제공할 수 있을 것으로 생각합니다.

Unix Programming Environment에서 Kernighan과 Pike는 간단한 C 기반 어휘 분석 및 즉시 실행에서 추상 머신을 위한 yacc/lex 구문 분석 및 코드 생성에 이르기까지 계산기를 만드는 5번의 반복 과정을 거칩니다.그들이 너무 잘 쓰기 때문에 더 원활한 소개를 제안할 수 없습니다.그것은 확실히 C보다 작지만, 당신에게 유리할 것 같습니다.

간단한 C 컴파일러를 작성하려면 어떻게 해야 합니까?

C를 컴파일하는 것에는 간단한 것이 없습니다.가장 간단한 C 컴파일러는 크리스 프레이저와 데이비드 핸슨의 lcc입니다.그들은 10년 동안 디자인 작업을 하면서 가능한 한 단순하게 만들었지만, 여전히 상당히 좋은 코드를 생성했습니다.만약 당신이 대학 도서관에 접근할 수 있다면, 당신은 그들의 책을 얻을 수 있을 것입니다.

C 컴파일러를 C나 다른 언어로 빌드하는 것을 시작해야 합니까?

다른 언어.한 번은 핸슨에게 프레이저와 함께 lcc 프로젝트에 10년을 보내면서 어떤 교훈을 얻었는지 물었습니다.핸슨이 말한 주요한 것은

C는 컴파일러를 쓰기에 형편없는 언어입니다.

당신은 하스켈이나 ML의 방언을 사용하는 것이 더 낫습니다.두 언어 모두 대수 데이터 유형에 대한 함수를 제공하며, 이는 컴파일러 작성자가 직면한 문제와 완벽하게 일치합니다.만약 당신이 여전히 C를 추구하고 싶다면, 당신은 ML로 작성된 C 컴파일러의 큰 덩어리인 George Necula의 CIL로 시작할 수 있습니다.

위에 나열한 것과 같은 정신으로 작성된 기사를 읽고 싶지만 적어도 부트스트랩 단계를 강조하는 기사는...

당신은 켄의 것과 같은 다른 기사를 찾을 수 없을 것입니다.하지만 Andrew Appel은 Axiomatic Bootstraping: A Guide for Compiler Hackers라는 멋진 기사를 썼습니다. 무료 버전을 찾을 수 없었지만 많은 사람들이 ACM 디지털 라이브러리에 액세스할 수 있습니다.

좋은 의견이라도 있나?

만약 당신이 컴파일러를 쓰고 싶다면,

  • 구현 언어로 Haskell 또는 ML을 사용합니다.

  • 첫 번째 컴파일러의 경우 Niklaus Wirth의 책 Algorithms + Data Structures = Programs에서 Oberon 또는 P0과 같은 매우 간단한 언어를 선택합니다.Wirth는 컴파일하기 쉬운 언어를 설계하는 것으로 유명합니다.

번째 컴파일러를 위해 C 컴파일러를 작성할 수 있습니다.

컴파일러는 다음의 측면을 다루는 복잡한 주제입니다.

  • Lexing, Parsing을 포함한 입력
  • AST(Abstract Syntax Tree)와 같이 사용되는 모든 변수의 심볼 저장소 구축
  • AST 트리에서 구문을 기반으로 기계 코드 이진 파일을 전치하고 작성합니다.

이것은 산꼭대기에서 보는 추상적인 조감도이기 때문에 결코 포괄적이지 않습니다. 구문 표기법을 정확하게 하고 잘못된 입력이 그것을 버리지 않도록 하는 것으로 요약됩니다. 사실 좋은 입력 처리는 아무리 잘못된 입력, 끔찍하고 남용되는 경우에도 결코 무릎을 꿇어서는 안 됩니다.그리고 출력이 무엇인지 결정하고 알 때, 기계 코드로 출력이 되는지도 알 수 있습니다. 이는 프로세서 명령을 자세히 알아야 한다는 것을 의미합니다.변수에 대한 메모리 주소 지정 등을 포함합니다.

다음은 시작하기 위한 몇 가지 링크입니다.

  • 잭 크렌쇼의 코드 포트가 C로...(몇 달 전에 다운로드한 기억이 납니다...)
  • 여기 SO에 대한 비슷한 질문에 대한 링크가 있습니다.
  • 또한 Basic to x86 어셈블러 컴파일러를 위한 또 다른 소규모 컴파일러 튜토리얼이 있습니다.
  • 타이니 C 컴파일러
  • Hendrix의 Small C 컴파일러가 여기 있습니다.

기능적 프로그래밍에 대해 배우는 것도 가치가 있을 수 있습니다.기능적 언어는 컴파일러를 작성하는 데 적합합니다.우리 학교의 인트로 컴파일러 수업은 기능 언어에 대한 인트로가 포함되어 있었고 과제는 모두 OCaml로 되어 있었습니다.

며칠 전에 람다 미적분 해석기를 썼기 때문에 오늘 당신이 이것을 물어봐야 한다는 것이 재미있습니다.람다 미적분학은 모든 기능 언어의 할아버지입니다.그것은 단지 200줄 길이입니다 (C++, 포함).오류 보고, 일부 예쁜 인쇄, 일부 유니코드), 코드 생성에 사용할 수 있는 중간 형식의 2단계 구조를 가지고 있습니다.

소규모로 시작하여 컴파일러에 대한 가장 실용적인 접근 방식을 구축할 뿐만 아니라 우수한 모듈식 조직 관행을 장려합니다.

컴파일러는 매우 큰 프로젝트입니다. 시도해 보는 것이 나쁠 것은 없다고 생각합니다.

저는 파스칼로 작성된 C 컴파일러를 적어도 하나는 알고 있기 때문에, 그것은 당신이 할 수 있는 가장 미친 일이 아닙니다.저는 개인적으로 C 컴파일러 프로젝트를 구현하는 더 현대적인 언어를 선택하고 싶습니다. 단순성(Python, Ruby, C, C++ 또는 Java의 경우 d/l 패키지를 쉽게 할 수 있음)과 이력서에 더 잘 어울릴 것이기 때문입니다.

그러나 컴파일러를 초보 프로젝트로 수행하기 위해서는 Agile kool-aid를 모두 마셔야 합니다.

아무 것도 하지 않더라도 항상 무언가를 실행합니다.컴파일러에 내용을 작은 단계로만 추가합니다. ("자주 릴리스")언어의 하위 집합을 선택하여 먼저 구현합니다. (지원만 해당)i = 0;처음에는 그것들을 확장합니다.)

스스로 컴파일하는 컴파일러를 쓰는 방법을 알려주는 놀라운 경험을 원한다면 1964년의 이 논문을 읽을 필요가 있습니다.

META II는 Val Schorre가 작성한 구문 지향 컴파일러 언어입니다.

10페이지로 구성되어 있으며, 컴파일러 작성 방법, 메타 컴파일러 작성 방법, 가상 메타 컴파일러 명령어 세트 및 메타 컴파일러로 빌드된 샘플 컴파일러를 제공합니다.

저는 60년대 후반에 이 논문에서 컴파일러를 쓰는 방법을 배웠고, 그 아이디어를 사용하여 여러 미니 컴퓨터와 마이크로프로세서를 위한 C와 같은 언어를 만들었습니다.

논문 자체가 너무 많은 경우(그렇지 않습니다!) 전체 과정을 안내하는 온라인 튜토리얼이 있습니다.

또한 ACM 회원이 아니기 때문에 원본 링크에서 용지를 가져오는 것이 어색할 경우 튜토리얼에 모든 세부 정보가 포함되어 있다는 것을 알게 될 것입니다.(IMHO, 가격에 비해 종이 자체는 가치가 있습니다.)

10페이지!

구현할 언어로 C로 시작하거나 컴파일러-생성기 또는 파서-생성기 도구로 시작하는 것을 권장하지 않습니다.C는 매우 까다로운 언어이며, 자신만의 언어를 만드는 것이 아마도 더 나은 생각일 것입니다.약간 C와 유사할 수 있습니다(예: 함수 본문을 나타내려면 곱슬머리 백켓을 사용하고, 동일한 유형 이름을 사용하므로 모든 것을 기억할 필요가 없습니다).

컴파일러와 파서를 만드는 도구는 훌륭하지만, 실제로는 속기 표기법이라는 문제가 있습니다.만약 당신이 긴 손으로 컴파일러를 만드는 방법을 모른다면, 속기는 암호화되고 불필요하게 제한적으로 보일 것입니다.따라서 먼저 간단한 컴파일러를 작성한 다음 계속합니다.또한 어셈블러를 먹고 호흡하지 않는 한 실제 기계 코드 생성을 시작하지 않는 것이 좋습니다.VM을 사용하여 고유한 바이트 코드 인터프리터를 생성합니다.

첫 번째 컴파일러를 만들려면 어떤 언어를 사용해야 합니까?언어가 상당히 완전하다면, 그것은 사실 중요하지 않습니다.여러분은 입력 텍스트를 읽고, 그것들로부터 데이터 구조를 구축하고, 이진 데이터를 작성하게 될 것입니다.그래서 만약 어떤 언어가 그러한 것들을 어떤 식으로든 더 쉽게 만든다면, 그것은 그것에 찬성하는 점입니다.잘 아는 언어를 선택하면 언어를 배우는 것이 아니라 컴파일러를 만드는 데 집중할 수 있습니다.저는 주로 OO 언어를 사용하는데, 이것은 구문 트리를 더 쉽게 작성할 수 있게 해줍니다. 만약 당신이 그것에 익숙하다면 기능적인 언어도 작동할 것입니다.

저는 프로그래밍 언어에 대해 많은 블로그를 해왔기 때문에 여기에서 유용한 게시물을 찾을 수 있습니다: http://orangejuiceliberationfront.com/category/language-design/

특히, http://orangejuiceliberationfront.com/how-to-write-a-compiler/ 은 일반적인 구조를 구문 분석하고 이로부터 유용한 것을 생성하는 세부 사항에 대한 출발점이며, 실제로 무언가를 수행하는 인텔 명령어를 뱉어내는 것에 대해 이야기하는 http://orangejuiceliberationfront.com/generating-machine-code-at-runtime/ 도 있습니다.

오, 컴파일러의 부트스트랩과 관련하여:아마 처음부터 제대로 할 수 없을 것입니다.컴파일러를 만드는 데는 상당한 양의 작업이 수반됩니다.따라서 부트스트래핑 컴파일러를 작성하는 것은 컴파일러를 작성하는 것뿐만 아니라 컴파일러가 있으면 자체를 사용하여 두 번째 버전의 컴파일러를 작성해야 합니다.이는 작업량의 두 배에 기존 컴파일러와 부트스트랩된 새 컴파일러가 모두 작동할 때까지 필요한 디버깅 기능을 더한 것입니다.즉, 일단 작동하는 컴파일러를 가지고 있으면 완전성을 테스트하는 좋은 방법입니다.좋아요, 아마 두 배가 아니라 더 많은 일을 할 겁니다.저는 쉬운 성공을 위해 먼저 노력하고, 그 다음에 거기서부터 계속할 것입니다.

어쨌든, 재미있게 놀아요!

언급URL : https://stackoverflow.com/questions/2349468/starting-off-a-simple-the-simplest-perhaps-c-compiler