JVM 프로그래밍 언어 만들기


91

루프, 함수 내부 함수 선언, 재귀 호출 등을 지원하는 동적 형식 프로그래밍 언어를 위해 C (lex & bison 사용)로 컴파일러를 만들었습니다. 또한 컴파일러에서 만든 중간 코드를 실행하는 가상 머신을 만들었습니다.

나는 이제 내 자신의 중간 코드로 컴파일하는 대신 자바 바이트 코드로 컴파일하는 것을 생각하고 있었다.

JVM 언어 생성에 대한 질문은 이미 것을 보았지만 그에 대한 답은 그리 유익하지 않습니다.

그래서 여기 내 질문이 있습니다.

  1. JVM에 대한 언어를 작성하려면 반드시 읽어야합니다. JVM 사양서 하다고 생각합니다. 다른 책을 제안 할 수 있습니까 (물론 Dragon Book 제외)? 저는 일반적으로 컴파일러가 아닌 JVM 언어를 만드는 방법에 대한 책이나 자습서에 주로 관심이 있습니다.
  2. jclasslib , bcel , gnu bytecode 등과 같은 .class 파일을 읽고, 쓰고, 변경할 수있는 많은 Java 라이브러리 가 있습니다. 어떤 것을 제안 하시겠습니까? 또한 동일한 작업을 수행하는 C 라이브러리를 알고 있습니까?
  3. Clojure, Jython 또는 JRuby와 같은 JVM을 대상으로하는 다른 언어를 살펴볼 생각이었습니다. 그러나 이러한 모든 언어는 매우 수준이 높고 복잡합니다. JVM을 대상으로하는 더 간단한 프로그래밍 언어 (알 수 없거나 사용되지 않은 경우 상관 없음)를 찾고 있었으며 컴파일러는 오픈 소스입니다. 어떤 아이디어?

답변:


61

나는 또한 ASM을 추천하고 싶지만 Jasmin을 살펴 보았고 대학 프로젝트에 사용했고 (또는 사용해야했고) 꽤 잘 작동했고, Java와 jasmin을 사용하는 프로그래밍 언어이므로 JVM 코드를 생성합니다. 여기 에 코드를 업로드했는데 흥미로운 부분은 소스 코드 자체 여야합니다. . "bytecode / InsanelyFastByteCodeCreator.java"폴더에서 AST 트리를 재스민 어셈블러의 입력 형식으로 변환하는 코드를 찾을 수 있습니다. 아주 간단합니다.

소스 언어 (Lexer + Parser + Analyzer에 의해 AST로 변환 됨)는 MiniJava라는 Java의 하위 집합입니다. 상속, 생성자, 정적 메서드, 개인 필드 / 메서드와 같은 일부 "복잡한"기능이 없습니다. 이러한 기능 중 구현하기 어려운 것은 없지만 X86 백엔드를 작성하는 또 다른 작업이있었습니다 (따라서 머신 어셈블러를 생성하기 위해). 이러한 기능은 일부 작업을 처리하는 JVM이 없으면 어려워지는 경향이 있습니다.

이상한 클래스 이름이 궁금한 경우 : 대학 프로젝트의 작업은 AST를 SSA 그래프 (입력 코드를 나타내는 그래프)로 변환 한 다음 그래프를 최적화 한 다음 그래프를 자바 바이트 코드로 바꾸는 것이 었습니다 . 이것은 프로젝트 작업의 약 3/4이었고 InsanlyFastByteCodeCreator는 모든 것을 테스트하는 지름길이었습니다.

Jon Meyer와 Troy Downing의 "Java Virtual Machine"책을 살펴보십시오. 이 책은 Jasmin-Assembler를 많이 참조하므로 JVM 내부를 이해하는 데 매우 유용합니다.


답변 해 주셔서 감사합니다. Jasmin을 살펴 보겠습니다. 그리고 제가 볼 수 있도록 소스를 업로드 해주시면 기쁩니다. 당신이 제안한 책에 관해서는 흥미로워 보이지만 절판되었고 꽤 오래되었습니다. :(.

이 책은 매우 저렴한 중고품입니다. 몇 달러에 대한 사본을 찾았습니다.
namin 2010-08-03

위의 편집 내용을 살펴보십시오. 질문이 있으시면 기꺼이 도와 드리겠습니다.
theomega 2010-08-03

"소스 코드 자체"에 대한 링크가 끊어졌습니다. 8 년 후에는 예상 할 수 있겠지만.
Llew Vallis

@LlewVallis, 모든 정보를 올바르게 해석하면 코드가 여기에있는 것 같습니다 : github.com/replimoc/compiler .
U880D

14

지난 학기에 "컴파일러 구성"과정에 참석했습니다. 우리 프로젝트는 정확히 당신이하고 싶은 일이었습니다.

제 언어를 작성하는 데 사용한 언어는 Scala 입니다. JVM에서 실행되지만 Java가 지원하지 않는 많은 고급 기능을 지원합니다 (여전히 순수 Java JVM과 완전히 호환 됨).

Java 바이트 코드를 출력하기 위해 Scala CAFEBABE 라이브러리를 사용했습니다 . 잘 문서화되어 있으며 수행 할 작업을 이해하기 위해 Java 클래스에 깊이 들어갈 필요가 없습니다.

책 이외에도 우리가 과정 중에 수행 한 실습 을 통해 많은 정보를 찾을 수 있다고 생각합니다 .


이것은 훌륭한 코스처럼 들립니다. 메모 나 코드를 공유 하시겠습니까?
Pedro

1
문제 없습니다. 백업이 어디에 있는지 확인하고 여기에 링크를 게시하여 최대한 빨리 다운로드 할 수 있습니다.
Kami

1
깔끔하게, 저는 자습을 위해 온라인으로 모든 자료와 함께 JVM을 대상으로하는 실습 컴파일러 과정을 찾고있었습니다.
namin 2010-08-03

5

ASM 은 바이트 코드 생성을위한 솔루션이 될 수 있습니다. 시작하려면 매뉴얼 에서 요소 생성에 대한 주제를 확인하십시오 .


4

Clojure, Jython 또는 JRuby와 같은 JVM을 대상으로하는 다른 언어를 살펴볼 생각이었습니다. 그러나 이러한 모든 언어는 매우 수준이 높고 복잡합니다.

제안 : Lua Programming Language를 살펴볼 수 있으며 LuaJ 와 같은 JVM 구현이 있습니다 .

기본, 문자열, 테이블, 패키지, 수학, io, os, 디버그 및 코 루틴 패키지, 컴파일러 , luajava 바인딩 및 JSR-233 플러그 형 스크립팅 엔진을 위한 라이브러리를 포함하여 J2ME 및 J2SE 용으로 작성된 가볍고 빠른 Java 중심 Lua 인터프리터 바인딩.

(JNI 접근 방식으로 네이티브 라이브러리를 사용하는 LuaJava와 혼동하지 마십시오.)


감사합니다. 제가 살펴볼 것입니다

3

지난 주말, 장난감 언어를 JVM으로 이식하는 것과 같은 질문을했습니다.

정보를 검색하는 데 몇 시간 밖에 걸리지 않으므로이 참고 자료를 염두에 두십시오.

  • 언어 구현 패턴 . 나는 개미를 싫어하지만이 책은 아주 좋아 보인다. antlr도 좋아하지 않는다면 "Parsing Techniques. A Practical Guide"를 구문 분석하는 것이 좋습니다.

    구성 파일 판독기, 데이터 판독기, 모델 기반 코드 생성기, 소스-소스 변환기, 소스 분석기 및 인터프리터를 구축하는 방법을 배웁니다. 컴퓨터 과학에 대한 배경 지식이 필요하지 않습니다. ANTLR 제작자 인 Terence Parr는 언어 구현을 가장 일반적인 디자인 패턴으로 분류하여 설명합니다. 패턴 별 패턴을 통해 자신의 컴퓨터 언어를 구현하는 데 필요한 핵심 기술을 배우게됩니다.

    10 장은이 주제를 30 페이지 (고속 IMO)로 다룹니다. 그러나 아마도 당신이 관심을 가질만한 다른 장이 있습니다.

    • 10 바이트 코드 인터프리터 구축
      • 10.1 바이트 코드 해석기 프로그래밍. .
      • 10.2 어셈블리 언어 구문 정의
      • 10.3 바이트 코드 머신 아키텍처. . . . .
      • 10.4 여기에서 이동할 위치. . . . . . . . . .
      • P.26. 바이트 코드 어셈블러. . . . . . . . . . .
      • P.27. 스택 기반 바이트 코드 인터프리터. . .
      • 28 페이지. 레지스터 기반 바이트 코드 인터프리터
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • Lua 5.0의 구현 이것은 레지스터 기반 바이트 코드 기계에 대한 훌륭한 문서입니다. 그것을 위해서도 그것을 읽으십시오.

    • 작은 조각의 Lisp. 이 책은 C로 컴파일되는 2 개의 schme 컴파일러를 작성하는 방법을 알려줍니다.이 책에서 많은 교훈을 배울 수 있습니다. 나는이 책의 사본을 소유하고 있으며 흥미로운 사람에게는 정말 좋은 것이 lisp이지만 아마도 당신의 차 한잔은 아닐 것입니다.

      이것은 의미론과 전체 Lisp 계열 언어, 즉 Lisp, Scheme 및 관련 방언의 구현에 대한 포괄적 인 설명입니다. 11 개의 인터프리터와 2 개의 컴파일러를 설명합니다 ...

    http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521562473

레지스터 기반 VM 인 Dalvik7 VM을 확인합니다. DVM은 Java 컴파일러에 의해 컴파일 된 Java 클래스 파일에서 변환 된 바이트 코드에서 작동합니다.

주제 jvm-languages에 대한 메일 링리스트가 있습니다.

아무 곳에 나 코드를 업로드 할 계획입니까? 제가 살펴보고 싶습니다.


Are you planning to upload the code to anyplace?나는 그 코드가 자랑스럽지 않다 :( ... 아마 전체를 다시 작성할 것입니다. 어쨌든 내가 그렇게한다면 알려 드리겠습니다. 제안 해 주셔서 대단히 감사합니다.

2

아직 모르는 경우 JVM 어셈블리의 작동 방식을 먼저 배우는 것이 좋습니다.

많은 지침 양식을 가지고 ?name, 어디 ?이며 i명령이 정수 유형에서 작동하는 경우a 는 참조 형식으로 작동하는 경우입니다.

기본적으로 JVM은 레지스터가없는 스택 머신이므로 모든 명령어는 스택에서 직접 데이터와 함께 작동합니다. 를 사용 ?push/?pop하여 로컬 변수 (오프셋으로 참조되는 스택 위치)와 스택 상단 사이에서 데이터를 푸시 / 팝 하고 이동할 수 있습니다 ?store/?load. 다른 중요한 지침은 다음 invoke???과 같습니다.if_??? 입니다.

들어 내 대학의 컴파일러 물론 우리가 사용 재스민을 프로그램을 조립. 이것이 최선의 방법인지는 모르겠지만 적어도 시작하기 쉬운 곳입니다.

다음은 새 버전보다 적은 수의 명령어를 포함 할 수있는 이전 버전의 JVM에 대한 명령어 참조 입니다.


0

먼저 저는 뒤로 물러나서 Java 바이트 코드 대신 실제 Java를 출력하도록 컴파일러를 수정하고 (컴파일러보다 변환기를 더 많이 생성 함을 의미 함) 편리한 Java 환경 (더 나은 객체 코드를 생성 할 수 있음)으로 Java 출력을 컴파일합니다. 내 컴파일러보다).

동일한 기술 (예 : C #으로 컴파일)을 사용하여 CLI 바이트 코드를 생성하거나 Pascal로 컴파일하여 P 코드 등을 생성 할 수 있습니다.

자신의 VM을 사용하는 대신 Java 코드를 고려하는 이유는 명확하지 않지만 성능을 고려한다면 물론 실제 기계 코드로 컴파일하는 것도 고려해야합니다.


JVM 용으로 컴파일하면 네이티브 코드로 컴파일하는 것보다 코드를 더 광범위하게 실행할 수 있습니다. 또한, 바이트 코드로 컴파일하면 코드가 Java 언어 자체에서는 불가능한 작업을 수행 할 수 있습니다.
supercat

0

물론 한 번 Java를 사용하여 새 언어를 작성할 수 있습니다. 자바 리플렉션 API를 사용하면 많은 것을 얻을 수 있습니다. 속도가 너무 중요하지 않다면 ASM 대신 Java를 선호합니다. 프로그래밍은 Java (IMHO) 에서 더 쉽고 오류가 발생하기 쉽습니다 . RPN 언어 7 번째를 살펴보십시오 . 전적으로 Java로 작성되었습니다.

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