martes, 4 de abril de 2017

Generación de codigo

Generación de código

Hay lenguajes que son pseudointerpretados que utilizan un código intermedio llamado código-P que utiliza lo que se denomina bytecodes (sentencias de un µP hipotético). Por ejemplo Java utiliza los ficheros .class, éstos tienen unos bytecodes que se someten a una JavaVirtualMachine, para que interprete esas sentencias. En este capítulo se muestra cómo se pueden utilizar los métodos de analizadores dirigidos por la sintaxis para traducir a un código intermedio, construcciones de lenguajes de programación como declaraciones, asignaciones y proposiciones de flujo de control. La generación de código intermedio se puede intercalar en el análisis sintáctico.

Código de tercetos

La elección de operadores permisibles es un aspecto importante en el diseño de código intermedio. El conjunto de operadores debe ser lo bastante rico como para implantar las operaciones del lenguaje fuente. Un conjunto de operadores pequeño es más fácil de implantar en una nueva máquina objeto. Sin embargo un conjunto de instrucciones limitado puede obligar a la etapa inicial a generar largas secuencias de proposiciones para algunas operaciones del lenguaje fuente. En tal caso, el optimizador y el generador de código tendrán que trabajar más si se desea producir un buen código.

Ejemplo de código de tercetos c = a label etqBucle if b = 0 goto etqFin b = b-1 c = c+1 goto etqBucle label etqFin

Para ilustrar como se utiliza el código de tercetos en una gramática vamos a suponer que nuestra calculadora en vez de ser una calculadora interpretada es una calculadora compilada, es decir, en vez de interpretar las expresiones vamos a generar código intermedio equivalente. Tendremos en cuenta la posibilidad de utilizar variables.
Las variables temporales sirven para almacenar resultados intermedios a medida que vamos calculando el resultado final.





Generacion de código de tercetos o sentencis de control
Cada vez que se reduce a una condición en base a expresiones, se genera el código
if arg1 op arg2 goto etq_verdad goto etq_falso
En el momento en que nos encontramos con un operador lógico, sabemos que a continuación nos vamos a encontrar otra condición, que también generará un código con la misma estructura, así como otras dos etiquetas, una de certeza, y otra de falsedad. Ambas condiciones y el operador lógico, se reducirán a una condición. Ahora bien, dicha condición reducida deberá tener solo dos etiquetas, ¿qué etiquetas le asignamos?. La solución depende de la conectiva que se emplee.
Veamos cada uno de los casos:
          cond      : cond AND cond { }
     Ventajas:

 Permite abstraer la máquina, separar operaciones de alto nivel de su implementación a bajo nivel.
 Permite la reutilización  de los front-ends y backends.
  Permite optimizaciones generales. 

  Desventajas:

Implica una pasada más para el compilador (no se puede utilizar el modelo de una pasada, conceptualmente simple).

 Dificulta llevar a cabo optimizaciones específicas  de la arquitectura destino.


  Suele ser ortogonal a la máquina destino, la traducción a una arquitectura específica será más larga e ineficiente

No hay comentarios.:

Publicar un comentario