Lenguajes de Programación Compilación vs Interpretación Juan Zamora O. Semestre II - 2013 Anteriormente... I Inicios de los LP. I Ppio de los tiempos → Secuencias de bits. I Aumento progresivo del nivel de abstracción. I Traductor → Interprete. I Modelo de computación y categorı́as. [email protected] 1/1 Compiladores I Compilacion y ejecucion de un programa en un lenguaje de alto nivel: P.Fuente Compilador Entrada Ejecutable Salida I Traducción del programa fuente en programa objeto (tipicamente en lenguaje de maquina). I ”tiempo de compilacion” vs ”tiempo de ejecución”. [email protected] 2/1 Compiladores I Compilacion y ejecucion de un programa en un lenguaje de alto nivel: P.Fuente Compilador Entrada Ejecutable Salida I Traducción del programa fuente en programa objeto (tipicamente en lenguaje de maquina). I ”tiempo de compilacion” vs ”tiempo de ejecución”. [email protected] 2/1 Interpretes I Esquema general de interpretación de un programa fuente: P.Fuente Interprete Salida Entrada I Interprete ∼ maquina virtual. I Se procesa y se ejecuta. I Manejo ”cómodo” de asignaciones dinámicas (dep. entrada). [email protected] 3/1 Interpretes I Esquema general de interpretación de un programa fuente: P.Fuente Interprete Salida Entrada I Interprete ∼ maquina virtual. I Se procesa y se ejecuta. I Manejo ”cómodo” de asignaciones dinámicas (dep. entrada). [email protected] 3/1 Interpretes I Esquema general de interpretación de un programa fuente: P.Fuente Interprete Salida Entrada I Interprete ∼ maquina virtual. I Se procesa y se ejecuta. I Manejo ”cómodo” de asignaciones dinámicas (dep. entrada). [email protected] 3/1 Compilador vs Interprete I I Lenguajes compilados generalmente tienen un mejor desempeño. I Ahorran realizacion de tareas en tiempo de ejecucion al ejecutarlas una unica vez en el tiempo de compilacion. I Criterio: Complejidad en el analisis e intervencion del codigo I Interprete ∼ traducción mecánica. I Compilador: I Análisis sintáctico. I Modifica código. I Genera programa intermedio entre c.orig. y lenguaje de maq. [email protected] 4/1 Compilador vs Interprete I I Lenguajes compilados generalmente tienen un mejor desempeño. I Ahorran realizacion de tareas en tiempo de ejecucion al ejecutarlas una unica vez en el tiempo de compilacion. I Criterio: Complejidad en el analisis e intervencion del codigo I Interprete ∼ traducción mecánica. I Compilador: I Análisis sintáctico. I Modifica código. I Genera programa intermedio entre c.orig. y lenguaje de maq. [email protected] 4/1 Compilador vs Interprete I I Lenguajes compilados generalmente tienen un mejor desempeño. I Ahorran realizacion de tareas en tiempo de ejecucion al ejecutarlas una unica vez en el tiempo de compilacion. I Criterio: Complejidad en el analisis e intervencion del codigo I Interprete ∼ traducción mecánica. I Compilador: I Análisis sintáctico. I Modifica código. I Genera programa intermedio entre c.orig. y lenguaje de maq. [email protected] 4/1 Compilador vs Interprete I I Lenguajes compilados generalmente tienen un mejor desempeño. I Ahorran realizacion de tareas en tiempo de ejecucion al ejecutarlas una unica vez en el tiempo de compilacion. I Criterio: Complejidad en el analisis e intervencion del codigo I Interprete ∼ traducción mecánica. I Compilador: I Análisis sintáctico. I Modifica código. I Genera programa intermedio entre c.orig. y lenguaje de maq. [email protected] 4/1 Compilador vs Interprete II I En L.Compilados, el ”traductor” se denomina preprocesador. I Operaciones basadas en calce de patrones. I Existe posibilidad de errores posteriores. P.Fuente Preprocesador P.Fuente Mod. Compilador Prog. Assembly Ejemplo gcc... [email protected] 5/1 Compilador vs Interprete II I En L.Compilados, el ”traductor” se denomina preprocesador. I Operaciones basadas en calce de patrones. I Existe posibilidad de errores posteriores. P.Fuente Preprocesador P.Fuente Mod. Compilador Prog. Assembly Ejemplo gcc... [email protected] 5/1 Compilador vs Interprete III Esquema gral. de impl. para la mayorı́a de los LLP. P.Fuente Traductor P.Interm. Maq. Virtual Salida Entrada [email protected] 6/1 Compilador vs Interprete III Esquema gral. de impl. para la mayorı́a de los LLP. P.Fuente Traductor depende de complej. P.Interm. Maq. Virtual Salida Entrada [email protected] 7/1 Como se construye un compilador? I Bootstrapping I Compilador C → C I Compilador ADA → ADA I Compilador no necesariamente traduce de L. de alto nivel a L. de maquina. I ∃ ssi ∃ traducción automat. Y ∃ análisis semántico de entrada (C.Fuente). [email protected] 8/1 Como se construye un compilador? I Bootstrapping I Compilador C → C I Compilador ADA → ADA I Compilador no necesariamente traduce de L. de alto nivel a L. de maquina. I ∃ ssi ∃ traducción automat. Y ∃ análisis semántico de entrada (C.Fuente). [email protected] 8/1 Fases de compilación I I Compilación consiste en una serie de pasos secuenciales. (Img. extraı́da del libro de Scott.) [email protected] 9/1 Fases de compilación II I Frontend: Buscan significado del programa. I Backend: Construyen programa objeto equivalente. I Ambos pueden ser compartidos por compiladores: I Frontend: para más de una maq. I Backend: para más de un lenguaje de fuente. [email protected] 10/1 Análisis léxico y sintáctico I Consideremos el siguiente código: int main (){ int i = getint () , j = getint (); while ( i != j ) { if (i > j ) i = i - j ; else j = j - i ; } putint ( i ); } I Análisis léxico: [email protected] 11/1 Análisis léxico y sintáctico II I I I Análisis léxico I Reconoce sólo estructura & agrupa atomos (tokens). I Reduce tamaño de la entrada. Análisis sintáctico organiza tokens jerárquicamente. I Representa conceptos de alto nivel (uno por nodo en árbol). I Componentes de c/concepto → hijos. I Hojas (D → I) son los Tokens recibidos por el A.Lex. Estructura del árbol se basa en cjto. de reglas recursivas (”CFG”). I Una regla: Concepto → { expansión posible} [email protected] 12/1 Análisis léxico y sintáctico III Árbol sintáctico Concreto del código anterior(1). [email protected] 13/1 Análisis léxico y sintáctico IV Árbol sintáctico Concreto del código anterior(2). [email protected] 14/1 Análisis léxico y sintáctico V Árbol sintáctico Abstracto del código anterior. [email protected] 15/1 Análisis léxico y sintáctico VI Importante I Cada punto de ramificcación → aplicación de una regla gramática. I Complejidad resultante es reflejo de gramática, no del programa de entrada. I Durante análisis léxico y sintáctico compilador verifica: I Correctitud de tokens (bien formados). (e.g. $mi var en C) I Coherencia de secuencia de tokens con la gramática. (e.g. i = j.i 2) [email protected] 16/1 Análisis semántico y gen. de cód. intermedio I I I Análisis semántico → Identificación del sentido/intención en un programa. I Reconoce si mult. ocurrencias de un ID hacen ref. a la misma entidad. I Verifica su uso consistente. I Rastrea tipos de ID y exprs. para verificar uso consistente. Construcción de tabla de sı́mbolos (T.S.). I Asocia cada ID con su información (tipo, ambito, estr. interna, etc.) [email protected] 17/1 Análisis semántico y gen. de cód. intermedio II I I (usando T.S.) Otras reglas pueden ser verificadas (e.g.): I Declaración previa de cada ID y aplicaciones coherentes (e.g. String + INT). I Parámetros correctos en subrutinas. Revisión exhaustiva de reglas semánticas en T.Compilación I Imposible. I ”Aquellas que sı́” → Semánticas Estáticas. I Resto → Semánticas Dinámicas. [email protected] 18/1 Análisis semántico y gen. de cód. intermedio III I ¿Balance en términos de desempeño? (verif. semant. estaticas vs dinámicas) I ¿Balance en términos de seguridad? (verif. semant. estaticas vs dinámicas) I Algunos LP. verifican en tiempo de ejecución: I Inicialización de vars. previo a su uso en expr. I Expr. con indices de arreglos queden dentro del rango. [email protected] 19/1 Análisis semántico y gen. de cód. intermedio IV I Compilador produce código para verificar algunas reglas (Lanzamiento de Excepciones). I Aquello que no puede ser verif. genera programas indefinidos. void main (){ int arr [4] = {0 , 1 , 2 , 3}; int * p = arr ; printf ( " % d \ n " , *( p +5)); } [email protected] 20/1 Arbol de sintáxis concreto vs abstracto I I I Árbol sintáctico pasa por 2 etapas: I Concreta: muestra derivación de reglas a partir de CFG. I Abstracta: Refinación de la v.Concreta. → Arbol de sintaxis (a secas). En etapa abstracta: I Nodos artificiales son removidos. I Incorporación de anotaciones por el A. Semántico.(atributos) I E.g. ptrs de ID hacia entradas de T.S. [email protected] 21/1 Arbol de sintáxis concreto vs abstracto II I En algunos compiladores: I Árbol de sintáxis [Forma intermedia] → Backend. I Recorrido sobre árbol de sintaxis [Forma Intermedia] → Backend. I E.g. grafo de flujo de control: potenciales caminos durante ejec. [email protected] 22/1 Generación de código objeto I I Forma intermedia es llevada al lenguaje objetivo. I Dada la info. del árbol de sintáxis se genera el código. I Revisión de T.S. para asignar ubic. de vars. I Recorrido de repres. intermedia (resto de ops. y ramificaciones) I T.S. almacenada en programa objeto para depuración. [email protected] 23/1 Generación de código objeto II Código ensamblado del programa GCD en C. [email protected] 24/1 Mejora del código I I ”Optimización” (no siempre es realizada) I Transforma programa que: I I Hace lo mismo. I Más rapido o I usando menos memoria. Mejoras pueden ser I Dependientes de la maq. I I I I sobre forma intermedia. Indep. de la maq. sobre programa objeto. 2 fases adicionales al proceso de compilación (eventualmente). [email protected] 25/1 Mejora del código II Código ensamblado del programa GCD en C.(version mejorada) [email protected] 26/1