두 언어간에 소스 코드를 '번역'할 수있는 프로그램이 있습니까?


28

두 언어간에 소스 코드를 '번역'할 수있는 프로그램이 있습니까 (번역자가 필수 라이브러리에 액세스한다고 가정)?

있다면 어떻게 작동 하는가 (사용되는 기술, 필요한 지식 등)? 그들은 어떻게 실현 가능할까요?

그렇지 않은 경우 개발을 방해하는 제한은 무엇입니까? 이것이 AI의 완전한 문제입니까 (자연어 번역이 하나로 나열 됨)?

EDIT 변환은 언어가 동일한 표현력을 가질 때만 동일한 종류의 문제를 해결할 있으며변환 코드는 대상 언어로 표현 될 있습니다. 예를 들어 쉘 스크립트에서 MATLAB으로의 변환은 예상되지 않습니다.



14
"두 언어"란 무엇을 의미합니까? 한 언어에서 다른 언어로 번역 할 수있는 프로그램이 있습니다. 이를 "컴파일러"라고합니다. 그것은 문자 그대로 컴파일러의 정의입니다. 프로그램을 한 언어에서 다른 언어로 번역하는 프로그램입니다. 그러나 "두 언어"? 나는 그것이 가능하지 않다고 생각합니다. 번역기는 소스 언어와 대상 언어를 모두 알아야하며 일반적으로 특정 언어 쌍에 따라 다릅니다.
Jörg W Mittag

프로그램은 소스 및 대상 언어로 제공됩니다. C ++로 프로그램을 작성하여 Java, python, Perl, Ruby, Go 등으로 변환하는 것을 생각하고 있습니다. 몇 가지 제한 사항이있을 수 있습니다 (예를 들어 쉘 스크립트를 MATLAB으로 변환하지는 않습니다).
Tobi Alafin

4
그렇습니다. 컴파일러라고하며 컴파일러처럼 작동하며 컴파일러처럼 구성 할 수 있습니다.
user253751

1
"두 언어"가 문자 그대로 (유한) 프로그램이 무한한 수의 입력 언어를 읽고 이해할 수 있어야한다는 의미라면 대답은 사소한 것이 아닙니다 . 그러나 유한 한 입력 언어를 사용하면 모든 언어에 대한 컴파일러를 찾을 수 있습니다.
Bakuriu

답변:


57

TLDR; 이것은 가능하지만 실용적이지는 않습니다.

(번역자가 필요한 라이브러리에 액세스 할 수 있다고 가정)?

이것은 까다로운 비트가되며 실제로 이와 같은 것들이 실제로 사용되지 않는 이유 중 일부입니다.

  1. 모든 컴파일러는 번역사입니다. 한 언어에서 다른 언어로 번역하는 것은 가능하며 말 그대로 모든 컴파일러가 수행하는 작업입니다. 컴파일러가 출력으로 뱉어내는 언어는 일반적으로 기계 코드 또는 어셈블리이지만, 이것은 다른 언어 일 뿐이며, 두 언어 사이를 번역하는 컴파일러 (때때로 트랜스 파일러 또는 트랜스 컴파일러)가 있습니다 . 예를 들어 PureScript, Elm, ClojureScript 등과 같은 자바 스크립트로 컴파일 할 수있는 언어가 있습니다.

  2. 두 Turing Complete 언어 사이의 번역은 항상 가능합니다. 라이브러리 호출, FFI 및 다른 불쾌한 실제 비트와 같은 것들을 무시합니다. 언어가 Turing Complete 인 경우 다음이 있습니다.

    • 튜링 머신을이 언어의 코드로 변환하는 번역
    • 이 언어에서 튜링 머신으로의 번역

    따라서 언어 A에서 언어 B로 변환하려면 A 코드를 Turing Machine으로 변환 한 다음 해당 시스템을 B 코드로 변환하십시오.

    물론 실제 비트는 방해가되므로 번역에 액세스 할 수 있어야합니다. 그것들은 기본적으로 모든 언어에 존재하지만 누군가가 언어를 쓰는 데 시간이 걸린다는 의미는 아닙니다.

  3. 이 번역을 효율적으로 수행하는 것은 어렵습니다 . 다른 언어는 다른 것을 우선시합니다. 예를 들어, C에서 Python으로 변환하면 포인터 산술을 수행 할 수 있도록 C의 메모리를 Python 사전으로 시뮬레이션해야 할 수 있습니다. 베어 메탈 메모리 명령에 액세스하지 않기 때문에 이와 관련된 오버 헤드가 발생합니다.

    언어마다 성능 우선 순위가 다르므로 한 언어에서 최적화 (또는 한 언어의 구현이 최적화)하여 다른 언어로 빠르게 수행하는 것이 불가능할 수 있습니다. 적절한 꼬리 호출없이 기능 언어를 번역하면 적절한 꼬리 호출없이 언어로 번역하면 속도가 느려집니다.

  4. 이 변환을 수행한다고해서 코드를 읽을 수있는 것은 아닙니다 . 언어 A의 코드와 동일하게 작동하는 언어 B의 코드를 쉽게 얻을 수 있습니다. 여러 가지 이유로 인간이 B로 작성한 코드처럼 보이기 어렵습니다. A와 B는 다른 추상화 도구를 가지고있을 수 있으며 컴퓨터는 코드를 읽을 수있게 만드는 요소를 모릅니다. 앞에서 설명한 Turing Machine 번역을 사용하는 경우 특히 그렇습니다.

    이것은 질문을 제기합니다 : 그러한 번역의 요점은 무엇입니까? 결국, 읽을 수없는 느리고 읽을 수없는 코드 블록을 머신 코드로 컴파일하고 FFI 또는 프로세스 간 통신을 사용하여 조각을 서로 연결하는 것이 어떻습니까?

    이에 대한 몇 가지 예외가 있습니다. 때로는 JavaScript와 같은 특정 언어로 물건이 필요합니다. 때로는 언어가 비슷하고 현명한 번역이 쉽습니다. 때로는 언어가 실행되는 것이 아니라 코드를 다른 언어 (예 : Coq)로 추출하기도합니다.

    그러나 일반적으로 실용적이지 않습니다.


5
Point 4의 한 예는 asm.js 입니다. 오늘날, 만드는 것이 가능하다 그렇다고 사용하여 읽을 수있는 자바 스크립트 소스지도 및 요소 검사기를하지만 아무도 ... 그 싶지 않을 것이다
이스마엘 미구엘

1
Modelica는 다른 언어 (이 경우 C)로 컴파일되도록 설계된 언어의 또 다른 예입니다.
Reinstate Monica

C ++에서 자바 스크립트로 웹 어셈블리 번역
Surt

X에서 Y 로의 트랜스 파일러에 대한 많은 예가 있지만, 범용 컴파일러와는 다릅니다. 트랜스 필이 적합한 경우가 분명히 있습니다.
jmite

IMO가없는 한 가지 중요한 예외 : C로 컴파일하기. 많은 드문 시스템에는 기존의 C 컴파일러가 있기 때문에 일반적으로 상당히 합리적인 머신 코드를 생성 할 수 있습니다. 따라서 언어를 C로 컴파일하면 이러한 드문 아키텍처에 대한 백엔드가 필요하지 않습니다.
MSalters

2

그러한 프로그램이 있습니다. 예를 들어 당시에 널리 사용 된 Lisp-to-Fortran 번역기. 단독 Lisp 컴파일러는 Lisp를 직접 컴파일하지 않고 C 코드를 생성하는 대신 일반 C 컴파일러에 의해 컴파일됩니다. 또 다른 예로는 직접 컴파일되지는 않지만 C ++ 코드가 컴파일되기 전에 C ++로 먼저 변환 된 Vala가 있습니다. Qt는 컴파일하기 위해 C ++로 번역되는 언어 인 MOC로 작성되었습니다 (그러나 MOC는 C ++로 C ++이므로 실제로는 "새 언어"라는 이름을 가진다면 논쟁 할 수있는 몇 가지 추가 명령이 있습니다)-그리고 그 전에 C ++ 컴파일러는 C ++에서 C 로의 변환기가있었습니다. 그리고 일부 프로젝트는 Pascal로 작성된 다음 C로 번역되었습니다. 또한 clang과 Java는 C ++ 및 Java 코드를 중간 언어로 변환하여 나중에 처리 할 수있는 것과 같은 경향이 있습니다.

언어 번역기의 결과를 기대할 수없는 것은 그 결과가 인간 독자에게는 의미가 있다는 것입니다. 언어의 기능과 사용중인 외부 라이브러리에 따라 작동하지 않습니다). 그러나 목적을 알지 못 하므로이 작업은 나머지 프로그램의 의미로 수행되므로 크게 손실 될 수 있습니다.


0

직접적인 대답은 아니지만 .Net Framework 용으로 작성된 도구 호출 ILSpy 가 있으며 .Net 어셈블리를 C # 또는 VB.Net으로 디 컴파일 할 수 있습니다.

.Net의 특성에 익숙하지 않은 경우 .Net 코드를 여러 언어로 작성할 수 있지만 주로 C # 또는 VB.Net으로 작성할 수 있습니다. 컴파일러는 응용 프로그램을 컴파일 할 때 코드를 "중급 언어"(또는 짧은 경우 IL) 코드로 변환합니다. 그런 다음이 코드는 .Net 바이너리로 컴파일됩니다.

.Net 응용 프로그램은 IL 코드에서 컴파일 된 이진 파일이므로 ILSpy는 .Net 응용 프로그램을 가져와 다시 IL 코드로 되 돌린 다음 한 단계 더 나아가 C # 또는 VB.Net으로 되돌릴 수 있습니다.

이 도구를 사용하면 응용 프로그램을 컴파일하기 만하면 컴파일 된 파일을 IL, C # 또는 VB.Net 코드로 찾아 볼 수 있습니다. 분명히, 코드가 처음 작성된 언어는 중요하지 않습니다. 바이너리가 .Net 어셈블리 인 한 컴파일 된 파일을 리버스 엔지니어링하고이 세 언어 중 하나로 콘텐츠를 출력 할 수 있습니다.

나는 이것이 정확히 컴파일러는 아니라는 것을 알고 있지만 그것은 당신이 찾고있는 것과 비슷한 최종 결과를 제공하는 도구이며 실제로 VB.Net 프로젝트를 약간의 것으로 번역하는 데 이것을 사용했습니다 저에게 더 친숙합니다. C #.


0

유스 케이스 (댓글 기반)의 경우 SWIG 가 유용 할 것 같습니다 .

SWIG는 C 및 C ++로 작성된 프로그램을 다양한 고급 프로그래밍 언어와 연결하는 소프트웨어 개발 도구입니다. SWIG는 Javascript, Perl, PHP, Python, Tcl 및 Ruby와 같은 일반적인 스크립팅 언어를 포함하여 다양한 유형의 대상 언어와 함께 사용됩니다. 지원되는 언어 목록에는 C #, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), D, Go 언어, Android를 포함한 Java, Lua, Modula-3, OCAML, Octave, Scilab 및 R과 같은 비 스크립트 언어도 포함됩니다. 또한 해석되고 컴파일 된 몇 가지 Scheme 구현 (Guile, MzScheme / Racket, Chicken)도 지원됩니다.


0

Fortran 77에서 C 로의 소스 간 변환을 수행 하는 유서 깊은 f2c를 상기 합니다.

포트란 컴파일러를 툴체인에 통합하지 않고도 수십 년 전부터 숫자 코드를 번역하는 데 주로 사용되었습니다.


0

이러한 프로그램이 원칙적으로 존재한다는 것을 알려주는 이론을 허용 가능한 번호 매기기 라고 합니다. 우리는 두 번호 매기기 사이에 계산 가능한 컴파일러가 있으며 모든 Turing-complete 형식주의 (또는 프로그래밍 언어)는 본질적으로 하나임을 증명할 수 있습니다.

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