Articulo de referencia

Compilador multipaso

Un compilador de múltiples pasadas es un tipo de compilador que procesa el código fuente o el árbol de sintaxis abstracta de un programa varias veces. Esto contrasta con un comp...

Un compilador de múltiples pasadas es un tipo de compilador que procesa el código fuente o el árbol de sintaxis abstracta de un programa varias veces. Esto contrasta con un compilador de una sola pasada , que recorre el programa solo una vez. Cada pasada toma como entrada el resultado de la pasada anterior y crea una salida intermedia. De esta manera, el código (intermedio) se mejora paso a paso, hasta que la pasada final produce el código definitivo.

Los compiladores de múltiples pasadas a veces se denominan compiladores amplios [ 1 ] , en referencia al mayor alcance de las pasadas: pueden "ver" todo el programa que se está compilando, en lugar de solo una pequeña parte. El mayor alcance disponible para estos compiladores permite una mejor generación de código (por ejemplo, menor tamaño de código, código más rápido) en comparación con la salida de los compiladores de una sola pasada, a costa de un mayor tiempo de compilación y consumo de memoria. Además, algunos lenguajes no se pueden compilar en una sola pasada, como resultado de su diseño.

Compilador típico de múltiples pasadas

Análisis léxico

Esta etapa de un compilador multipaso consiste en eliminar información irrelevante del programa fuente que el análisis sintáctico no podrá utilizar ni interpretar. La información irrelevante puede incluir elementos como comentarios y espacios en blanco. Además de eliminar la información irrelevante, el análisis léxico determina los tokens léxicos del lenguaje. Este paso implica que, por lo general, no es necesaria la declaración anticipada si se utiliza un compilador multipaso. Esta fase se centra en dividir una secuencia de caracteres en tokens con atributos como tipo, clase, valor y, potencialmente, otros.

Análisis sintáctico

El análisis sintáctico se encarga de examinar las reglas sintácticas del lenguaje (a menudo como una gramática libre de contexto ) y construir una representación intermedia del mismo. Un ejemplo de esta representación intermedia podría ser un árbol sintáctico abstracto o un grafo acíclico dirigido .

Análisis semántico

El análisis semántico toma la representación obtenida mediante el análisis sintáctico y le aplica reglas semánticas para asegurar que el programa cumpla con los requisitos semánticos del lenguaje. Por ejemplo, en el ejemplo siguiente, durante el análisis semántico, si el lenguaje requiriera que las condiciones de las sentencias `if` fueran expresiones booleanas, se verificaría el tipo de la condición para asegurar que fuera una expresión booleana válida.

si ( cond ) { ... } de lo contrario { ... }

Además de realizar un análisis semántico en esta etapa de compilación, a menudo se crean tablas de símbolos para facilitar la generación de código.

Generación de código

Esta etapa final de un compilador típico convierte la representación intermedia del programa en un conjunto ejecutable de instrucciones (a menudo en lenguaje ensamblador ). Esta última etapa es la única de la compilación que depende de la máquina. También se pueden realizar optimizaciones en esta etapa para mejorar la eficiencia del programa.

Otras fases del compilador incluyen una fase de generación de código intermedio que tiene lugar antes de la generación de código y una fase de optimización de código que puede tener lugar cuando se escribe el programa fuente, o después de la fase de generación de código intermedio, o después de la fase de generación de código.

Ventajas de los compiladores multipaso

Independencia de la máquina : Dado que las múltiples pasadas incluyen una estructura modular y la generación de código está desacoplada de los demás pasos del compilador, las pasadas se pueden reutilizar para diferentes hardware/máquinas.

Lenguajes más expresivos : Las múltiples pasadas eliminan la necesidad de declaraciones anticipadas, lo que permite implementar la recursión mutua de forma elegante. Los principales ejemplos de lenguajes que requieren declaraciones anticipadas para poder compilarse en una sola pasada son C y Pascal , mientras que Java no las tiene.

Marcos de trabajo

Existen varios meta-marcos para diseñar compiladores de múltiples pasadas, como los compiladores nanopass que utilizan lenguajes intermedios explícitos. [ 2 ]

Referencias

  1. ^ Grune, Dick; van Reeuwijk, Kees; Bal, Enrique; Jacobs, Ceriel; Langendoen, Koen (2012). Diseño de compilador moderno (Segunda  ed.). Ámsterdam, Países Bajos: Springer. pag.  27.ISBN 978-1-4939-4472-9.
  2. Ringo, Nathan; Kramer, Lucas; Van Wyk, Eric (23 de octubre de 2023). «Gramáticas de atributos Nanopass» . SLE 2023: Actas de la 16.ª Conferencia Internacional ACM SIGPLAN sobre Ingeniería de Lenguajes de Software . ACM: 70–83 . doi : 10.1145/3623476.3623514 . ISBN 979-8-4007-0396-6.

Lecturas adicionales

  • Bornat, Richard , Comprender y escribir compiladores: Una guía práctica , Macmillan Publishing, 1979. ISBN 0-333-21732-2
  • Bent Thomsen, Languages ​​and Compilers SProg og Overseattere , Departamento de Ciencias de la Computación, Universidad de Aalborg