web-dev-qa-db-fra.com

Créer un langage de programmation JVM

J'ai créé un compilateur en C (utilisant Lex & bison) pour un langage de programmation dynamique typé qui prend en charge les boucles, les déclarations de fonctions dans les fonctions, les appels récursifs, etc. J'ai également créé une machine virtuelle qui exécute le code intermédiaire créé par le compilateur.

Je pensais maintenant, au lieu de compiler mon propre code intermédiaire, le compiler en code octet Java. 

J'ai vu que la question sur la création d'un langage JVM a déjà été demandé mais je ne trouve pas la réponse très informative.

Donc, voici mes questions: 

  1. Je suppose que pour créer un langage pour la machine virtuelle Java, il est indispensable de lire le livre spécification JVM . Quels autres livres pouvez-vous suggérer (à l'exception de Dragon Book, bien sûr)? Je suis surtout préoccupé par les livres ou les tutoriels sur la création d'un langage JVM, et non par un compilateur en général.
  2. Il existe de nombreuses bibliothèques Java pour lire, écrire et modifier des fichiers .class tels que jclasslib , bcel , gnu bytecode , etc. Lequel proposeriez-vous? De plus, connaissez-vous des bibliothèques C qui font le même travail?
  3. Je pensais à peut-être jeter un coup d'œil à un autre langage qui cible la machine virtuelle Java, comme Clojure, Jython ou JRuby. Mais tous ces langages sont de très haut niveau et compliqués (créer un compilateur pour eux). Je recherchais un langage de programmation plus simple (peu importe si c'est inconnu ou non utilisé) qui cible la machine virtuelle Java et son compilateur est open source. Des idées?
87
functional

Je recommanderais également ASM, mais jetez un œil à Jasmin , je l’ai utilisé (ou: ai dû l’utiliser) pour un projet universitaire, et cela fonctionne assez bien, j’ai écrit un lexer/parse/analyseur/optimiseur combinaison générateur/générateur pour un langage de programmation utilisant Java et jasmin, générant ainsi du code JVM. J'ai téléchargé le code ici , la partie intéressante devrait être le code-source lui-même . Dans le dossier "bytecode/InsanelyFastByteCodeCreator.Java", vous trouverez un fragment de code qui transforme un arbre AST dans le format d'entrée de jasmin assembler. Est assez simple.

Le langage source (qui a été transformé en AST par Lexer + Parser + Analyzer) est un sous-ensemble de Java appelé MiniJava. Il manque certaines fonctionnalités "compliquées" comme l'héritage, les constructeurs, les méthodes statiques, les champs privés/méthodes. Aucune de ces fonctionnalités n'est difficile à implémenter, mais il y avait une autre tâche d'écrire un backend X86 (donc de générer machine-assembleur), et ces choses ont tendance à devenir difficile si vous n'avez pas de machine virtuelle qui gère certaines choses.

Si vous vous interrogez sur le nom étrange de la classe: le projet de l'université consistait à transformer le AST en aa SSA Graph (donc un graphique représentant le code d'entrée), puis d'optimiser la graphique et ensuite transformer le graphique en code octet Java. Cela représentait environ les trois quarts du travail du projet et InsanlyFastByteCodeCreator n'était qu'un raccourci pour tout tester.

Consultez le livre "Java Virtual Machine" de Jon Meyer et Troy Downing. Ce livre fait largement référence à Jasmin-Assembler, il est très utile pour comprendre les éléments internes de la machine virtuelle Java.

58
theomega

Le semestre dernier, j'ai suivi un cours "Compiler Construction". Notre projet était exactement ce que vous voulez faire.

La langue que j'ai utilisée pour écrire ma langue était Scala . Il fonctionne sur une machine virtuelle, mais prend en charge de nombreuses fonctionnalités avancées non prises en charge par Java (encore pleinement compatible avec une machine virtuelle Java pure).

Pour sortir du code Java, j'ai utilisé la bibliothèque Scala CAFEBABE . Bien documenté et il n'est pas nécessaire d'aller au fond des classes Java pour comprendre quoi faire.

A côté du livre, je pense que vous pouvez trouver beaucoup d’informations en parcourant les laboratoires que nous avons réalisés pendant le cours.

10
Kami

ASM peut être une solution pour générer du bytecode. Pour commencer, consultez les rubriques sur la génération de éléments à partir du manual .

4
h3xStream

Je pensais à regarder peut-être une autre langue qui cible la machine virtuelle Java comme Clojure, Jython ou JRuby. Mais tout ces langues sont de très haut niveau et compliqué (créer un compilateur pour eux).

Suggestion: Vous pourriez jeter un oeil sur Lua Programming Language , il existe des implémentations JVM comme LuaJ

Léger, rapide, Lua , Centré sur Java. interpreter écrit pour J2ME et J2SE, avec des bibliothèques pour basic, string, table, paquet, maths, io, os, débogage et coroutine packages, un compiler, liaisons luajava, et JSR-233 liaisons de moteur de script enfichables.

(À ne pas confondre avec LuaJava qui utilise une bibliothèque native avec une approche JNI.)}

3
bakkal

Le week-end dernier, je me posais la même question pour transférer mon langage de jouet sur la machine virtuelle Java. 

Je ne passe que quelques heures à rechercher des informations, prenez donc ces références avec un grain de sel. 

  • Modèles d'implémentation du langage. Je déteste tous mais ce livre a l’air très bon. Si vous n’aimez ni l’un ni l’autre, c’est un très bon sujet de l’analyse "Techniques d’analyse. Un guide pratique". 

    Apprenez à créer des lecteurs de fichiers de configuration, des lecteurs de données, des générateurs de code basés sur un modèle, des traducteurs de source à source, des analyseurs de source et des interprètes. Vous n'avez pas besoin de connaissances en informatique - Terence Parr, créateur d'ANTLR, démystifie l'implémentation du langage en le décomposant en modèles de conception les plus courants. Modèle par modèle, vous apprendrez les compétences clés dont vous avez besoin pour mettre en œuvre vos propres langages informatiques.

    Le chapitre 10 couvre en 30 pages (to fast IMO) ces sujets. Mais il y a un autre chapitre qui vous intéressera probablement. 

    • 10 Construire des interpréteurs de code-octets
      • 10.1 Programmation des interpréteurs de code-octet. .
      • 10.2 Définir une syntaxe de langage d'assemblage
      • 10.3 Architecture de machine à code octet. . . . .
      • 10.4 Où aller d'ici. . . . . . . . . .
      • P.26. Assembleur de Bytecode. . . . . . . . . . .
      • P.27. Interpréteur de Bytecode basé sur la pile. . .
      • P.28. Interpréteur de code-octets basé sur un registre
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • L’implémentation de Lua 5.0 C’est un excellent article sur les machines de bytecode à registre - Allez-y même pour le plaisir de le lire. 

    • LISP en petites pièces. Ce livre explique comment écrire un compilateur à 2 schémas qui est compilé en C. On peut tirer de nombreuses leçons de ce livre. Je possède un exemplaire de ce livre et il est vraiment bon pour quiconque est intéressant est LISP, mais peut-être pas votre tasse de thé. 

      Ceci est un compte rendu complet de la sémantique et de la mise en œuvre de toute la famille de langues du LISP, à savoir le LISP, le schéma et les dialectes associés. Il décrit 11 interprètes et 2 compilateurs ... 

    http://www.Amazon.com/LISP-Small-Pieces-Christian-Queinnec/dp/0521562473

Vérifiez la machine virtuelle Dalvik7, une machine virtuelle basée sur des registres. Le DVM fonctionne sur des bytecodes qui sont transformés à partir des fichiers de classe Java compilés par un compilateur Java. 

Il existe une liste de diffusion sur le sujet, jvm-languages. 

Envisagez-vous de télécharger le code ailleurs? Je voudrais jeter un coup d'oeil.

2
Pedro

La meilleure ressource pour le début pourrait être La présentation de Ola Bini . Prenez les diapositives aussi.

1
lisak

Je vous recommanderais d’apprendre d’abord le fonctionnement de JVM Assembly, si vous ne le connaissez pas déjà.

De nombreuses instructions ont la forme ?name, où ? est i si l'instruction fonctionne avec un type entier et a si elle fonctionne avec un type de référence.

Fondamentalement, la machine virtuelle Java est une machine à pile sans registres, de sorte que toutes les instructions fonctionnent avec des données directement sur la pile. Vous pouvez pousser/extraire des données avec ?push/?pop et déplacer des données entre des variables locales (emplacements de pile référencés par des décalages) et le haut de la pile à l'aide de ?store/?load. invoke??? et if_??? sont quelques autres instructions importantes.

Pour le cours de compilation de mon université nous avons utilisé Jasmin pour assembler les programmes. Je ne sais pas si c'est la meilleure façon, mais au moins c'est un endroit facile pour commencer.

Voici une référence d'instruction pour une ancienne version de la machine virtuelle Java, qui peut contenir moins d'instructions qu'une nouvelle.

1
Jørgen Fogh

Bien sûr, une fois pourrait utiliser Java pour écrire un nouveau langage. Avec l'API de réflexion Java, vous pouvez accomplir beaucoup de choses. Si la vitesse ne compte pas trop, je donnerais la préférence à Java au lieu de ASM. La programmation est plus facile et moins sujette aux erreurs avec Java (IMHO). Jetez un coup d'œil au langage RPN 7th . Il est entièrement écrit en Java.

0
Kaplan

Tout d'abord, je me retirais, je modifiais mon compilateur pour produire du code Java à la place des codes d'octets Java (ce qui signifie créer plus d'un traducteur que du compilateur), et je compilais la sortie Java avec l'environnement de travail quelconque (ce qui générerait probablement un meilleur code objet que mon propre compilateur).

Vous pouvez utiliser la même technique (par exemple, compiler en C #) pour générer des codes d'octet CLI, ou compiler en Pascal pour générer du code P, etc.

La raison pour laquelle vous envisagez d'utiliser des codes Java au lieu d'utiliser votre propre ordinateur virtuel n'est pas claire, mais si c'est pour des performances optimales, vous devriez bien sûr également envisager de le compiler en code machine réel.

0
joe snyder