왜 C ++가 컴파일러를 작성해야합니까?


14

왜 C ++이 컴파일러를 작성하기에 좋은 선택인지 궁금했습니다. 물론 많은 컴파일러가 C 또는 C ++로 작성되었지만 이번에는 C ++에 더 관심이 있기 때문에 C도이 목적에 적합합니다. 좋은 이유가 있습니까? 나는 인터넷에서 그것을 찾고 있었지만 좋은 이유를 찾을 수 없습니다.


3
"많은 컴파일러들이 C ++로 작성되었습니다 ...] 어느 것? C ++이 다른 일반적인 언어보다 컴파일러 구성에 더 자주 사용된다고 생각하는 이유는 무엇입니까?
Doc Brown

6
@DocBrown 그럼, 연타 및 MSVC가 지금에 C ++의 비트 GCC, ++ 대부분은 C로 작성되어, 자바 JVM은 C로 작성되어 ++ stackoverflow.com/questions/410320/what-is-java-written-in 도하고 수퍼 유저가됩니다. com / questions / 136136 /…
Klaim

@DocBrown DMD D에 대한 참조 컴파일러는 C ++로 작성되었습니다
ratchet freak

3
누가 좋은 선택이라고합니까 ??
Phil

1
@ 필 당신은 그들이 대안을 고려하지 않고이 선택을했다고 생각합니까? "좋은"선택이 아니라 "효율적인"선택입니다.
Klaim

답변:


24

C ++에는 두 가지 측면이 있습니다. 저수준 개발 측면을 가지고있어 코드 생성과 같은 저수준 일을하는 데 자연스러운 언어처럼 보입니다. 또한 높은 수준의 측면 (C는 그렇지 않음)을 사용하여 복잡한 응용 프로그램 (컴파일러와 같은)을 논리적 객체 지향 방식으로 구성하면서 성능을 계속 유지할 수 있습니다. 낮은 수준과 높은 수준의 측면을 모두 가지고 있기 때문에 낮은 수준의 기능이나 성능이 필요한 대규모 응용 프로그램에 적합합니다.


11
컴파일러 내부의 많은 논리가 기능적 특성 (복잡한 데이터 구조를 다른 데이터 구조로 변환)이라는 것을 알기 때문에 객체 지향 기능 (대규모 프로그래밍을보다 대상으로 함)이 확실하지 않습니다. , 아키텍처 측면)은 절차 적 프로그래밍 스타일로 컴파일러 구성에 실질적 이점을 제공합니다. 그냥 내 2 센트.
조르지오

5
@Giorgio 객체를 갖는 것은 컴파일러 작성의 다른 많은 측면에서 도움이됩니다. 예를 들어, 최적화 할 때 컴파일러가 처리해야하는 상태가 많으며 이러한 종류의 작업은 OOP에 적합합니다. 또한 OOP 및 함수형 프로그래밍은 상당히 보완적일 수 있으므로 알고리즘이 대부분 기능적 일 수 있다고해서 개체가 도움이되지 않는다는 의미는 아닙니다.
Oleksi

3
@Giorgio와 Oleksi : 둘 다 확인할 수 있습니다. 하스켈과 함께 실제 언어로 컴파일러를 작성했습니다. 정말 잘 맞았습니다. 그러나 때때로 나는 주변의 OO를 놓쳤다. 다른 컴파일러를 작성해야한다면 분명히 Haskell을 선택해야하지만 이것은 실제로 특별한 경우입니다. 다른 유형의 프로젝트에 주저없이 Haskell을 선택하지 않겠습니다.
scarfridge

27
코드 생성을 수행하기 위해 "낮은 수준의 언어"가 필요한 이유는 무엇입니까? 이 두 가지가 어떤 식으로 연결되어 있는지 알 수 없습니다.
phant0m

5
일본어 텍스트를 파일에 쓸 수있는 유니 코드 식별자 보다 코드 생성을 위해 "낮은 수준"이 필요하지 않습니다 .
dan04

17

내 경험이 여기에 당신의 전제에 동의하지 않습니다. 사실, 고급 범용 언어의 경우 소스 언어 (컴파일되는 언어)와 동일한 언어로 컴파일러를 작성하는 것이 일반적 입니다. 예를 들면 다음과 같습니다.

  • Sun의 Java 컴파일러는 Java로 작성되었습니다
  • 스칼라 컴파일러는 스칼라로 작성되었습니다
  • Mono의 C # 컴파일러는 C #으로 작성되었습니다.
  • 스퀵의 스몰 토크 컴파일러는 스몰 토크로 작성되었습니다
  • ... 그리고 더 많은

예외는 GCC, LLVM 또는 Polyglot과 같은 기존 컴파일러 프레임 워크 용으로 작성된 컴파일러 프론트 엔드이며 프레임 워크 언어로 작성된 컴파일러 또는 Yacc와 같은 기존 파서 생성기를 사용하는 컴파일러입니다. GCC, LLVM 및 Yacc는 C 및 C ++로 작성된 일반적이고 확립 된 도구이므로 컴파일러 작성자가이를 사용하도록 인센티브를 제공하므로 C 및 C ++가 컴파일러 구현 언어 배포에서 큰 비중을 차지하게됩니다.


2
필자는 컴파일러를 잘 아는 사람들이 객관적인 기술적 이유보다 컴파일러를 작성하는 언어를 좋아하는 사람들과 훨씬 더 관련이 있다고 생각합니다.
토마스 보니 니

1
@Krelp 객관적인 기술적 이유가 아니라는 점에 동의하지만, 실제로는 "적합"하지도 않습니다. 언어에 대한 통과 의례로 간주 될뿐입니다. 컴파일러".
Oak

1
Sun의 Java 컴파일러는 C ++로 작성되었습니다. stackoverflow.com/questions/410320/what-is-java-written-in
Klaim

12
@Klaim 두 제품을 혼동하고 있습니다. 하나는 javacJava를 Java 바이트 코드로 컴파일하는 Sun의 Java 컴파일러 ( 명령 줄)입니다. Java로 작성되었습니다. 여러 번 직접 수정 했으며 Java 소스를 온라인으로 찾아 볼있습니다 . 다른 하나는 핫스팟 JVM에 내장 된 JIT (Just-In-Time) 컴파일러입니다.이 컴파일러는 Java 바이트 코드 를 기본 머신 코드로 컴파일합니다 . 대부분의 JVM과 마찬가지로 C ++로 작성되었지만 Java 컴파일러 는 아닙니다. 실제로 Java 언어에 대해서는 아무것도 모릅니다.
Oak

@ 오크, 절대적으로 맞습니다! 즉, JVM = javac의!
폴 드레이퍼

6

무엇을 무엇으로 컴파일하려면? 컴파일러는 소스 코드를 한 언어 (원본 언어) 에서 다른 언어 (대상 언어)로 변환하는데, 이는 대상 언어의 저수준에 대해서는 아무 것도 나타내지 않습니다.

  • CoffeeScript 는 JavaScript로 컴파일되며, 컴파일러는 CoffeeScript로 작성됩니다.
  • Script #은 C #을 JavaScript로 컴파일합니다. 컴파일러는 C #을 잘 기억하고 있습니다.
  • 기타

컴파일러를 작성하기 위해 선택한 언어는 상황에 따라 다릅니다. 예를 들어, PHP에서 파생 된 언어를 기본 PHP 코드로 컴파일하는 프로젝트를 작업하면서 PHP와 C #을 혼합하여 컴파일러를 작성했습니다. 다른 사람은 Python, Java 및 PHP 또는 C ++을 약간의 JavaScript 또는 기타로 선택합니다.

C 또는 C ++는 컴파일러 관련 도구 (Telastyn의 답변 참조)를 지원하고이 두 언어를 사용하면 실제로 네이티브로 이동할 수 있기 때문에 널리 사용됩니다. 그러나 다른 언어를 선택하는 데 아무런 문제가 없습니다.

좀 더 괴상 하기 위해 컴파일러 자체를 작성하기 위해 소스 언어를 선택할 수 있습니다. CoffeeScript 컴파일러와 다른 많은 컴파일러에서 일어난 일입니다. IDE에도 인기가 있습니다. 첫 번째 Visual Studio 중 하나는 동일한 Visual Studio를 사용하여 빌드되었습니다.


5
자체 호스팅은 괴짜가 아니며 컴파일러를 이식하는 데 중요한 속성입니다.

5
그 이유는 컴파일러 자체를 즉시 테스트 프로그램으로 만들 수 있기 때문입니다. 그것은 아마도 그 컴파일러에게 가장 큰 프로그램 일 것입니다.

6

나는 여기서 기본적인 전제에 의문을 갖는 경향이있다. C와 C ++는 컴파일러 작성에 완벽하게 작동하지만 다른 언어들도이 작업에 완벽하게 작동하는 것 같습니다.

약간은 컴파일하는 언어에 따라 다릅니다. 작고 간단한 언어의 경우 C와 Pascal이 잘 작동합니다. 크고 복잡한 것을 컴파일하려는 경우 컴파일러도 크고 복잡해집니다.이 경우 더 큰 프로그램을 구성하고 작업하기위한 C ++의 추가 기능은 분명히 유용합니다. 컴파일에는 그다지 구체적이지 않고 일반적으로 더 큰 프로그램에 유용한 기능입니다.

다른 요점도 언급 할 가치가 있다고 생각합니다. 초보자는 컴파일러가 주로 텍스트 조작을하는 것으로 생각하므로 Perl과 같은 것이 컴파일러 작성에 큰 도움이 될 것이라고 생각합니다. 실제로 컴파일의 흥미로운 부분은 대부분 AST를 빌드 한 후에 시작되지 않습니다. Perl이 완벽하게 잘 할 수 있다고 확신하지만 텍스트 조작 기능은 실제로 큰 이점을 제공하지는 않습니다 (텍스트 조작은 대부분 어휘 분석기에 있으며 C와 같은 것들에 대한 어휘 생성기는 RE를 지원합니다).


2
AST = 추상 구문 트리, RE = 정규 표현식
chaotic3quilibrium

5

컴파일러는 모든 현대 언어로 구현 될 수 있습니다. 그러나 컴파일러의 가장 중요한 요구 사항 중 하나는 빠릅니다.

C ++은 여기에 분명한 장점이 있습니다. C ++의 최적화는 저렴하지 않습니다. 그러나이 언어의 낮은 수준의 특성으로 인해 다른 언어 (휴대용이 아닌 어셈블리 제외)보다 C ++ 코드를 수동으로 최적화 할 수 있습니다.


11
또 다른 중요한 요구 사항은 생성 된 코드가 정확해야한다는 것입니다. 잘못된 코드를 생성하는 빠른 컴파일러보다 신뢰할 수있는 느린 컴파일러가 필요합니다.

2
C ++를 매우 많이 최적화하는 것이 가능 하지만 , 최적의 C ++ 코드보다 훨씬 적습니다.
Donal Fellows

2
@DonalFellows 다른 방향으로 돌리십시오 : 모든 언어로 최적 코드보다 적은 코드를 작성할 수는 있지만 C ++ (어셈블러 이외) 이외의 다른 언어에서는 사용할 수없는 최적화가 있습니다. 부족으로 인해 C를 포함하지 않습니다 더 높은 인라인을 허용하는 높은 수준의 구조).
클라 임

@ user1249-C ++ 코드의 속도로 인해 광석 버그가 생길 이유가 없습니다. 오히려 느리고 올바른 컴파일러보다 빠르고 정확한 컴파일러를 원합니다.
gnasher729

3

나는 그들의 사용에 대한 주요 동기가 C에서 Lex / Yacc / Bison 출력이 (주로) 있다고 생각합니다. 그것이 오랫동안 표준 이었으므로 추진력이 있습니다.

그것들이 특히 좋은 이유는 아닙니다 ...


실제로 그것은 나를 만족시키지 않지만 시도해 주셔서 감사합니다.
코브라

"컴파일러 구성을 위해 C 대신 C ++를 선택하는 이유"라는 질문에는 대답하지 않습니다.
Doc Brown

3
전혀 좋은 이유가 아닙니다. Lex 및 Yacc와 유사한 도구가 많은 플랫폼에 존재합니다. 예를 들어 PLY와 ANTLR.
user16764

또한 가장 인기있는 실제 컴파일러 (예를 들어 Clang 및 GCC는 꽤 잘 알려져 있습니다)는 손으로 쓴 파서를 사용합니다.

@delnan : 네.하지만 아마도 생성 된 것을 사용하여 작업을 시작했을 것입니다. 파서의 수동 생성은 다른 작업이 작동 함을 증명할 때까지 실제로 원하지 않는 최적화 단계입니다.
Martin York

1

이 문제에 대한 경험이 있습니다. C 및 C ++로 컴파일러를 작성했습니다. C와 C ++의 주요 차이점은 C에 자동 방식으로 동적 메모리 관리 기능이 없다는 것입니다. C의 모든 메모리 관리는 명시 적으로 수행해야합니다. 컴파일러를 작성하면 문자열 처리 및 배열 관리가 많이 처리됩니다. C에서는 모든 문자열과 선언하는 모든 배열의 크기를 생각하고 해당 객체에 액세스 할 때 인덱스를 확인해야합니다 (코드를 안전하고 안정적으로 유지하려는 경우). C에서는 물론 동적 메모리 관리가 가능하지만 자동적 인 것은 없습니다. malloc () 및 free ()를 사용하여 명시 적으로 메모리를 할당하고 사용 가능하게하고 동적 오브젝트의 크기를 분리 된 변수로 유지하여 경계 외부로 액세스하지 않도록해야합니다.

C ++에서는 동일한 메커니즘을 사용할 수 있지만 명시 적으로 호출 할 필요가없는 생성자와 소멸자 내에 모든 메모리 관리를 캡슐화 할 수 있기 때문에 실제로 개발 시간이 효율적입니다. 따라서 컴파일러는 리소스를 할당하고 해제합니다. 클래스를 직접 만들면 동적 객체의 크기를 캡슐화 할 수 있으며 오버로드 연산자 []를 사용하여 경계 액세스를 위해 인덱스를 확인할 수 있습니다. 이러한 추상화는 코드를 더 깨끗하고 이해하기 쉽고 디버깅하며 개발 속도를 높여줍니다.

C로 컴파일러를 만들면 더 많은 시간이 걸립니다. C ++을 사용하면 짧은 시간 안에 프로젝트를 완료 할 수 있습니다. C와 C ++의 성능은 동일하지만 C ++에는 C와는 다른 많은 장점이 있습니다.


0

CompCert의 프로젝트는 연구의 C ++ C 또는 C로 작성되지 않은 컴파일러,하지만 더 OCaml로하고 COQ입니다.

C ++가 C로 번역 된 적이 있음을 관찰하십시오 ( Cfront에서 ). 이제 GCC 프론트 엔드를 Gimple으로 사용 하고 Gimple을 일부 데이터베이스에 덤프 한 다음 Gimple을 어셈블러 번역기에 쓸 수 있습니다. 그러나 법적 이유 ( GCC 런타임 라이브러리 예외 )는 이러한 컴파일러가 오픈 소스 여야합니다. 자세한 내용은 변호사에게 문의하십시오. 저는 변호사가 아닙니다. 이전 버전의 GCC는 일부 C ++ 변형에 대한 프런트 엔드를 사용하여 C (+ 여러 도메인 특정 언어)로 작성되었습니다. OpenWatcom 은 C로 작성된 C ++ 컴파일러 일 수 있습니다 (확인하겠습니다).

Compcert의 출처는 학술 및 연구 목적으로 무료로 제공됩니다. 산업적으로 (법적으로) 사용하려면 Absint로부터 라이센스를 받아야합니다.

참조 두 개의 관련 질문에 대한 답변을.

내가 2020 년에 C (또는 C ++) 컴파일러를 처음부터 (Linux에서 실행 중이거나, 일부 크로스 컴파일러에서 ) 작성해야한다면 아마도 C ++로 작성하지 않을 것입니다. Ocaml , Go 또는 Rust 사용하여 작성하는 것이 좋습니다. 그리고 가능하다면 Frama-C를 기반으로 할 수 있습니다. C 또는 C ++로 코딩 해야하는 경우 먼저 가비지 수집기 라이브러리를 코딩합니다. 일부 지속성 계층은 전체 프로그램 최적화에 매우 유용합니다. 그런 다음 메타 프로그래밍 방식을 고려합니다 (대부분의 C 또는 C ++ 코드 생성) Ad-hoc 도구가 포함 된 컴파일러, Bismon 또는 RefPerSys 허용되는 경우).

Common Lisp 또는 Python (예 : ShivyC 또는 nqcc )으로 코딩 된 일부 (오픈 오픈 소스) C 컴파일러를 찾을 수 있습니다. ZetaC 도 살펴보십시오 .

최신 버전의 GCC 는 기술적으로 순수 C ++로 코딩되지 않았으며, GCC와 관련된 수십 개의 도메인 특정 언어입니다 (여러 언어Turing-complete ). 내 이전 GCC MELT 프로젝트 도 참조하십시오 .

향후 버전의 GCC에서 일부 Python 또는 Guile 인터프리터가 GCC의 패스 관리자를 대체하는 것과 같이 내부에 포함되어 있으면 놀라지 않을 것입니다.

MILEPOST GCC 프로젝트 도 살펴보십시오 .

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