stringtranslate.com

Compilador de múltiples pasadas

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 el resultado de la pasada anterior como entrada 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 final.

Los compiladores de múltiples pasadas a veces se denominan compiladores amplios [1] , haciendo referencia al mayor alcance de las pasadas: pueden "ver" todo el programa que se está compilando, en lugar de solo una pequeña parte de él. El alcance más amplio disponible de este modo para estos compiladores permite una mejor generación de código (por ejemplo, un tamaño de código más pequeño, 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 multi-paso típico

Análisis léxico

Esta etapa de un compilador de múltiples pasadas consiste en eliminar la información irrelevante del programa fuente que el análisis de sintaxis 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 significa que la declaración anticipada generalmente no es necesaria si se utiliza un compilador de múltiples pasadas. Esta fase se centra en dividir una secuencia de caracteres en tokens con atributos como tipo, valor y, potencialmente, otros también.

Análisis de sintaxis

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

Análisis semántico

El análisis semántico toma la representación creada a partir del análisis sintáctico y aplica reglas semánticas a la representación para asegurarse de que el programa cumpla con los requisitos de reglas semánticas del lenguaje. Por ejemplo, en el ejemplo siguiente, en la etapa de análisis semántico, si el lenguaje requiere que las condiciones de las declaraciones if sean expresiones booleanas, se verificará el tipo de cond para asegurarse de que sea una expresión booleana válida.

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

Además de realizar análisis semántico en esta etapa de compilación, a menudo se crean tablas de símbolos para ayudar en 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 de ensamblaje ). Esta última etapa es la única etapa de la compilación que depende de la máquina. También se puede realizar una optimización en esta etapa de la compilación que haga que el programa sea más eficiente.

Otras fases del compilador incluyen la fase de generación de código intermedio, que tiene lugar antes de la generación de código, y la 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 multi-paso

Independiente de la máquina : dado que los pases múltiples incluyen una estructura modular y la generación de código está desacoplada de los otros pasos del compilador, los pases se pueden reutilizar para diferentes hardware/máquinas.

Lenguajes más expresivos : los pases múltiples eliminan la necesidad de declaraciones adelantadas, lo que permite implementar la recursión mutua de manera elegante. Los principales ejemplos de lenguajes que requieren declaraciones adelantadas debido al requisito de ser compilables en un solo pase incluyen C y Pascal , mientras que Java no tiene declaraciones adelantadas.

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.