Bir JVM programlama dili oluşturmaya nasıl yaklaşılır?


94

Döngüleri, işlevler içindeki işlev bildirimlerini, özyinelemeli çağrıları vb. Destekleyen dinamik tipte bir programlama dili için C'de (Lex & Bison kullanarak) bir derleyici oluşturdum. Ayrıca derleyici tarafından oluşturulan ara kodu çalıştıran bir sanal makine de yarattım.

Kendi ara kodum yerine Java bayt koduna derlemeyi düşünüyordum.

Bir JVM dili oluşturmayla ilgili sorunun zaten sorulduğunu gördüm, ancak cevabı çok bilgilendirici bulmuyorum.

Sorularım işte burada:

  1. Sanırım JVM için bir dil oluşturmak için bir zorunluluk JVM şartname kitabını okumaktır, başka hangi kitapları önerebilirsiniz (tabii ki Dragon Book hariç)? Genel olarak bir derleyici değil, bir JVM dilinin nasıl oluşturulacağıyla ilgili kitaplar veya öğreticilerle ilgileniyorum.
  2. .classDosyaları okumak, yazmak ve değiştirmek için jclasslib , bcel , gnu bayt kodu vb. Gibi birçok Java kitaplığı vardır . Hangisini önerirsiniz? Ayrıca, aynı işi yapan C kütüphanelerinin farkında mısınız?
  3. Clojure, Jython veya JRuby gibi JVM'yi hedefleyen başka bir dile bakmayı düşünüyordum. Ancak tüm bu diller çok yüksek seviyeli ve karmaşıktır (onlar için bir derleyici oluşturmak için). JVM'yi hedefleyen daha basit (bilinmeyen veya kullanılmayan) bir programlama dili arıyordum ve derleyicisi açık kaynak. Herhangi bir fikir?

Yanıtlar:


64

Ayrıca ASM tavsiye ama bir göz olurdu Jasmin , kullandım (daha doğrusu kullanmak zorunda) bir üniversite projesi için, ve oldukça iyi çalıştı. Java ve Jasmin kullanan bir programlama dili için lexer-parser-analyzer-optimizer-generator kombinasyonu yazdım, bu yüzden JVM Kodu oluşturuyordu. Kodu buraya yükledim ; ilginç kısım, kaynak kodun kendisi olmalıdır . Klasörde bytecode/InsanelyFastByteCodeCreator.java, AST Ağacını Jasmin assembler giriş formatına dönüştüren bir kod parçası bulacaksınız. Oldukça basit.

Kaynak dil (lexer-parser-analyzer tarafından AST'ye dönüştürülmüş olan) MiniJava adı verilen bir Java alt kümesidir. Kalıtım, yapıcılar, statik yöntemler, özel alanlar ve yöntemler gibi bazı "karmaşık" özelliklerden yoksundur. Bu özelliklerin hiçbirinin uygulanması zor değildir, ancak bir x86 arka uç yazmak için başka bir görev vardı (yani makine derleyicisi oluşturmak için) ve bu şeylerden bazılarını yöneten JVM'niz yoksa bu şeyler zorlaşabilir.

Tuhaf sınıf adını merak ediyorsanız: Üniversite projesinin görevi, AST'yi bir SSA Grafiğine (giriş kodunu temsil eden) dönüştürmek, grafiği optimize etmek ve ardından Java bayt koduna dönüştürmekti. Bu, projenin çalışmasının yaklaşık'ü kadardı ve InsanlyFastByteCodeCreatorher şeyi test etmek için sadece bir kestirme yoldu.

Jon Meyer ve Troy Downing'in "Java Virtual Machine" kitabına bir göz atın. Bu kitap, Jasmin Assembler'a yoğun bir şekilde atıfta bulunuyor; JVM'nin iç özelliklerini anlamak için oldukça yararlıdır.


Cevabınız için teşekkürler, Jasmin'e bir göz atacağım. Ayrıca bir göz atabilmem için kaynağı yüklerseniz sevinirim. Önerdiğiniz kitap hakkında ilginç görünüyor, ancak baskısı yok ve oldukça eski :(.

Kitap çok ucuz ikinci el. Birkaç dolara bir kopya buldum.
namin

Yukarıdaki düzenlememe bir göz atın, herhangi bir sorunuz varsa yardımcı olmaktan memnuniyet duyarız.
theomega

"Kaynak kodun kendisine" bağlantısı kesildi. Sanırım bu 8 yıl sonra bekleniyor.
Llew Vallis

@LlewVallis, tüm bilgileri doğru yorumlarsam, kod burada görünüyor: github.com/replimoc/compiler .
U880D

15

Geçen dönem "Derleyici İnşaat" kursuna katıldım. Bizim projemiz tam da yapmak istediğiniz şeydi.

Dilimi yazmak için kullandığım dil Scala idi . Bir JVM üzerinde çalışır ancak Java'nın desteklemediği birçok gelişmiş özelliği destekler (yine de saf bir java JVM ile tam uyumludur).

Java bayt kodunu çıkarmak için Scala CAFEBABE kitaplığını kullandım . İyi belgelenmiş ve ne yapacağınızı anlamak için java derslerinin derinliklerine inmeniz gerekmiyor.

Kitabın yanı sıra, kurs boyunca yaptığımız laboratuarları inceleyerek birçok bilgi bulabileceğinizi düşünüyorum .


Bu harika bir kurs gibi görünüyor. Notlarınızı veya kodunuzu paylaşabilir misiniz?
Pedro

1
Sorun değil, yedeklerimin nerede olduğunu kontrol edeceğim ve en kısa sürede indirebilmeniz için buraya bir bağlantı göndereceğim.
Kami

1
Neat, kendi kendine çalışma için tüm çevrimiçi materyallerle JVM'yi hedefleyen uygulamalı bir derleyici kursu arıyordum.
namin


4

Clojure, Jython veya JRuby gibi JVM'yi hedefleyen başka bir dile bakmayı düşünüyordum. Ancak tüm bu diller çok yüksek seviyeli ve karmaşıktır (onlar için bir derleyici oluşturmak için).

Öneri: Lua Programlama Diline bir göz atabilirsiniz, LuaJ gibi JVM uygulamaları var .

J2ME ve J2SE için yazılmış hafif , hızlı, Java merkezli Lua yorumlayıcı , temel, dize, tablo, paket, matematik, io, os, hata ayıklama ve coroutine paketleri için kitaplıklar, bir derleyici , luajava bağlamaları ve JSR-233 takılabilir komut dosyası oluşturma motoru bağlamalar.

(JNI yaklaşımı ile yerel bir kitaplık kullanan LuaJava ile karıştırılmamalıdır.)


Teşekkür ederim. Bir göz atacağım

4

Geçen hafta sonu, oyuncak dilimi JVM'ye taşımak için kendime aynı soruyu soruyordum.

Bilgi aramak için sadece birkaç saat harcıyorum, bu yüzden bu referansları biraz tuzlu bir şekilde ele alın.

  • Dil Uygulama Kalıpları . Antlr'den nefret ediyorum ama bu kitap çok iyi görünüyor. Antlr'ı da sevmiyorsanız, "Ayrıştırma Teknikleri. Pratik Bir Kılavuz" ayrıştırmanın çok iyi bir yanı var.

    Yapılandırma dosyası okuyucuları, veri okuyucuları, modele dayalı kod oluşturucular, kaynaktan kaynağa çevirmenler, kaynak çözümleyiciler ve yorumlayıcılar oluşturmayı öğrenin. Bilgisayar biliminde bir geçmişe ihtiyacınız yok — ANTLR yaratıcısı Terence Parr, dil uygulamasını en yaygın tasarım modellerine bölerek açıklığa kavuşturuyor. Desen desen, kendi bilgisayar dillerinizi uygulamak için ihtiyaç duyduğunuz temel becerileri öğreneceksiniz.

    Bölüm 10, 30 sayfada (hızlı IMO'ya) bu konuları kapsar. Ama muhtemelen ilgileneceğiniz başka bölümler de var.

    • 10 Bytecode Yorumlayıcı Oluşturma
      • 10.1 Bayt Kodu Yorumlayıcılarını Programlama. .
      • 10.2 Bir Assembly Dili Sözdizimi Tanımlama
      • 10.3 Bytecode Makine Mimarisi. . . . .
      • 10.4 Buradan Nereye Gidilir. . . . . . . . . .
      • S.26. Bytecode Assembler. . . . . . . . . . .
      • S.27. Yığın Tabanlı Bytecode Yorumlayıcı. . .
      • S.28. Kayıt Tabanlı Bytecode Yorumlayıcı
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • Lua 5.0 Uygulaması Bu, kayıt tabanlı bayt kodu makineleri hakkında harika bir makale. Git ve uğruna bile oku.

    • Küçük Parçalarda Lisp. Bu kitap, C'ye derlenen 2 schme derleyicisinin nasıl yazılacağını öğretir. Bu kitaptan pek çok ders çıkarılabilir. Bu kitabın bir kopyasına sahibim ve peltek merak edenler için gerçekten çok iyi, ama belki de sizin fincan çayınız değil.

      Bu, tüm Lisp dil ​​ailesinin, yani Lisp, Scheme ve ilgili lehçelerin anlambiliminin ve uygulamasının kapsamlı bir açıklamasıdır. 11 yorumlayıcı ve 2 derleyiciyi tanımlar ...

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

Kayıt tabanlı bir sanal makine olan Dalvik7 sanal makinesini kontrol edin. DVM, bir Java derleyicisi tarafından derlenen Java Sınıfı dosyalarından dönüştürülen bayt kodlarında çalışır.

Konuyla ilgili jvm dilleri için bir posta listesi var.

Kodu herhangi bir yere yüklemeyi planlıyor musunuz? Bir göz atmak istiyorum


Are you planning to upload the code to anyplace?Bu kodla gurur duymuyorum :( ... Belki her şeyi yeniden yazarım. Her neyse, yaparsam sana haber veririm. Önerileriniz için çok teşekkür ederim.

2

Henüz bilmiyorsanız, önce JVM montajının nasıl çalıştığını öğrenmenizi tavsiye ederim.

Birçok talimatlar form var ?name, ?bir italimat bir tamsayı türü ile çalışır ve eğer abu bir referans türü ile çalışır eğer.

Temel olarak JVM, kaydı olmayan bir yığın makinesidir, bu nedenle tüm talimatlar doğrudan yığın üzerindeki verilerle çalışır. ?push/?popVerileri yerel değişkenlerle (ofsetlerle referans verilen yığın konumları) ve kullanarak yığının tepesiyle itebilir / aktarabilirsiniz ?store/?load. Diğer bazı önemli talimatlar invoke???ve if_???.

İçin benim üniversitenin derleyici elbette kullandığımız Jasmin programları monte etmek. En iyi yol bu mu bilmiyorum ama en azından başlamak için kolay bir yer.

Yeni bir komuttan daha az talimat içerebilen eski bir JVM sürümü için bir talimat referansı burada verilmiştir.


0

Öncelikle geri çekilir, derleyicimi Java bayt kodları yerine gerçek Java çıktısını alacak şekilde değiştirirdim (bu, derleyiciden daha fazla bir çevirmen oluşturmak anlamına gelir) ve Java çıktısını uygun olan Java ortamı ile derler (muhtemelen daha iyi nesne kodu oluşturur) kendi derleyicimden).

CLI bayt kodları oluşturmak için aynı tekniği (örneğin, C # için derleme) kullanabilir veya P kodunu oluşturmak için Pascal'a derleyebilirsiniz, vb.

Neden kendi sanal makinenizi kullanmak yerine Java kodlarını düşündüğünüz net değil, ancak performans içinse, tabii ki gerçek makine koduna derlemeyi de düşünmelisiniz.


JVM için derleme, kişinin kodunun yerel koda göre derlenmesinden daha geniş çapta çalıştırılmasına izin verecektir. Ayrıca, bayt koduna derlemek, kodun Java dilinin kendi içinde mümkün olmayan bazı şeyleri yapmasını mümkün kılacaktır.
supercat

0

Elbette bir zamanlar Java'yı yeni bir dil yazmak için kullanabilirdi. Java yansıma API'si ile bir llot elde edebilirsiniz. Hız çok önemli değilse, ASM yerine Java'yı tercih ederim. Java'da (IMHO) programlama daha kolaydır ve daha az hataya açıktır . 7. RPN diline bir göz atın . Tamamen Java ile yazılmıştır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.