한 프로그래밍 언어에서 다른 프로그래밍 언어로 자동 번역기가없는 이유는 무엇입니까? [닫은]


37

대부분의 프로그래밍 언어는 Turing complete이므로 한 언어로 해결할 수있는 모든 작업을 다른 언어로, 또는 Turing 기계에서 해결할 수 있습니다. 그렇다면 특정 언어에서 다른 언어로 프로그램을 변환 할 수있는 자동 번역기가없는 이유는 무엇입니까? 두 가지 언어에 대한 몇 가지 시도를 보았지만 항상 제한된 언어 하위 세트에서만 작동하며 실제 프로젝트를 변환하는 데 거의 사용될 수 없습니다.

적어도 이론적으로는 모든 언어 사이에 100 % 정확한 번역기를 쓸 수 있습니까? 실제로 어떤 도전이 있습니까? 작동하는 기존 번역가가 있습니까?


5
“모든 언어”에는 Oook와 같은 어리석은 언어도 포함됩니다. (완전성을 말하는 것은 전체 이야기가 아닙니다. 실제로 시스템 콜이 필요합니다.)
Donal Fellows

일부가 있습니다. C에서 파스칼로, 파스칼에서 C 로의 번역가는 한 시점에서 꽤 일반적이었습니다. 아래 답변에서 알 수 있듯이 출력은 수동으로 정리하지 않으면 읽을 수 없었습니다. 그리고 이들은 비교적 간단한 라이브러리를 가진 비교적 단순한 언어입니다. 예를 들어 C ++에서 Haskell로 또는 그 반대로 잘하는 것은 불가능할 것입니다.
Steve314

C #을 VB로 또는 그 반대로 변환 할 수있는 서비스로 .net 컴파일러 Roslyn을 확인하십시오.
Daniel Little

2
모든 컴파일러는 하나의 PL을 다른 PL로 변환하지만 대상 PL의 코드를 쉽게 읽을 수 있다고 보장하지는 않습니다
jk.

Google 번역의 정확성을 확인한 후 평생 통역가를 보게 될 것입니다. 예, github 또는 stackoverflow와 같은 대형 코드베이스를 분석하는 경우와 같이 어려운 노력이 될 것이며 엄청난 노력이 필요할 수 있습니다. AI와 ML을 공부할 프로그래머가 많이 있습니다. 그러한 도구를 스스로 개발하는 사람은 없을 수도 있습니다. 그러나이 문제를 해결하기 위해 봇을 개발하기위한 봇을 개발할 수 있습니다.
Ganesh Kamath- '코드 열풍'

답변:


32

가장 큰 문제는 프로그램 코드의 실제 번역이 아니라 플랫폼 API의 이식입니다.

PHP에서 Java 로의 번역기를 고려하십시오. PHP 바이너리의 일부를 포함하지 않고이를 수행 할 수있는 유일한 방법은 모든 PHP 모듈과 API를 Java로 다시 구현하는 것입니다. 여기에는 10.000 개 이상의 기능을 구현해야합니다. 실제로 구문을 번역하는 작업은 간단합니다. 그리고 모든 작업 후에도 Java 코드가 없을지라도 Java 플랫폼에서 실행되는 일종의 괴물이 있지만 내부의 PHP와 같이 구성되었습니다.

그렇기 때문에 유념해야 할 유일한 도구는 나중에 코드를 배포하지 않고 배포하기 위해 코드를 번역하는 것입니다. Google의 GWT는 Java를 JavaScript로 "컴파일"합니다. Facebook의 힙합은 PHP를 C로 컴파일합니다.



누군가 Java 번역기에서 PHP를 만들고 실제로 PHP 바이너리를 포함시킨 것처럼 보입니다. 요점은 바뀌지 않지만 동의했습니다. runtimeconverter.com/single-post/2017/09/15/…
user1122069 5

20

당신이 중간 형식이있는 경우에, 당신은 언어 X에서 프로그램을 변환하는 것을 구현할 수 해당 형식을,도 에서 언어 Y.에 해당 형식 당신이 관심있는 모든 언어에 대한 이러한 변환을 구현하고, 오른쪽 완료?

당신은 무엇을 알고 있습니까? 이러한 형식은 이미 존재합니다 : 어셈블리. 컴파일러는 이미 "언어 X에서 어셈블리로"변환을 수행하고 디스어셈블러를 "어셈블리에서 언어 Y로"변환합니다.

이제 어셈블리는 역변환을 수행하는 데 큰 언어가 아니지만 MSIL은 실제로 그렇게 나쁘지 않습니다. Reflector를 다운로드 하면 .NET 어셈블리를 여러 언어로 분해 할 수있는 옵션이 있습니다 (플러그인은 더 많은 것을 제공합니다). 따라서 C #에서 프로그램을 가져 와서 DLL (MSIL)로 컴파일 한 다음 리플렉터를 사용하여 VB, C ++ / CLI, F # 및 기타 여러 가지로 분해 할 수 있습니다. 물론 다른 모든 변환 작업도 수행됩니다. F # 파일을 가져 와서 DLL로 컴파일하고 Reflector를 사용하여 C #으로 변환하십시오.

물론 두 가지 큰 문제는 다음과 같습니다.

  1. 코드는 기본적으로 읽을 수 없습니다. MSIL (디버깅 정보 포함)은 원본 소스에서 많은 정보를 제거하므로 변환 된 버전은 100 % 충실도를 갖지 않습니다 (이론적으로 C #-> MSIL-> C # 변환을 수행하면 원래 코드를 다시 제공해야 함). 습관).
  2. 많은 .NET 언어에는 자체 사용자 지정 라이브러리 (예 : VB 런타임 라이브러리, F # 라이브러리 등)가 있습니다. 변환 할 때도 포함 (또는 변환)해야합니다.

실제로 2 번을 해결할 수는 없지만 MSIL에서 속성을 통해 추가 주석을 사용하여 1 번을 얻을 수 있습니다. 물론 추가 작업이 될 것입니다.


원본 소스의 많은 메타 데이터가 MSIL (XML 주석 및 원본 메서드, 속성 및 멤버 이름 포함)에 포함되어 있으므로 C #으로의 변환을 말 그대로 읽을 수 없다고 생각합니다. .NET 프레임 워크의 일부를 해체하십시오. 매우 읽기 쉽습니다. 물론 F #에서 C #으로 변환하는 상황은 다를 수 있습니다.
Robert Harvey

@Robert : XML 주석은 MSIL에 포함되지 않습니다. 당신이 보면 Microsoft.NET\Framework\v2.0.50727\en, 예를 들어, 당신은 시스템 라이브러리의 XML 문서를 모두 볼 수 있습니다. 이것은 Reflector (et al)가 주석을 표시하기 위해 사용하는 것입니다. 변환은 읽을 수 없으며 소스 레벨 변환에서 기대할 수있는 100 % 충실도가 아닙니다.
Dean Harding

2
디스어셈블러는 머신 실행 가능 바이너리를 해당 특정 프로세서 유형에 대한 어셈블러로 다시 변환합니다 (모든 세계가 x86 인 것은 아닙니다). 컴파일 된 코드를 다시 소스로 가져 오는 디 컴파일러를 의미합니다. 각 최적화 수준에서 각 제조업체의 각 컴파일러가 소스 라인을 다른 출력 이진 형식으로 변환하기 때문에 끔찍한 작업입니다.
uɐɪ

20

적어도 이론적으로는 모든 언어 사이에 100 % 정확한 번역기를 쓸 수 있습니까? 실제로 어떤 도전이 있습니까?

  • 구조화 된 언어에서 구조화되지 않은 언어로 여전히 튜링 완료된 언어로의 번역은 항상 가능합니다.
    • 이 주장은 엄밀히 기술적 인 의미로 봐야합니다. 즉, 번역 된 프로그램이 실행될 때 정확히 동일한 결과를 생성한다는 것을 의미합니다.
    • 번역 된 코드의 가독성이나 원래 프로그램 구조의 보존에 대해서는 암시되지 않습니다.
  • 구조화되지 않은 언어에서 구조화 된 언어로의 변환은 가능하지만 번역 된 코드는 구조화되지 않은 형태로 유지됩니다.

1
당신은 머리에 못을 쳤다. LLVM의 C 백엔드에서 나오는 코드를 읽어보십시오. 기술적으로 합법적 인 C 코드이지만 It Ai n't Pretty (TM)입니다.
dsimcha

1
@ dsimcha : C 백엔드를 제외하고 가독성이 뛰어나 디버깅이나 분해보다 출력을 훨씬 쉽게 읽을 수 있습니다. 잠시 동안 유지 보수가 끝난 후 백엔드를 다시 가져 와서 기쁩니다.
JM Becker

10

왜 프로그램을 변환하고 싶습니까?

어쨌든 소스 언어와 대상 언어는 모두 (가상) 머신 코드로 컴파일되므로 기술적 인 이유로 다른 고급 언어에 대한 컴파일러가 필요하지 않습니다.

언어는 인간을위한 것입니다. 따라서 귀하의 질문에 대한 암시 적 요구 사항은 ' 판독 가능한 코드 를 생성하는 번역기가없는 이유 ' 이며 그 대답은 (imho)입니다. 두 언어가 충분히 다르면 '판독 가능한 코드'방법이 작성되기 때문입니다. 알고리즘을 변환하는 데 필요한 것이 아니라 다른 알고리즘을 취하는 방식이 다릅니다.

예를 들어 C의 일반적인 반복과 lisp의 반복을 비교하십시오. 또는 관용적 인 루비로 파이썬을 '최상의 방법'으로 사용하십시오.

여기에서 영어와 독일어로 번역 할 때 '고양이 비가 내리고있다'라는 의미로 '버릇이 쏟아져 나온다'라는 의미로 실제 언어로 된 것과 같은 문제가 나타나기 시작합니다. 더 이상 단어를 단어로 번역하지만 의미를 찾아야합니다.

그리고 '의미'는 쉬운 개념이 아닙니다.

*) 음, 커피 스크립트가 있습니다 ...


1
좋은 대답입니다. 두 언어에 정확히 동일한 기능 및 숙어 집합이있는 경우 한 언어를 다른 언어로 상당히 효율적으로 번역 할 수 있지만 대부분의 언어는 제작자가 적절하지 않은 기능 및 숙어를 지원할 목적으로 설계되었습니다. 다른 언어로 지원됩니다 . 대상 언어의 기능과 관용구가 소스 언어의 기능과 관용구 인 경우 유지 관리 가능한 코드의 기계 번역이 가능할 수 있지만 그러한 상황은 그리 일반적이지 않습니다.
supercat

6

이론적으로는 가능하지만 대부분 쓸모가 없습니다. 소스 및 대상 언어의 거의 모든 조합이 가능하지만 대부분의 경우 아무도 결과를 보거나 사용하기를 원하지 않습니다.

C 컴파일러는 거의 모든 플랫폼에서 사용할 수 있기 때문에 공정한 수의 컴파일러가 C를 대상으로합니다. 프로세서를 설계하고 새 프로세서를 대상으로하는 C 컴파일러를 자동으로 생성 할 수있는 자동 컴파일러 생성기가 있습니다. 물론 .NET, JVM, C-- 및 LLVM과 같은 다양한 가상 머신에서 사용되는 언어를 대상으로하는 많은 구현이 있습니다.

그러나 핵심은 대상이 기본적으로 컴파일 프로세스의 단계로만 사용되는 어셈블리 언어 인 경우에만 유용하다는 것입니다. 특히, 일반적으로 일반 프로그래머가 해당 결과를 읽거나 작업하기를 원하지 않습니다 . 일반적으로 읽기가 쉽지 않습니다.


5

FWIW에는 Java에서 D 로의 번역기가 있습니다. TioPort 라고 하며 SWT를 D로 이식하기 위해 상당히 진지한 시도에 사용되었습니다. 주요 문제는 Java 표준 라이브러리의 많은 부분을 이식해야한다는 것이 었습니다. .


4

코드 번역 자체는 아니지만 언어 워크 벤치 의 개념은 모든 언어 간의 100 % 정확한 번역기와 유사한 것을 구현할 수있는 방법을 보여줍니다.

현재 접근 방식에서 소스 코드는 텍스트 형식으로 저장됩니다. 컴파일하는 동안 사람이 읽을 수있는 텍스트 파일은 추상 구문 트리 표현으로 구문 분석되어 바이트 코드 또는 기계 코드를 생성하는 데 사용됩니다. 그러나이 추상 표현은 일시적이며 컴파일러 내부에 있습니다.

언어 워크 벤치 접근 방식에서 유사한 추상 구문 트리 표현은 영구적으로 저장된 아티팩트입니다. 기계 코드와 텍스트 '소스'코드는이 추상 표현을 기반으로 생성됩니다. 이러한 방법의 결과 중 하나는 프로그램의 추상 표현이 실제로 언어에 구애받지 않으며 구현 된 언어로 텍스트 코드를 생성하는 데 사용될 수 있다는 것입니다. 즉, 한 사람이 가장 적합한 언어를 사용하여 시스템의 다양한 측면에서 자유롭게 작업 할 수 있거나 팀의 각 구성원이 가장 친숙한 언어로 공유 프로젝트를 수행 할 수 있습니다.

내가 아는 한, 기술은 여전히 ​​주류 개발에 사용할 수는 없지만 독립적으로 작업하는 여러 그룹이 있습니다. 그들 중 누구라도 약속을 지킬 것인지는 말하기 어렵지만, 그런 일이 일어나는 것은 흥미로울 것입니다.


이 그룹 중 일부의 이름을 지정할 수 있습니까?
Qwertie

4

있는 일부 자동 번역은. 목표가 읽을 수있는 코드가 아닌 컴파일 가능한 코드를 생성하는 것이라면 그다지 자주 사용하지 않는 것이 가능하고 때로는 유용합니다. 유명한 첫 번째 C ++ 컴파일러는 실제로는 컴파일러가 아니라 C ++을 (정말로 복잡한) C 소스로 변환 한 다음 C 컴파일러에서 컴파일했습니다. 많은 컴파일러가 요청에 따라 어셈블리 코드를 생성 할 수 있지만 어셈블리 텍스트를 분리 한 다음이를 기계어 코드로 변환하는 대신 일반적으로 기계어 코드를 직접 생성 할 수 있습니다.

언어 A의 완전한 사양이 주어지면 원칙적으로 일부 언어 B로 지시문을 표현하는 프로그램을 작성하는 것은 그리 어렵지 않습니다. 그러나 일반적으로 문제를 겪는 사람은 "언어 B"에 대해 실제로 저수준을 선택합니다. 또는 요즘 바이트 코드 : Jython은 Java VM에 의해 해석되는 Java 바이트 코드를 생성하는 python 구현입니다. Java 클래스 계층을 작성하고 컴파일 할 필요가 없습니다!


3

이것은 항상 이루어집니다.

모든 컴파일러는 변환 해석 언어의 경우 기계의 기본 어셈블리 언어 또는 아키텍처 독립적 인 바이트 코드에 C ++와 같은 "기본 언어를".

그래도 당신이 말하는 것이 아니라고 생각합니다. C ++을 Java 또는 Python과 같은 것으로 변환하는 번역기를 원할 것입니다. 그래도 요점이 뭐야? 기껏해야 최종 결과는 원래 소스와 동일한 효율성을 갖습니다. (실제로 훨씬 나빠질 것입니다.)

코드를 번역하기 만하면 이해하는 언어로 읽을 수 있으면 이러한 번역기는 원하는 효과와 반대되는 결과를 낳습니다. 당신은 비밀스럽고 직관적이지 않고 읽을 수없는 수많은 코드를 갖게 될 것입니다.

가장 사소한 것만이 한 언어에서 다른 언어로 직접 번역되기 때문입니다. 종종, 한 언어에서 간단한 것은 다른 언어를위한 거대한 라이브러리를 필요로하거나 불가능할 수도 있습니다. 따라서:

  1. 프로그램이 사소한 경우 괜찮은 결과를 얻을 수 있습니다. 그러나 그것이 그렇게 간단하다면 번역기를 통해 그것을 실행하는 요점은 무엇입니까?
  2. 프로그램이 중요하지 않은 경우 코드 품질이 떨어집니다.

결국, 좋은 코드를 작성하는 유일한 방법은 실제로 작성하는 것입니다. 컴퓨터는 최소한 아직은 아니지만 가독성, 모범 사례 및 우아한 솔루션 문제와 관련하여 인간을 맞출 수는 없습니다.

요컨대, 그만한 가치가 없습니다.


그런 다음 귀하의 비유는 일반 컴파일에도 적용되며 경험적으로는 그렇지 않습니다! 컴퓨터는 양질의 코드를 '생성'합니다 (쓰기 아님). 그들이 자주하는 일은 가독성 / 유지 보수성입니다. 누군가가 때때로 사람들을 믿게하는 그러한 과정이 필요하다면, 두 가지 문제 모두 쇼 스토퍼입니다. 만약 그렇다면, 번역은 원래 중요하지 않은 것입니다.
JM Becker

1

프로그래밍 언어는 엄청나게 복잡하기 때문에 프로그래밍 언어를위한 언어 번역기가 없습니다. 가상적으로 가능하지만 많은 난제가 있습니다.

첫 번째 과제는 언어의 수용 가능한 관행에 있습니다. Java 및 C ++와 같은 두 객체 지향 언어 간의 변환은 매우 복잡하며 C 기반입니다. 번역 프로그램은 두 언어 모두에 대한 표준 라이브러리에 대한 완벽한 지식이 있어야하고 행동의 차이점을 알 수 있어야합니다. 방대한 사전을 만들어야 할 때조차도 프로그래머에서 프로그래머로 프로그래밍 스타일의 차이점은 일부 변경을 수행하는 방법을 추측해야한다는 것을 의미합니다.

구문 번역을 얻은 후에는 첫 번째 언어의 구문을 두 번째 언어의 구문으로 변환하는 방법을 알아 내야합니다. C ++의 객체를 Java의 객체 (비교적으로 쉽다)로 간다면 C ++ 구조체로 무엇을합니까? 아니면 C ++ 클래스 외부의 함수입니까? 이것을 처리하는 방법을 결정하는 것은 또 다른 문제, 즉 블롭 객체의 생성을 초래할 수 있으므로 까다로울 수 있습니다. 얼룩은 반 패턴으로, 일반적입니다.

이것은 문제의 완전한 목록은 아니지만 두 가지 일 뿐이며 큰 문제입니다. 내 교수 중 한 명이 누군가 80 년대에 자신의 고용주가 기계 코드에서 C로 코드를 만들 수 있다고 확신했지만 그때는 효과가 없었습니다. 나는 완전히 작동하는 것을 의심합니다.


기존 라이브러리를 알 필요가 없다고 생각합니다. 소스를 사용할 수 있다고 가정하면 라이브러리를 그대로 번역 할 수 있습니다.
serg

1
그것은 실제로 두 번째 문제의 복잡성을 증가시킵니다. 그리고 그것은 당신이 그것을 번역하기 위해 소스 코드에 액세스 할 수 있다고 가정합니다. 어느 쪽이든, 그것은 여전히 ​​불가능합니다.
indyK1ng

라이브러리에 대한 +1 포인트는 완전히 유효하며 항상 라이브러리가 있습니다.
Dan Rosenstark

1

컴파일의 요점은 컴퓨터에 유용한 것을 얻는 것입니다. 즉 실행할 수있는 것. 왜 당신이 쓴 것보다 더 높은 수준으로 컴파일해야합니까?

.NET 전략이 더 좋습니다. 모든 것을 공통 언어로 컴파일하십시오. 이것은 (N ^ 2) -N 크로스 언어 컴파일러를 만들 필요없이 통신 할 수있는 언어의 이점을 제공합니다.

예를 들어 10 개의 프로그래밍 언어가있는 경우 .NET 모델에서 10 개의 컴파일러 만 작성하면되고 서로 통신 할 수 있습니다. 가능한 모든 크로스 언어 컴파일러를 만들었다면 90 개의 컴파일러를 작성해야합니다. 이점이 거의없는 추가 작업이 많이 있습니다.

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