다른 프로그래밍 언어로 쉽게 번역 할 수 있도록 코드에 어떤 종류의 패턴을 적용 할 수 있습니까? [닫은]


95

저는 한 프로그래밍 언어에서 다른 프로그래밍 언어로 코드를 번역하는 것을 목표로하는 사이드 프로젝트를 시작하려고합니다. 내가 시작하는 언어는 PHP와 Python (Python에서 PHP로 시작하는 것이 더 쉬울 것임)이지만 이상적으로는 (상대적) 쉽게 다른 언어를 추가 할 수 있습니다. 계획은 다음과 같습니다.

  • 이것은 웹 개발을위한 것입니다. 원본 코드와 대상 코드는 프레임 워크 위에 배치됩니다 (또한 작성해야 함). 이러한 프레임 워크는 MVC 디자인 패턴을 수용하고 엄격한 코딩 규칙을 따릅니다. 이렇게하면 번역이 다소 쉬워집니다.

  • 또한 IOC 및 종속성 주입을 검토하고 있습니다. 번역 프로세스를 더 쉽게 만들고 오류 발생 가능성을 줄일 수 있기 때문입니다.

  • 저는 추상 구문 트리를 조작 할 수있는 파이썬의 파서 모듈 을 사용할 것입니다 . 분명히 PHP로 얻을 수있는 가장 가까운 것은 token_get_all () 이며 시작입니다.

  • 그때부터 AST, 기호 테이블 및 제어 흐름을 구축 할 수 있습니다.

그러면 코드 출력을 시작할 수 있다고 믿습니다. 완벽한 번역이 필요하지 않습니다 . 여전히 생성 된 코드를 검토하고 문제를 해결해야합니다. 이상적으로 번역자는 문제가있는 번역에 플래그를 지정해야합니다.

"도대체이게 뭐야?"라고 묻기 전에 답은 ... 흥미로운 학습 경험이 될 것입니다. 이를 덜 어렵게 만드는 방법에 대한 통찰력이 있으면 알려주십시오.


편집하다:

번역을 수행하는 방법보다 코드를 더 쉽게 번역 (예 : IoC, SOA?) 할 수 있도록 코드에 어떤 종류의 패턴을 적용 할 수 있는지 알고 싶습니다.


6
.NET CLR 또는 Perl6의 Parrot과 같은 시스템을 보셨습니까? 그들은 공통 인터프리터가 실행할 수있는 중간 표현으로 언어 세트를 컴파일합니다. 중간 표현에서 언어로 되돌아 갈 수 있다면 번역가가 있습니다.
Borealid

1
@Borealid AFAIK의 .NET CIL은 (상대적으로) 쉽게 컴파일하는 것입니다 으로 하지만, 좋은 행운이에서 읽을 수있는 코드를 다시 받고. 지금 앵무새를보고 있습니다.
NullUserException 2010 년

다른 언어에 대해서도 비슷한 프로젝트가 있습니다. 저자가 얼마나 부유한지 잘 모르겠습니다. 그리고 저는 실제로 프레임 워크가 필요하고 엄격한 코딩 규칙을 준수함으로써 여기에서 많은 것을 제지하고 있습니다.
NullUserException 2010 년

2
특정 지식을 추가 할 수는 없지만 잠옷 ( pyjs.org ), 특히 translator.py 를 살펴 보셨습니까 ? 이것은 python to javascript 컴파일러입니다.
스테판

3
다시 편집 : 번역 될 코드를 제어 할 수있는 경우 가장 분명한 방법은 번역하기 어려운 구문을 피하는 것입니다! 예를 들어 C는 포인터 산술이없는 경우 Java로 번역하기가 훨씬 쉽습니다. 파이썬의 경우 아마도 클로저를 피할 것입니다. 다른 방법은 번역하기 어려운 부분이 항상 관용적으로 코딩되도록 소스 코드를 작성하여 특수한 경우를 더 쉽게 인식하고 처리 할 수 ​​있도록하는 것입니다.
Ira Baxter

답변:


122

봤는데 구축 도구 (DMS 소프트웨어 재 설계 툴킷) 1995 년부터 강력한 컴퓨터 과학자 팀의 지원을 받아 범용 프로그램 조작 (언어 번역이 특별한 경우)을 수행하는 를 . DMS는 일반 구문 분석, AST 구축, 기호 테이블, 제어 및 데이터 흐름 분석, 번역 규칙 적용, 주석이있는 소스 텍스트 재생성 등을 제공하며, 모두 컴퓨터 언어의 명시 적 정의에 따라 매개 변수화됩니다.

이 작업을 수행하는 데 필요한 기계의 양 방대하며 (특히 일반적인 방식으로 여러 언어에 대해이 작업을 수행하려는 경우) 신뢰할 수없는 정의를 가진 언어에 대해 신뢰할 수있는 파서가 필요합니다 (PHP는 이에 대한 완벽한 예입니다. ).

언어 대 언어 번역기를 만들거나 시도하는 것에 대해 생각하는 데 아무런 문제가 없지만 실제 언어에 대해서는 예상보다 훨씬 더 큰 작업이 될 것이라고 생각합니다. 우리는 단지 DMS에만 100 명의 인력을 투자했고 각각의 "신뢰할 수있는"언어 정의 (PHP 용으로 고통스럽게 구축 한 언어 포함)에 6-12 개월을 투자했으며, C ++와 같은 불쾌한 언어에 대해서는 훨씬 더 많이 투자했습니다. 그것은 "지옥의 학습 경험"이 될 것입니다. 우리를위한 것입니다. (위 웹 사이트의 기술 문서 섹션에서 학습을 바로 시작할 수 있습니다.)

사람들은 종종 익숙한 기술로 시작하여 일종의 일반화 된 기계를 만들려고 시도합니다. (Python AST가 좋은 예입니다). 좋은 소식은 작업의 일부가 완료되었다는 것입니다. 나쁜 소식은 기계에 엄청난 양의 가정이 내장되어 있다는 것입니다. 대부분은 다른 일을하도록 씨름하기 전까지는 발견 할 수 없습니다. 그 시점에서 당신은 기계가 원래하는 일을하도록 연결되어 있다는 것을 알게되며, 실제로 다른 일을하려는 당신의 시도에 저항 할 것입니다. (Python AST를 사용하여 PHP를 모델링하는 것이 재미있을 것 같습니다.)

제가 DMS를 구축하기 시작한 이유는 그러한 가정이 거의 내장되지 않은 기초를 구축하기 위해서였습니다. 우리에게 골칫거리가되는 것도 있습니다. 지금까지 블랙홀은 없습니다. (지난 15 년 동안 제 일에서 가장 힘든 부분은 그러한 가정이 들어오지 못하도록하는 것입니다.)

많은 사람들은 또한 그들이 구문 분석을 할 수 있다면 (그리고 아마도 AST를 얻을 수 있다면) 복잡한 일을 잘하고 있다고 가정하는 실수를 범합니다. 어려운 교훈 중 하나는 좋은 프로그램 분석이나 변환을 수행하기 위해 기호 테이블과 흐름 분석이 필요하다는 것입니다. AST가 필요하지만 충분하지 않습니다. 이것이 Aho & Ullman의 컴파일러 책이 2 장에서 멈추지 않는 이유입니다. (OP는 AST를 넘어서 추가 기계를 만들 계획이라는 점에서이 권한을 가지고 있습니다.) 이 주제에 대한 자세한 내용은 Life After Parsing을 참조하십시오 .

"완벽한 번역이 필요 없다"는 말이 번거 롭다. 약한 번역가가하는 일은 코드의 "쉬운"80 %를 변환하여 어려운 20 %는 손으로 할 수 있도록하는 것입니다. 변환하려는 응용 프로그램이 매우 작고 한 번만 잘 변환하려는 경우 20 %는 괜찮습니다. 많은 응용 프로그램 (또는 시간이 지남에 따라 약간 변경된 동일한 응용 프로그램)을 변환하려는 경우 좋지 않습니다. 100K SLOC를 변환하려고하면 20 %는 번역, 이해 및 수정하기 어려운 원본 코드 20,000 줄이며, 이미 이해하지 못하는 번역 된 프로그램의 다른 80,000 줄의 맥락에서 수정됩니다. 엄청난 노력이 필요합니다. 백만 라인 수준에서 이것은 실제로 불가능합니다.더 어렵고 그들은 일반적으로 오랜 시간 지연, 높은 비용 및 종종 완전한 실패로 고통스럽게 발견합니다.)

대규모 시스템을 번역하기 위해 촬영해야하는 것은 90 %의 높은 전환율이거나 번역 활동의 수동 부분을 완료하지 못할 가능성이 높습니다.

또 다른 주요 고려 사항은 번역 할 코드의 크기입니다. 좋은 도구를 사용하더라도 작동하고 강력한 번역기를 만드는 데는 많은 에너지가 필요합니다. 단순히 수동 변환을 수행하는 대신 번역기를 구축하는 것이 섹시하고 멋져 보이지만, 소규모 코드베이스 (예 : 경험상 최대 약 100K SLOC)의 경우 경제적 측면에서이를 정당화하지 않습니다. 아무도이 답변을 좋아하지 않지만 실제로 10K SLOC 코드 만 번역해야한다면 총알을 깨물고 실행하는 것이 좋습니다. 그리고 네, 그것은 고통 스럽습니다.

저는 우리의 도구가 매우 훌륭하다고 생각합니다 (하지만 저는 꽤 편견이 있습니다). 그리고 좋은 번역가를 만드는 것은 여전히 ​​매우 어렵습니다. 약 1.5-2 년이 걸리며 도구 사용법을 알고 있습니다. 차이점은 이렇게 많은 기계를 사용하면 실패보다 훨씬 더 자주 성공 한다는 것입니다.


8
"고통스럽게 구축 된"PHP 정의를 전체적으로 PHP 커뮤니티에 다시 기여하는 것을 고려한 적이 있습니까? 아니면 자신의 수익 흐름과 너무 밀접하게 연관되어이를 실현할 수 없습니까?
TML

53
수익원에 기여하고 싶지 않고 직접 작업하고 오픈 소스 할 수있는 에너지가없는 많은 사람들로부터 우리가하는 모든 일을 "오픈 소스"로 만들도록 요청 받았습니다. 아주 큰 프로젝트에 작은 부분 만 기여하거나 다른 수입원이 있다면 "오픈 소스"가 괜찮아 보입니다. 모든 작업을 직접 수행하고 유일한 수입원이라면 이는 훨씬 덜 매력적입니다. [저는 "자유 소프트웨어"철학의 상대적인 장점에 대해 논의하고 싶지 않으므로이 라인에 대한 더 이상의 의견에는 참여하지 않겠습니다.]
아이라 박스터

9
나는 당신이 여기서 말한 것에 동의합니다. 그래서 내가했던 것처럼 질문을 표현한 것입니다. 우리는 그 응답에서 그것이 당신의 수익과 너무 밀접하게 연관되어 있다고 느끼는 것을 직감해야한다고 생각합니다. 그리고 그것은 전혀 문제가 없습니다. 그냥 물어볼 가치가 있다고 생각했습니다.
TML

3
@IraBaxter 당신은 다른 많은 수련에도 적용될 수있는 컴퓨터와 관련된 수련에 대한 일반적인 관용구를 말합니다. 당신이 작성한 모든
것에서 흥미로운

1
답변에 Clang 관련 페이지에 대한 링크를 제공하는 경우가 많습니다. 그것은 다른 누군가가 웹 페이지를 만들 수 있다는 것을 증명할뿐입니다. 우리 대부분은 잘 작성된 웹 페이지가 귀하의 답변에서 암시하는 것처럼 독자를 속이려는 사기적인 시도가 아니라 진지하고 실제적인 작업이 있음을 의미한다고 가정합니다. 실제로 웹 페이지가 사기라고 생각하십니까? 이 페이지에는 "관련"소스에 대한 참조 정보가 포함되어 있습니다. 작업에 대한 계약이 필요하기 때문에 익명화됩니다. 내가 도울 수 없다고.
Ira Baxter

13

내 대답은 Ira가 그의 대답에서 잘 언급 한 상위 수준이 아닌 다른 언어로 번역하기 위해 Python을 구문 분석하는 특정 작업을 다룰 것입니다.

간단히 말해서 파서 모듈을 사용하지 마십시오. 더 쉬운 방법이 있습니다.

astPython 2.6부터 사용할 수있는 이 모듈은 작업 할 준비된 AST를 제공하므로 필요에 훨씬 더 적합합니다. 나는 썼다작년 에이 기사를 했지만 간단히 말해서 Python 소스 코드를 AST로 구문 분석 하는 parse방법을 사용합니다 ast. parser모듈은 당신에게 파스 트리가 아닌 AST를 제공 할 것입니다. 차이에주의하십시오 .

이제 Python의 AST는 매우 상세하기 때문에 AST가 주어지면 프런트 엔드 작업이 그렇게 어렵지 않습니다. 기능의 일부에 대한 간단한 프로토 타입을 아주 빨리 준비 할 수 있다고 생각합니다. 그러나 완전한 솔루션을 얻으려면 주로 언어의 의미가 다르기 때문에 더 많은 시간이 걸립니다. 언어의 간단한 하위 집합 (함수, 기본 유형 등)은 쉽게 번역 할 수 있지만 더 복잡한 계층에 들어가면 한 언어의 핵심을 다른 언어로 에뮬레이트하기 위해 무거운 기계가 필요합니다. 예를 들어, PHP에 존재하지 않는 Python의 생성기와 목록 이해를 고려하십시오 (내가 아는 한, PHP가 관련되어있을 때 좋지 않음).

마지막 팁을 제공하기 위해 2to3Python 개발자가 Python 2 코드를 Python 3 코드로 변환하기 위해 만든 도구를 고려하십시오 . 프런트 엔드는 파이썬을 무언가 로 번역하는 데 필요한 대부분의 요소를 가지고 있습니다. . 그러나 Python 2와 3의 코어가 비슷하기 때문에 에뮬레이션 기계가 필요하지 않습니다.


위엘. 2to3AST에서 AST로. ast모듈 의 기능을 넘어서는 작업을 지원하지 않습니다 . 번역의 모든가는 것을 공지 사항 에서 호스트 파이썬 프로세스에 의해 지원되는 구문을 하는 호스트 파이썬 프로세스에 의해 지원되는 구문. 2.6은이를 지원하지 않기 때문에 함수 주석을 추가하는 변환기가 없습니다.
habnabit

... 그리고 OP의 질문은 단기적으로 Python 2.6 AST에서 PHP로 ... ast 모듈은 PHP 구문을 잘 표현하지 않을 가능성이 높으므로 ast도 아닙니다.
Ira Baxter

2
@Aaron : 2to3에서 생성 된 AST를 사용하는 예제로 볼 수 있습니다 ast.
Eli Bendersky

AFAIK, 2to3은 틀림없이 Python보다 PHP 로의 변환이 더 쉽습니다 (결국 Python에서 Python으로)? 그리고 그것은 특히 잘 작동하지 않습니다. 아직 2to3를 통과하지 못한 많은 양의 파이썬 2.6을 주목하세요 ... 왜냐하면 아직 수행해야 할 번역 후 손 패치가 상당히 많기 때문입니다. 100 % 자동화 되었다면 Python 2.6은 죽었을 것입니다.
Ira Baxter

5

번역가를 쓰는 것은 불가능하지 않습니다. 특히 Joel의 인턴 이 여름에 한 것을 고려하면 더욱 그렇습니다 .

하나의 언어를하고 싶다면 쉽습니다. 더 많이하고 싶다면 조금 더 어렵지만 너무 많지는 않습니다. 가장 어려운 부분은 모든 튜링 완성 언어는 다른 튜링 완성 언어가하는 일을 할 수 있지만 내장 데이터 유형은 언어가 놀랍도록 변경 될 수 있다는 것입니다.

예를 들면 :

word = 'This is not a word'
print word[::-2]

복제 하는 데 많은 C ++ 코드가 필요합니다 (좋아요, 일부 루핑 구조로 상당히 짧게 할 수 있지만 여전히).

제 생각에는 약간 제쳐두고 요.

언어 문법을 기반으로 토크 나이저 / 파서를 작성한 적이 있습니까? 이 프로젝트의 주요 부분이기 때문에 그렇게하지 않았다면 그 방법을 배우고 싶을 것입니다. 내가 할 일은 기본적인 Turing 완전한 구문을 만드는 것 입니다. 파이썬 바이트 코드 와 상당히 비슷합니다 . 그런 다음 언어 문법을 취하는 어휘 분석기 / 파서를 만듭니다 (아마도 BNF를 사용하여 ) 기반으로 언어를 중간 언어로 컴파일 . 그런 다음 원하는 것은 반대로 수행하는 것입니다. 언어에서 문법에 따라 대상 언어로 파서를 만듭니다.

내가 본 가장 명백한 문제는 처음 에는 특히 Python과 같은 더 강력한 * 언어에서 끔찍하게 비효율적 인 코드를 만들 수 있다는 것입니다 .

그러나 이렇게하면 결과를 최적화하는 방법을 알아낼 수있을 것입니다. 요약:

  • 제공된 문법 읽기
  • 프로그램을 중간 (튜링 완료) 구문으로 컴파일
  • 중간 프로그램을 최종 언어로 컴파일 (제공된 문법에 따라)
  • ...?
  • 이익!(?)

* 강력하다는 것은 이것이 4 줄을 필요로한다는 것을 의미합니다.

myinput = raw_input("Enter something: ")
print myinput.replace('a', 'A')
print sum(ord(c) for c in myinput)
print myinput[::-1]

그런 일을 할 수있는 다른 언어를 4 줄로 보여 주시면 파이썬만큼 강력한 언어를 보여 드리겠습니다.


"언어 문법에 기반한 토크 나이저 / 파서를 작성해 본 적이 있습니까?"저는 JavaCC를 사용하여 작성했습니다.
NullUserException

2
Joel의 인턴은 여름에 부분적인 일을했습니다. 그의 원어는 기존 언어의 하위 집합이었으며 아마도이 하위 집합은 다소 조정될 수 있습니다. 그것은 일을 훨씬 쉽게 만듭니다. 마찬가지로 NullPointerException은 Python의 더 쉬운 부분에서 시작하여 수동 변환을 위해 더 어려운 부분을 통과 할 수 있습니다 (질문에 언급 됨).
David Thornley

@NullUserException : 약간의 노출이있을 수 있지만 기본적으로 JavaCC를 다시 구현할 것입니다. 출력 언어로 Java 대신 <여기에 langauge 삽입>을 수행 할 것입니다. @David, 아주 그렇습니다. Thistle조차도 일부 언어 구조에 대한 도움이 필요합니다. 내가 OP라면 기능을 먼저 수행 한 다음 최적화하지 않으면 C ++에서 문자열 슬라이싱 (단계 포함)을 수행하려고 영원히
Wayne Werner

@WayneWerner 기록을 위해 C #과 같은 언어에는 줄 바꿈이 전혀 필요하지 않습니다. (적어도 한 줄 주석을 제거한 후에는 아닙니다.) 따라서 모든 C # 프로그램을 한 줄에 작성할 수 있습니다. 하지만 물론 나는 당신이 무엇을 얻고 있는지 이해합니다.
leviathanbadger

@ aboveyou00 : 옳지 않다고 생각합니다. 전 처리기 조건문을 허용하지 않으면 맞을 수 있습니다.
Ira Baxter

3

귀찮게하지 말라고하는 몇 가지 답변이 있습니다. 그게 얼마나 도움이 되나요? 배우고 싶어? 당신은 배울 수 있습니다. 이것은 편집입니다. 대상 언어가 기계 코드가 아니라 또 다른 고급 언어가되는 경우도 있습니다. 이것은 항상 수행됩니다.

시작하는 비교적 쉬운 방법이 있습니다. 먼저 http://sourceforge.net/projects/lime-php/(PHP 에서 작업하려는 경우) 또는 일부를 가져 와서 예제 코드를 살펴 봅니다. 다음으로, 일련의 정규 표현식을 사용하여 어휘 분석기를 작성하고 생성 한 파서에 토큰을 공급할 수 있습니다. 시맨틱 동작은 코드를 다른 언어로 직접 출력하거나 출력 코드를 생성하기 위해 마사지 및 트래버스 할 수있는 일부 데이터 구조 (생각 개체, 사람)를 구축 할 수 있습니다.

PHP와 Python은 여러 측면에서 서로 동일한 언어이지만 구문이 다르기 때문에 운이 좋습니다. 어려운 부분은 문법 형식과 데이터 구조 사이의 의미 적 차이를 극복하는 것입니다. 예를 들어 Python에는 목록과 사전이 있지만 PHP에는 assoc 배열 만 있습니다.

"학습자"접근 방식은 제한된 언어 하위 집합 (예 : 인쇄 문, 단순 수학 및 변수 할당 만 해당)에 대해 제대로 작동하는 것을 구축 한 다음 점차적으로 제한을 제거하는 것입니다. 그것은 기본적으로 그 분야의 "큰"사람들이 한 일입니다.

아, 그리고 파이썬에 정적 유형이 없기 때문에 파이썬이하는 방식에 따라 숫자, 문자열 또는 객체를 추가하는 "python_add"와 같은 PHP 함수를 작성하고 의존하는 것이 가장 좋습니다.

분명히, 당신이 그것을 허용하면 훨씬 더 커질 수 있습니다.


3
사실은 "귀찮게 하지마"라고 말하지 않았습니다. 제가 말한 것은 "일반적인 방법으로 언어를 번역하는 것은 매우 어렵다"는 것입니다. OP가 Python 트리를 사용하여 PHP를 생성하는 원래 경로를 따라 가면 그는 많은 것을 배울 것이며 저는 학습 경험에 찬성합니다. 저도 거기서 시작했습니다. 그는 새로운 언어를 쉽게 추가 할 수 없습니다.
Ira Baxter

@IraBaxter 귀하의 진술을 지원할 수 없습니다. Python-> PHP 및 PHP-> Javascript를 수행하는 것은 쉬운 일입니다. cf. 의 마지막 부분 stackoverflow.com/a/22850139/140837 나는 또한 "논증"처리 답의 중간에
amirouche

2

파서 대신 ast.parse를 사용하는 것과 관련하여 @EliBendersky 관점에서 두 번째로 볼 것입니다 (이전에 알지 못했던). 또한 그의 블로그를 검토 할 것을 적극 권장합니다. 저는 ast.parse를 사용하여 Python-> JavaScript 번역기 (@ https://bitbucket.org/amirouche/pythonium )를 수행했습니다. 다른 구현 을 다소 검토하고 직접 시도 하여 Pythonium 디자인을 생각해 냈습니다 . 나는 https://github.com/PythonJS/PythonJS 에서 Pythonium을 포크 했고, 실제로는 완전히 다시 작성했습니다. 전체 디자인은 PyPy 및 http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-89-1.pdf 문서 에서 영감을 얻었습니다 .

내가 시도한 모든 것, 처음부터 최고의 솔루션까지, Pythonium 마케팅처럼 보이지만 실제로는 그렇지 않습니다 (네티켓에 맞지 않는 것이 있으면 주저하지 말고 알려주세요).

  • 프로토 타입 상속을 사용하여 Plain Old JavaScript에서 Python 시맨틱 구현 : AFAIK JS 프로토 타입 객체 시스템을 사용하여 Python 다중 상속을 구현하는 것은 불가능합니다. 나중에 다른 트릭을 사용하여 시도했습니다 (getattribute 참조). 내가 아는 한 JavaScript에서 Python 다중 상속을 구현하지 않는 한, 존재하는 최고는 단일 상속 + 믹스 인이며 다이아몬드 상속을 처리하는지 확실하지 않습니다. Skulpt와 비슷하지만 Google clojure가 없습니다.

  • 실제로 Skulpt 코드 #fail을 읽는 대신 Skulpt (컴파일러)처럼 Google clojure를 사용해 보았습니다. 어쨌든 JS 프로토 타입 기반 객체 시스템 때문에 여전히 불가능합니다. 바인딩을 만드는 것은 매우 어려웠습니다. JavaScript와 많은 상용구 코드를 작성해야합니다 (참고 : 내가 유령 인 경우 https://github.com/skulpt/skulpt/issues/50 ). 그 당시에는 빌드 시스템에 바인딩을 통합하는 명확한 방법이 없었습니다. Skulpt는 라이브러리이고 html에 .py 파일을 포함하면 실행되며 개발자가 컴파일 단계를 수행 할 필요가 없습니다.

  • pyjaco (컴파일러)를 시도했지만 바인딩 생성 (Python 코드에서 자바 스크립트 코드 호출)은 매우 어려웠으며 매번 생성하기에는 너무 많은 상용구 코드가있었습니다. 이제 나는 pyjaco가 Pythonium에 더 가깝다고 생각합니다. pyjaco는 Python (ast.parse도 마찬가지)으로 작성되었지만 JavaScript로 작성되었으며 프로토 타입 상속을 사용합니다.

나는 실제로 Pajamas #fail 실행에 성공한 적이 없으며 코드 #fail을 다시 읽지 않았습니다. 그러나 내 마음에 잠옷은 Python에서 JavaScript 로의 번역이 아닌 API-> API 변환 (또는 프레임 워크에서 프레임 워크로)을 수행하고있었습니다. JavaScript 프레임 워크는 이미 페이지에있는 데이터 또는 서버의 데이터를 사용합니다. 파이썬 코드는 단지 "배관"입니다. 그 후 나는 잠옷이 실제로 진짜 python-> js 번역기라는 것을 발견했습니다.

그래도 API-> API (또는 프레임 워크-> 프레임 워크) 번역을 수행 할 수 있다고 생각하며 기본적으로 Pythonium에서 수행하는 작업이지만 하위 수준에서 수행합니다. 아마도 파자마는 Pythonium과 동일한 알고리즘을 사용합니다.

그런 다음 Skulpt와 같은 Javascript로 완전히 작성된 brython을 발견했습니다. 컴파일과 보풀이 필요하지 않지만 JavaScript로 작성되었습니다.

이 프로젝트 과정에서 작성된 초기 라인 이후로 나는 PyPy, 심지어 PyPy 용 JavaScript 백엔드까지도 알고있었습니다. 예, 찾으면 PyPy에서 JavaScript로 Python 인터프리터를 직접 생성 할 수 있습니다. 사람들은 그것이 재앙이라고 말합니다. 나는 왜 어디서도 읽지 않았다. 그러나 그 이유는 인터프리터를 구현하는 데 사용하는 중간 언어 인 RPython이 C (아마도 asm)로 번역되도록 맞춤화 된 Python의 하위 집합이기 때문이라고 생각합니다. Ira Baxter는 무언가를 만들 때 항상 가정을하고 아마도 PyPy : Python-> C 번역의 경우에 의도 한 바에 따라 최선을 다하도록 미세 조정한다고 말합니다. 이러한 가정은 다른 맥락에서 더 나쁘게 관련되지 않을 수 있으며 오버 헤드를 추론 할 수 있습니다. 그렇지 않으면 직접 번역이 항상 더 좋을 것이라고 말했습니다.

인터프리터를 파이썬으로 작성하는 것은 (아주) 좋은 생각처럼 들렸습니다. 하지만 성능상의 이유로 컴파일러에 더 관심이 많았습니다. 실제로 파이썬을 해석하는 것보다 자바 스크립트로 컴파일하는 것이 더 쉽습니다.

저는 JavaScript로 쉽게 번역 할 수있는 Python의 하위 집합을 모으는 아이디어로 PythonJS를 시작했습니다. 처음에는 과거의 경험으로 인해 OO 시스템을 구현하는 데 신경 쓰지 않았습니다. JavaScript로 번역하기 위해 얻은 Python의 하위 집합은 다음과 같습니다.

  • 정의와 호출 모두에서 의미론적인 전체 매개 변수를 가진 함수. 이것이 제가 가장 자랑스럽게 생각하는 부분입니다.
  • while / if / elif / else
  • Python 유형이 JavaScript 유형으로 변환되었습니다 (어떤 종류의 Python 유형도 없음).
  • for Javascript 배열 만 반복 할 수 있음 (in 배열의 경우)
  • JavaScript에 대한 투명한 액세스 : Python 코드로 Array를 작성하면 javascript의 Array로 변환됩니다. 이것은 경쟁사보다 유용성 측면에서 가장 큰 성과입니다.
  • Python 소스에 정의 된 함수를 javascript 함수로 전달할 수 있습니다. 기본 인수가 고려됩니다.
  • new (Python) (1, 2, spam, "egg")는 "new Python (1, 2, spam,"egg ")로 번역됩니다.
  • "var"는 번역기에 의해 자동으로 처리됩니다. (Brett (PythonJS 기고자)의 아주 좋은 결과입니다.
  • 글로벌 키워드
  • 폐쇄
  • 람다
  • 목록 이해
  • import는 requirejs를 통해 지원됩니다.
  • 단일 클래스 상속 + classyjs를 통한 믹스 인

이것은 많이 보이지만 실제로 파이썬의 완전한 의미에 비해 매우 좁습니다. 실제로 Python 구문을 사용하는 JavaScript입니다.

생성 된 JS는 완벽합니다. 오버 헤드가 없으며 추가 편집으로 성능면에서 향상 될 수 없습니다. 생성 된 코드를 개선 할 수 있다면 Python 소스 파일에서도이를 수행 할 수 있습니다. 또한 컴파일러는 http://superherojs.com/ 에 의해 작성된 .js에서 찾을 수있는 JS 트릭에 의존하지 않았기 때문에 매우 읽기 쉽습니다.

PythonJS의이 부분의 직계 자손은 Pythonium Veloce 모드입니다. 전체 구현은 https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/veloce/veloce.py?at=master 793 SLOC + 약 100 SLOC의 공유 코드를 다른 번역자와 함께 찾을 수 있습니다 .

pystones.py의 개조 된 버전은 Veloce 모드 cf. https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pystone/?at=master

기본 Python-> JavaScript 번역을 설정 한 후 전체 Python을 JavaScript로 번역하는 다른 경로를 선택했습니다. 대상 언어를 제외한 객체 지향 클래스 기반 코드를 수행하는 glib 방법은 JS이므로 배열, 맵과 같은 객체 및 기타 많은 트릭에 액세스 할 수 있으며 해당 부분은 모두 Python으로 작성되었습니다. IIRC에는 Pythonium 번역기로 작성된 자바 스크립트 코드가 없습니다. 단일 상속을 얻는 것은 어렵지 않습니다. 여기에 Pythonium이 Python과 완전히 호환되는 어려운 부분이 있습니다.

  • spam.egg파이썬에서는 항상 getattribute(spam, "egg")이것을 특별히 프로파일 링하지는 않았지만 많은 시간을 잃어버린 곳에서 asm.js 또는 다른 것으로 향상시킬 수 있는지 확신하지 못합니다.
  • 메서드 해결 순서 : Python으로 작성된 알고리즘을 사용하더라도 Python Veloce 호환 코드로 번역하는 것은 큰 노력이었습니다.
  • getattributre : 실제 getattribute 해결 알고리즘은 다소 까다 롭고 여전히 데이터 설명자를 지원하지 않습니다.
  • 메타 클래스 클래스 기반 : 코드를 연결할 위치를 알고 있지만 여전히 ...
  • 마지막으로, some_callable (...)은 항상 "call (some_callable)"로 변환됩니다. AFAIK 번역자는 추론을 전혀 사용하지 않으므로 호출을 할 때마다 어떤 종류의 객체를 호출 할 것인지 확인해야합니다.

이 부분은 https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/runtime.py?at=master 에서 고려됩니다 . Python Veloce와 호환되는 Python으로 작성되었습니다.

실제 호환 번역기 https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/compliant.py?at=master 는 JavaScript 코드를 직접 생성하지 않으며 가장 중요한 것은 ast-> ast 변환을 수행하지 않습니다. . 나는 ast-> ast 일을 시도했고 cst보다 좋더라도 ast.NodeTransformer와 함께 작업하는 것이 좋지 않더라도 ast-> ast를 할 필요가 없습니다.

내 경우에는 python ast를 python ast로 수행하는 것이 적어도 성능 향상이 될 수 있습니다. 예를 들어 관련 코드를 생성하기 전에 언젠가 블록의 내용을 검사하기 때문입니다.

  • var / global : 무언가를 var로 만들 수 있으려면 var가 아닌 내가 무엇을해야하는지 알아야합니다. 주어진 블록에 생성 된 변수를 추적하는 블록을 생성하고 생성 된 펑션 블록 위에 삽입하는 대신, 실제로 하위 노드를 방문하여 관련 코드를 생성하기 전에 블록에 들어갈 때 눈에 띄는 변수 할당을 찾습니다.
  • yield, generators는 아직 JS의 특수 구문을 가지고 있으므로 "var my_generator = function"을 작성하고 싶을 때 어떤 Python 함수가 생성자인지 알아야합니다.

그래서 저는 번역의 각 단계마다 한 번씩 각 노드를 방문하지 않습니다.

전체 프로세스는 다음과 같이 설명 할 수 있습니다.

Python source code -> Python ast -> Python source code compatible with Veloce mode -> Python ast -> JavaScript source code

Python 내장 기능은 Python 코드 (!)로 작성됩니다. IIRC에는 부트 스트랩 유형과 관련된 몇 가지 제한 사항이 있지만 호환 모드에서 Pythonium을 번역 할 수있는 모든 것에 액세스 할 수 있습니다. https://bitbucket.org/amirouche/pythonium/src/33898da731ee2d768ced392f1c369afd746c25d7/pythonium/compliant/builtins/?at=master를 살펴보세요

Pythonium 호환에서 생성 된 JS 코드를 읽는 것은 이해할 수 있지만 소스 맵이 큰 도움이 될 것입니다.

이 경험에 비추어 제가 드릴 수있는 귀중한 조언은 친절한 구세대입니다.

  • 문학 및 기존 프로젝트에서 주제를 광범위하게 검토합니다. 다른 기존 프로젝트를 검토 할 때 더 많은 시간과 동기를 부여해야했습니다.
  • 질문! C / Javascript 시맨틱 불일치로 인한 오버 헤드 때문에 PyPy 백엔드가 쓸모가 없다는 것을 미리 알았다면. 저는 아마도 6 개월 전에 아마 3 년 전에 Pythonium 아이디어를 가지고 있었을 것입니다.
  • 무엇을하고 싶은지 알고 목표를 정하십시오. 이 프로젝트에서 저는 다른 목표를 가지고있었습니다. 자바 스크립트를 조금 연습하고, Python에 대해 더 배우고, 브라우저에서 실행되는 Python 코드를 작성할 수 있다는 것입니다.
  • 실패는 경험이다
  • 작은 발걸음은 발걸음
  • 작게 시작하다
  • 큰 꿈
  • 데모를하다
  • 반복하다

Python Veloce 모드 만 사용하면 매우 기쁩니다! 그러나 그 과정에서 내가 정말로 찾고 있던 것이 자바 스크립트로부터 나와 다른 사람들을 해방시키는 것이었지만 더 중요한 것은 편안한 방식으로 만들 수 있다는 것을 발견했습니다 . 이것은 나를 Scheme, DSL, Models 그리고 결국 도메인 특정 모델 (참조 : http://dsmforum.org/ )로 이끌었습니다 .

Ira Baxter의 답변 :

추정치는 전혀 도움이되지 않습니다. PythonJS와 Pythonium 모두에 대해 6 개월 정도의 자유 시간을 가졌습니다. 그래서 나는 풀 타임 6 개월에서 더 많은 것을 기대할 수 있습니다. 저는 우리 모두가 기업 맥락에서 100 인년이 의미하는 것이 무엇인지 전혀 알고 있다고 생각합니다.

누군가가 어렵거나 더 자주 불가능하다고 말하면 "불가능한 문제에 대한 해결책을 찾는 데 시간이 걸린다"고 대답하고 그렇지 않으면 불가능하다는 것이 증명 된 경우를 제외하고는 불가능한 것이 없다고 대답합니다.

불가능하다고 증명되지 않았다면 상상의 여지가 남습니다.

  • 불가능하다는 것을 증명하는 증거 찾기

  • 불가능하다면 해결책을 가질 수있는 "열등한"문제가있을 수 있습니다.

또는

  • 불가능하지 않다면 해결책 찾기

단지 낙관적 인 생각이 아닙니다. 내가 Python-> Javascript를 시작했을 때 모두가 불가능하다고 말했습니다. PyPy는 불가능합니다. 메타 클래스가 너무 어렵습니다. 등 ... 저는 Scheme-> C 논문 (25 년 된)보다 PyPy를 가져 오는 유일한 혁명은 자동 JIT 생성 (내 생각에 RPython 인터프리터에 작성된 기반 힌트)이라고 생각합니다.

어떤 것이 "단단하다"또는 "불가능하다"고 말하는 대부분의 사람들은 그 이유를 제공하지 않습니다. C ++는 구문 분석하기 어렵습니까? 나는 여전히 그들은 (무료) C ++ 파서라는 것을 알고 있습니다. 세부 사항에 악이 있습니까? 알아요. 혼자서 불가능하다고 말하는 것은 도움이되지 않는다. "도움이되지 않는 것"보다 더 나쁘다. 그것은 낙담한다. 어떤 사람들은 다른 사람들을 낙담시킨다. /programming/22621164/how-to-automatically-generate-a-parser-code-to-code-translator-from-a-corpus 를 통해이 질문에 대해 들었습니다 .

완벽 어떤 것이 당신을 위해 ? 이것이 다음 목표를 정의하는 방법이며 전체 목표에 도달 할 수도 있습니다.

번역을 수행하는 방법보다 코드를 더 쉽게 번역 (예 : IoC, SOA?) 할 수 있도록 코드에 어떤 종류의 패턴을 적용 할 수 있는지 알고 싶습니다.

적어도 완벽하지 않은 방식으로 한 언어에서 다른 언어로 번역 할 수없는 패턴은 없습니다. 언어에서 언어로의 번역이 가능하므로 먼저 이것을 목표로하는 것이 좋습니다. http://en.wikipedia.org/wiki/Graph_isomorphism_problem 에 따르면 두 컴퓨터 언어 간의 번역은 트리 또는 DAG 동형 이라고 생각 합니다. 둘 다 튜링이 완료되었다는 것을 이미 알고 있더라도 ...

API-> API 번역으로 더 잘 시각화하는 프레임 워크-> 프레임 워크는 생성 된 코드를 개선하기위한 방법으로 여전히 염두에 두어야 할 것입니다. 예 : Prolog는 매우 구체적인 구문이지만 여전히 Python에서 동일한 그래프를 설명하여 계산과 같은 Prolog를 수행 할 수 있습니다. Prolog를 Python 변환기로 구현하려면 Python에서 통합을 구현하지 않고 C 라이브러리에서 올 수 있습니다. Pythonist가 매우 읽기 쉬운 "Python 구문"을 사용합니다. 결국 구문은 의미를 부여하는 "그림"일뿐입니다 (그래서 제가 계획을 시작한 이유입니다). 악은 언어의 세부 사항에 있으며 구문에 대해 말하는 것이 아닙니다. 언어에서 사용되는 개념getattribute후크 (이 없이도 살 수 있음)이지만 꼬리 재귀 최적화와 같은 필수 VM 기능은 처리하기 어려울 수 있습니다. 초기 프로그램이 꼬리 재귀를 사용하지 않는지 상관하지 않으며 대상 언어에 꼬리 재귀가 없더라도 greenlets / event 루프를 사용하여 에뮬레이트 할 수 있습니다.

대상 및 소스 언어의 경우 다음을 찾으십시오.

  • 크고 구체적인 아이디어
  • 작고 일반적인 공유 아이디어

이것으로부터 나타날 것입니다 :

  • 번역하기 쉬운 것
  • 번역하기 어려운 것

또한 빠르고 느린 코드로 변환되는 내용을 알 수있을 것입니다.

stdlib 또는 라이브러리에 대한 질문도 있지만 명확한 대답은 없으며 목표에 따라 다릅니다.

관용적 코드 또는 읽을 수있는 생성 코드에도 솔루션이 있습니다.

느린 경로 및 / 또는 중요한 경로의 C 구현을 제공 할 수 있으므로 PHP와 같은 플랫폼을 대상으로하는 것이 브라우저를 대상으로하는 것보다 훨씬 쉽습니다.

첫 번째 프로젝트가 Python을 PHP로 번역하고 있다는 점을 감안할 때 적어도 내가 아는 PHP3 하위 집합의 경우 veloce.py를 사용자 정의하는 것이 가장 좋습니다. PHP 용 veloce.py를 구현할 수 있다면 호환 모드를 실행할 수있을 것입니다. 또한 PHP를 PHP의 하위 집합으로 변환 할 수 있다면 php_veloce.py로 생성 할 수 있습니다. veloce.py가 사용할 수있는 Python의 하위 집합입니다. 즉, PHP를 Javascript로 번역 할 수 있습니다. 그냥 ...

해당 라이브러리를 살펴볼 수도 있습니다.

또한이 블로그 게시물 (및 의견)에 관심이있을 수 있습니다. https://www.rfk.id.au/blog/entry/pypy-js-poc-jit/


컴퓨터 언어로 번역 일대일 컴퓨터 언어에 대해 나에게 스릴 유적에 설명되어있는 유일한 stackoverflow.com/questions/22621164/...
amirouche

두 번째로 데이터 유형에 대한 다른 답변입니다. Pythonium에서는 asm.js없이 호환 모드에서 올바른 정수 및 부동 유형을 지원할 계획조차 없었습니다.
amirouche

좋아요, 제가 여러분에게 100K SLOC의 파이썬 패키지를주고 당신의 "번역기"를 통해 실행한다면, 제가 작동하는 프로그램을 얻습니까? 문제를 해결하려면 번역 후 수작업이 얼마나 필요합니까? 여기서 말씀하신 내용은 "AST를 빌드하는 기존의 좋은 Python 파서가 있다면 6 개월 안에 부분 번역기를 만들 수 있습니다."라는 것입니다. 아무도 놀라지 않습니다. 6 개월은 대부분의 사람들의 기준에 따라 "간단한"것이 아닙니다 (다른 의견에서 인용). 나머지 문제를 해결하려면 더 많은 노력이 필요합니다. 내 대답은 기본적으로 "이렇게하는 것은 쉽지 않다"고 "일반적인 방식으로하는 것은 어렵다"고 말했다.
Ira Baxter

... OP의 원래 욕구에 대한 응답의 마지막 요점 : "이상적으로는 (상대적) 쉽게 다른 언어를 추가 할 수있을 것입니다.", 내 대답은 구체적으로 설명합니다.
Ira Baxter

나는 동의하지 않기를 간청한다. 특히 당신이 무엇을하고 있는지 알고있을 때 그것은 쉽다. 나는 당신이 질문과 관련된 어떤 것을 다루고 있는지 잘 모르겠습니다. 당신은 4-5 개의 단락에서 당신의 회사가 그것을한다고 말하고 있습니다. 그러나 그렇지 않으면 주제에 대한 FUD를 퍼 뜨리고 stackoverflow.com/questions/22621164/… 에서처럼 주제에서 벗어난 상태를 유지 합니다. 6 개월 동안 나는 완전한 번역가를 썼을 것입니다.
amirouche 2014

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