tutorial traduccion programacion lenguaje compiler-construction programming-languages jvm jvm-languages

compiler-construction - programacion - groovy traduccion



Crear un lenguaje de programación JVM (8)

Creé un compilador en C (utilizando lex y bison) para un lenguaje de programación de tipo dinámico que admite bucles, declaraciones de funciones dentro de funciones, llamadas recursivas, etc. También creé una máquina virtual que ejecuta el código intermedio creado por el compilador.

Ahora estaba pensando en lugar de compilar en mi propio código intermedio, compilarlo en el código de byte de Java.

Vi que la pregunta sobre la creación de un lenguaje JVM ya se ha asked pero no encuentro la respuesta muy informativa.

Asi que aqui están mis preguntas:

  1. Supongo que para crear un lenguaje para JVM es imprescindible leer el libro de especificaciones de JVM , ¿qué otros libros puedes sugerir (excepto Dragon Book, por supuesto)? Me preocupan principalmente los libros o tutoriales sobre cómo crear un lenguaje JVM, no un compilador en general.
  2. Hay muchas bibliotecas de Java para leer, escribir y cambiar archivos .class como jclasslib , bcel , gnu bytecode , etc. ¿Cuál sugeriría usted? Además, ¿conoce las bibliotecas C que hacen el mismo trabajo?
  3. Estaba pensando en echar un vistazo a otro lenguaje que se dirige a la JVM como Clojure, Jython o JRuby. Pero todos estos lenguajes son de muy alto nivel y complicado (para crear un compilador para ellos). Estaba buscando un lenguaje de programación más simple (no me importa si es desconocido o no utilizado) que se dirige a la JVM y su compilador es de código abierto. ¿Algunas ideas?

Estaba pensando en echar un vistazo a tal vez otro lenguaje que se dirige a la JVM como Clojure, Jython o JRuby. Pero todos estos lenguajes son de muy alto nivel y complicado (para crear un compilador para ellos).

Sugerencia: podría echarle un vistazo al lenguaje de programación Lua , hay implementaciones de JVM como LuaJ .

Lua, ligero , rápido, intérprete de Lua escrito en Java para J2ME y J2SE, con bibliotecas para paquetes básicos, de cadenas, tablas, paquetes, matemáticos, io, os, debug y coroutine, un compilador , enlaces luajava y un motor de scripts conectable JSR-233 enlaces

(No debe confundirse con LuaJava que usa un libs nativo con el enfoque JNI).


El último semestre asistí a un curso de "Construcción de compiladores". Nuestro proyecto fue exactamente lo que quieres hacer.

El lenguaje que he usado para escribir mi idioma era Scala . Se ejecuta en una JVM pero admite muchas características avanzadas que Java no (aún totalmente compatible con una JVM Java pura).

Para enviar un bytecode java, he usado la biblioteca Scala CAFEBABE . Bien documentado y no tienes que profundizar en las clases de Java para entender qué hacer.

Además del libro, creo que puedes encontrar mucha información yendo a través de los labs que hemos realizado durante el curso.


El fin de semana pasado, me estaba haciendo la misma pregunta para transferir mi lenguaje de juguete a la JVM.

Paso pocas horas buscando información, así que tome estas referencias con un grano de sal.

  • Patrones de implementación del lenguaje . Odio antlr, pero este libro se ve muy bien. Si no te gusta antlr tampoco, hay una muy buena para analizar "Técnicas de análisis. Una guía práctica".

    Aprenda a construir lectores de archivos de configuración, lectores de datos, generadores de códigos basados ​​en modelos, traductores fuente-fuente, analizadores de fuentes e intérpretes. No necesitas formación en informática: el creador de ANTLR, Terence Parr, desmitifica la implementación del lenguaje descomponiéndolo en los patrones de diseño más comunes. Patrón por patrón, aprenderá las habilidades clave que necesita para implementar sus propios lenguajes de programación.

    El Capítulo 10 cubre en 30 páginas (para IMO rápido) estos temas. Pero hay otro capítulo que probablemente te interese.

    • 10 Construyendo intérpretes de bytecode
      • 10.1 Programación de intérpretes de códigos de bytes. .
      • 10.2 Definición de una sintaxis del lenguaje ensamblador
      • 10.3 Arquitectura de la máquina Bytecode. . . . .
      • 10.4 A dónde ir desde aquí. . . . . . . . . .
      • P.26. Bytecode Ensamblador. . . . . . . . . . .
      • P.27. Intérprete de bytecode basado en pila. . .
      • P.28. Intérprete de Bytecode basado en registro
      http://pragprog.com/titles/tpdsl/language-implementation-patterns
    • La implementación de Lua 5.0 Este es un excelente documento sobre máquinas de códigos de bytes basadas en registros. Ve a leerlo incluso por el bien de eso.

    • Lisp en pequeñas piezas. Este libro enseña cómo escribir un 2 compiladores de schme que compilan a C. Se pueden aprender muchas lecciones de este libro. Poseo una copia de este libro y es realmente bueno para alguien interesante es lisp, pero tal vez no sea su taza de té.

      Esta es una cuenta completa de la semántica y la implementación de toda la familia de lenguajes Lisp, concretamente Lisp, Scheme y dialectos relacionados. Describe 11 intérpretes y 2 compiladores ...

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

Compruebe la máquina virtual Dalvik7, una máquina virtual basada en registros. El DVM funciona con códigos de bytes que se transforman a partir de los archivos de la clase Java compilados por un compilador de Java.

Hay una lista de correo sobre el tema, jvm-languages.

¿Estás planeando subir el código a cualquier lugar? Me gustaría echar un vistazo.



Le recomiendo que primero aprenda cómo funciona el ensamblaje de JVM, si aún no lo sabe.

Muchas instrucciones tienen la forma ?name , ? dónde ? es si la instrucción funciona con un tipo entero y a si funciona con un tipo de referencia.

Básicamente, JVM es una máquina de pila sin registros, por lo que todas las instrucciones funcionan con los datos directamente en la pila. Puede hacer push / pop datos con ?push/?pop y mover datos entre variables locales (ubicaciones de pila referenciadas por offsets) y la parte superior de la pila usando ?store/?load . Algunas otras instrucciones importantes son invoke??? y if_??? .

Para el curso de compilación de mi universidad usamos Jasmin para armar los programas. No sé si esta es la mejor manera, pero al menos es un lugar fácil para comenzar.

Aquí hay una referencia de instrucción para una versión anterior de la JVM, que podría contener menos instrucciones que una nueva.


Primero retrocederé, modificaré mi compilador para producir Java real en lugar de códigos de bytes Java (lo que significa crear más de un traductor que compilador), y compilar el resultado de Java con cualquier entorno Java que sea conveniente (lo que probablemente genere un mejor código objeto) que mi propio compilador).

Puede usar la misma técnica (por ejemplo, compilar en C #) para generar códigos de bytes CLI, o compilar a Pascal para generar código P, etc.

No está claro por qué está considerando códigos Java en lugar de utilizar su propia máquina virtual, pero si se trata de rendimiento, por supuesto, también debe considerar la compilación de códigos máquina reales.


También recomendaría ASM, pero eche un vistazo a Jasmin , lo utilicé (o: tuve que usarlo) para un proyecto universitario, y funciona bastante bien, escribí una combinación de lexer / analizador / optimizador / generador para un lenguaje de programación que usa java y jasmin, por lo que genera el código JVM. Cargué el código here , la parte interesante debería ser el código fuente en sí . En la carpeta "bytecode / InsanelyFastByteCodeCreator.java", se encuentra una porción de código que transforma un árbol AST en el formato de entrada del ensamblador jasmin. Es bastante directo.

El idioma fuente (que fue transformado en AST por Lexer + Parser + Analyzer) es un subconjunto de Java llamado MiniJava. Carece de algunas características "complicadas" como Herencia, Constructores, métodos estáticos, campos / métodos privados. Ninguna de estas características es difícil de implementar, pero había otra tarea para escribir un backend X86 (para generar un ensamblador de máquina), y esas cosas tienden a ser difíciles si no tienes JVM que maneje algunas cosas.

En caso de que se pregunte sobre el extraño nombre de clase: La tarea del proyecto de la universidad era transformar el AST en un gráfico SSA (por lo tanto, un gráfico que representa el código de entrada), luego optimizar el gráfico y luego convertir el gráfico en código de bytes java. Eso fue aproximadamente 3/4 del trabajo del proyecto y el InsanlyFastByteCodeCreator fue solo un atajo para probar todo.

Eche un vistazo al libro "Java Virtual Machine" de Jon Meyer y Troy Downing. Este libro hace referencia en gran medida a Jasmin-Assembler, es bastante útil para entender las partes internas de JVM.


ASM puede ser una solución para generar bytecode. Para comenzar, consulte los temas sobre la generación de elementos del manual .