La generación de código tiene como objetivo generar el ejecutable que después emplearía el usuario. Sin embargo, es habitual que el producto del compilador no sea directamente un fichero ejecutable. Es bastante más común que sea un fichero en lenguaje ensamblador. De esta manera, se evitan problemas como tener que medir el tamaño exacto de las instrucciones o llevar la cuenta de sus direcciones. Además, es muy probable que el código generado tenga referencias a objetos externos como funciones de biblioteca. Estas referencias externas serían resueltas por el enlazador o el cargador.
Existen diversos tipos de códigos intermedios que varían en cuanto a su sencillez, lo próximos que están a las maquinas reales y lo fácil que es trabajar con ellos. Nosotros nos centraremos en un tipo de código que se parece bastante al lenguaje ensamblador. Existen otros tipos de código intermedio que representan los programas como árboles o grafos. También existen representaciones mixtas que combinan grafos o árboles y representaciones lineales.
La administración de la memoria se da en esta etapa.
Se debe considerar tanto la memoria estática como dinámica, y en esta se utilizan generalmente pilas.
• Los lenguajes intermedios generalmente tienen árboles de derivación más pequeños que su contraparte original.
• Se puede representar un árbol sintáctico con un Grafo Dirigdo Acíclico (GDA).
• La notación postfija es una manera linealizada de representar un árbol sintáctico.
• a := b*-c+b*-c
• abc -*bc -*+=
• x := y op z
• x+y*z
• t1:=y*z
• t2:=x+t1
Por ejemplo:
a = b + c * d;
El generador de código intermedio, tratar de dividir esta expresión en sub-expresiones y, a continuación, generar el código correspondiente.
r1 = c * d; r2 = b + r1; r3 = r2 + r1; a = r3
R que se utilizan como registros en el programa de destino.
Un código de dirección tiene un máximo de tres direcciones para calcular la expresión. Un código de dirección puede estar representado en dos formas : cuádruples y triples.
No hay comentarios.:
Publicar un comentario