Crea un linguaggio di programmazione JVM


91

Ho creato un compilatore in C (usando lex e bison) per un linguaggio di programmazione tipizzato dinamico che supporta loop, dichiarazioni di funzioni all'interno di funzioni, chiamate ricorsive ecc. Ho anche creato una macchina virtuale che esegue il codice intermedio creato dal compilatore.

Ora stavo pensando invece di compilare il mio codice intermedio, compilarlo in codice java byte.

Ho visto che la domanda sulla creazione di un linguaggio JVM è già stata posta ma non trovo la risposta molto istruttiva.

Quindi ecco le mie domande:

  1. Immagino che per creare un linguaggio per JVM sia necessario leggere il libro delle specifiche JVM , quali altri libri puoi suggerire (tranne Dragon Book ovviamente)? Sono principalmente preoccupato per i libri o le esercitazioni su come creare un linguaggio JVM, non un compilatore in generale.
  2. Esistono molte librerie Java per leggere, scrivere e modificare i file .class come jclasslib , bcel , gnu bytecode , ecc. Quale suggeriresti? Inoltre, sei a conoscenza delle librerie C che fanno lo stesso lavoro?
  3. Stavo pensando di dare un'occhiata a forse un altro linguaggio che prende di mira la JVM come Clojure, Jython o JRuby. Ma tutti questi linguaggi sono di altissimo livello e complicati (creare un compilatore per loro). Stavo cercando un linguaggio di programmazione più semplice (non mi importa se è sconosciuto o inutilizzato) che prenda di mira la JVM e il suo compilatore sia open source. Qualche idea?

Risposte:


61

Consiglierei anche ASM, ma dai un'occhiata a Jasmin , l'ho usato (o: ho dovuto usarlo) per un progetto universitario, e funziona abbastanza bene, ho scritto una combinazione lexer / parse / analizzatore / ottimizzatore / generatore per un linguaggio di programmazione che utilizza java e jasmin, generando così codice JVM. Ho caricato il codice qui , la parte interessante dovrebbe essere il codice sorgente stesso . Nella cartella "bytecode / InsanelyFastByteCodeCreator.java" trovi un pezzo di codice che trasforma un albero AST nel formato di input dell'assembler jasmin. È abbastanza semplice.

Il linguaggio sorgente (che è stato trasformato in AST da Lexer + Parser + Analyzer) è un sottoinsieme di Java chiamato MiniJava. Manca di alcune funzionalità "complicate" come ereditarietà, costruttori, metodi statici, campi / metodi privati. Nessuna di queste funzionalità è difficile da implementare, ma c'era un'altra attività per scrivere un backend X86 (quindi per generare l'assemblatore di macchine), e quelle cose tendono a diventare difficili se non si dispone di una JVM che gestisce alcune cose.

Nel caso ti chiedessi dello strano nome della classe: Il compito del progetto universitario era trasformare l'AST in un grafico SSA (quindi un grafico che rappresenta il codice di input), quindi ottimizzare il grafico e quindi trasformare il grafico in codice java byte. Erano circa 3/4 del lavoro del progetto e InsanlyFastByteCodeCreator era solo una scorciatoia per testare tutto.

Dai un'occhiata al libro "Java Virtual Machine" di Jon Meyer e Troy Downing. Questo libro fa molto riferimento al Jasmin-Assembler, è molto utile per comprendere gli interni di JVM.


Grazie per la tua risposta, darò un'occhiata a Jasmin. E inoltre sarei felice se potessi caricare la fonte in modo da poter dare un'occhiata. Riguardo al libro che hai suggerito, sembra interessante ma è fuori stampa e piuttosto vecchio :(.

Il libro però è di seconda mano molto economico. Ho trovato una copia per pochi dollari.
namin

Dai un'occhiata alla mia modifica sopra, se hai domande, sarò lieto di aiutarti.
theomega

Il collegamento al "codice sorgente stesso" è interrotto. Anche se immagino che sia prevedibile dopo 8 anni.
Llew Vallis

@ LlewVallis, se interpreto correttamente tutte le informazioni, il codice sembra essere qui: github.com/replimoc/compiler .
U880D

14

Lo scorso semestre ho frequentato un corso di "Costruzione di compilatori". Il nostro progetto era esattamente quello che volevi fare.

La lingua che ho usato per scrivere la mia lingua era Scala . Funziona su una JVM ma supporta molte funzionalità avanzate che Java non fa (ancora completamente compatibile con una JVM java pura).

Per produrre il bytecode java ho usato la libreria Scala CAFEBABE . Ben documentato e non è necessario approfondire le lezioni Java per capire cosa fare.

Oltre al libro, credo che tu possa trovare molte informazioni andando attraverso i laboratori che abbiamo fatto durante il corso.


Sembra un ottimo corso. Ti dispiacerebbe condividere le tue note o il tuo codice?
Pedro

1
Nessun problema, controllerò dove sono i miei backup e inserirò un link qui in modo che tu possa scaricarlo al più presto.
Kami

1
Perfetto, stavo cercando un corso pratico sul compilatore che si rivolge alla JVM con tutto il materiale online per lo studio autonomo.
namin

5

ASM può essere una soluzione per generare bytecode. Per iniziare, controlla gli argomenti sulla generazione di elementi dal manuale .


4

Stavo pensando di dare un'occhiata a forse un altro linguaggio che prende di mira la JVM come Clojure, Jython o JRuby. Ma tutti questi linguaggi sono di altissimo livello e complicati (creare un compilatore per loro).

Suggerimento: potresti dare un'occhiata a Lua Programming Language , ci sono implementazioni JVM come LuaJ .

Interprete Lua leggero , veloce, basato su Java, scritto per J2ME e J2SE, con librerie per pacchetti di base, stringhe, tabelle, pacchetti, math, io, os, debug e coroutine, un compilatore , collegamenti luajava e motore di scripting collegabile JSR-233 attacchi.

(Da non confondere con LuaJava che utilizza librerie native con approccio JNI.)


Grazie. Darò un'occhiata

3

Lo scorso fine settimana, mi sono posto la stessa domanda per trasferire il mio linguaggio giocattolo nella JVM.

Trascorro solo poche ore a cercare informazioni, quindi prendi questi riferimenti con le pinze.

  • Modelli di implementazione del linguaggio . Odio antlr ma questo libro sembra molto buono. Se non ti piacciono nemmeno le antlr, è molto utile analizzare "Tecniche di analisi. Una guida pratica".

    Impara a costruire lettori di file di configurazione, lettori di dati, generatori di codice basati su modello, traduttori da sorgente a sorgente, analizzatori di sorgenti e interpreti. Non è necessaria una formazione in informatica: il creatore di ANTLR Terence Parr demistifica l'implementazione del linguaggio suddividendolo nei modelli di progettazione più comuni. Modello per modello, imparerai le competenze chiave necessarie per implementare i tuoi linguaggi informatici.

    Il capitolo 10 copre in 30 pagine (per velocizzare IMO) questi argomenti. Ma ci sono altri capitoli che probabilmente ti interesseranno.

    • 10 Creazione di interpreti bytecode
      • 10.1 Programmazione interpreti Bytecode. .
      • 10.2 Definizione di una sintassi del linguaggio assembly
      • 10.3 Architettura della macchina Bytecode. . . . .
      • 10.4 Dove andare da qui. . . . . . . . . .
      • P.26. Bytecode Assembler. . . . . . . . . . .
      • P.27. Interprete Bytecode basato su stack. . .
      • P.28. Interprete Bytecode basato su registro
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • L'implementazione di Lua 5.0 Questo è un ottimo articolo sulle macchine bytecode basate su registri. Vai a leggerlo anche solo per il gusto di farlo.

    • Lisp in piccoli pezzi. Questo libro insegna come scrivere un compilatore 2 schme che compila in C. Molte lezioni possono essere apprese da questo libro. Possiedo una copia di questo libro ed è davvero buono per chiunque sia interessante è lisp, ma forse non è la tua tazza di tè.

      Questo è un resoconto completo della semantica e dell'implementazione dell'intera famiglia di linguaggi Lisp, vale a dire Lisp, Scheme e dialetti correlati. Descrive 11 interpreti e 2 compilatori ...

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

Controlla la VM Dalvik7, una VM basata su registri. Il DVM opera su bytecode che vengono trasformati dai file Java Class compilati da un compilatore Java.

C'è una mailing list sull'argomento, jvm-languages.

Hai intenzione di caricare il codice da qualche parte? Vorrei dare un'occhiata.


Are you planning to upload the code to anyplace?Non sono orgoglioso di quel codice :( ... forse riscriverei il tutto. Comunque se lo faccio ti farò sapere. Grazie mille per i tuoi suggerimenti.

2

Ti consiglio di imparare prima come funziona l'assemblaggio JVM, se non lo conosci già.

Molte istruzioni hanno la forma ?name, dove ?è ise l'istruzione funziona con un tipo intero e ase funziona con un tipo di riferimento.

Fondamentalmente, JVM è una macchina stack senza registri, quindi tutte le istruzioni funzionano con i dati direttamente sullo stack. È possibile eseguire il push / pop dei dati con ?push/?pope spostare i dati tra le variabili locali (posizioni dello stack a cui fanno riferimento gli offset) e la parte superiore dello stack utilizzando ?store/?load. Alcune altre istruzioni importanti sono invoke???e if_???.

Per il corso di compilazione della mia università abbiamo usato Jasmin per assemblare i programmi. Non so se questo sia il modo migliore, ma almeno è un punto di partenza facile.

Di seguito è riportato un riferimento di istruzioni per una vecchia versione della JVM, che potrebbe contenere meno istruzioni rispetto a una nuova.


0

Per prima cosa farei marcia indietro, modificherei il mio compilatore per produrre l'effettivo Java invece dei codici byte Java (il che significa creare più di un traduttore che del compilatore) e compilerei l'output Java con qualsiasi ambiente Java sia conveniente (che probabilmente genererebbe un codice oggetto migliore del mio compilatore).

È possibile utilizzare la stessa tecnica (ad esempio, compilare in C #) per generare codici byte CLI o compilare in Pascal per generare codice P, ecc.

Non è chiaro il motivo per cui stai considerando i codici Java invece di utilizzare la tua VM, ma se è per le prestazioni, ovviamente dovresti anche considerare la compilazione in codice macchina effettivo.


La compilazione per la JVM consentirà di eseguire il codice più ampiamente rispetto a quando si compila in codice nativo. Inoltre, la compilazione in bytecode renderà possibile al codice di fare alcune cose che non sono possibili all'interno del linguaggio Java stesso.
supercat

0

Ovviamente una volta poteva usare Java per scrivere una nuova lingua. Con l'API di riflessione Java puoi ottenere un sacco. Se la velocità non è importante, darei la preferenza a Java invece di ASM. La programmazione è più semplice e meno soggetta a errori in Java (IMHO) . Dai un'occhiata al 7 ° linguaggio RPN . È interamente scritto in Java.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.