¿Qué es un compilador?

Mujer trabajando desde casa con la computadora

Autores

Josh Schneider

Staff Writer

IBM Think

Ian Smalley

Staff Editor

IBM Think

¿Qué es un compilador?

Un compilador es un tipo de programa informático que convierte código de un lenguaje de programación (el lenguaje de origen) a otro lenguaje de programación (el lenguaje de destino).

Los compiladores se utilizan para transformar código fuente de alto nivel en código de destino de bajo nivel (como lenguaje ensamblador, código objeto o código de máquina) mientras se preserva la funcionalidad del programa.

Una herramienta crítica para la programación informática moderna y práctica, los compiladores permiten a los programadores trabajar en código de alto nivel legible por humanos y luego convertir su código fuente en código de destino ejecutable. Los compiladores también ayudan a los desarrolladores de software a crear programas ejecutables eficientes con seguridad, estabilidad y portabilidad mejoradas. Esto se debe a que los compiladores ayudan a identificar y abordar errores, creando así aplicaciones portátiles ejecutables. 

Aunque todos los compiladores convierten el código de alto nivel en código ejecutable de bajo nivel, se utilizan diferentes tipos de compiladores para diferentes lenguajes de programación y aplicaciones. Por ejemplo, un compilador cruzado se utiliza para producir código para un tipo de CPU o sistema operativo diferente al que se ejecuta.

Cuando el compilador ideal no está disponible o aún no se ha creado, se utiliza un compilador de Bootstrapping temporal para compilar un compilador más permanente que está mejor optimizado para compilar cualquier lenguaje de programación específico.

Una breve lista de otro software relacionado incluye:

  • Los descompiladores funcionan como compiladores inversos y convierten código de bajo nivel en lenguajes de alto nivel.
  • Los compiladores de fuente a fuente (o transpiladores) convierten código de alto nivel en otros lenguajes de alto nivel.
  • Los reescritores de lenguaje convierten expresiones de código formal en diferentes formas sin cambiar el lenguaje.
  • Los compiladores-compiladores se utilizan para crear compiladores genéricos y reutilizables o componentes de compiladores que se pueden incorporar a fines más específicos del proyecto.  

Las últimas noticias tecnológicas, respaldadas por los insights de expertos

Manténgase al día sobre las tendencias más importantes e intrigantes de la industria sobre IA, automatización, datos y más con el boletín Think. Consulte la Declaración de privacidad de IBM.

¡Gracias! Ya está suscrito.

Su suscripción se entregará en inglés. En cada boletín, encontrará un enlace para darse de baja. Puede gestionar sus suscripciones o darse de baja aquí. Consulte nuestra Declaración de privacidad de IBM para obtener más información.

Cómo funcionan los compiladores

En la práctica, usar un compilador puede ser tan simple como ingresar un comando en una línea de comandos en cualquier sistema Linux (o equivalente), especificando el archivo ejecutable del compilador y los archivos fuente que se compilarán. Este comando indica al sistema que procese el código fuente, compilándolo en un código de máquina de destino y dando como resultado los archivos de objeto necesarios para producir un programa ejecutable. 

Los compiladores de código abierto como GNU Compiler Collection (GCC), una robusta colección de compiladores de C comúnmente utilizada para compilar código C en programas C, o la alternativa Clang están disponibles en repositorios como GitHub. Otros compiladores pueden instalar libremente o adquirir a una amplia gama de distribuidores. También se pueden integrar en entornos de desarrollo integrado (IDE) populares, que agrupan varias compañías de servicios públicos para el desarrollo de software, incluidos editores de texto, documentación API y herramientas de depuración .     

Independientemente del compilador específico que se emplee, el proceso de compilación de código implica pasar el código fuente a través de varios niveles de análisis, optimización y, en última instancia, generación de código. El código fuente pasa por las diferentes capas analíticas secuencialmente y se evalúa en cada paso del proceso.

Si el compilador reconoce algún problema con el código fuente, podría devolver un mensaje de error, lo que indica a los desarrolladores que corrijan los errores identificados antes de continuar con la compilación del resto del código. Generalmente, los compiladores proceden a través de los siguientes pasos:

  1. Análisis léxico: el primer paso de la compilación pasa el código fuente a través del lexer del compilador, un programa que transforma caracteres en unidades significativas de lenguaje, como palabras clave, identificadores y operadores conocidos. Estas unidades se conocen colectivamente como tokens. Este paso esencialmente prepara el código fuente para los siguientes pasos mediante la conversión de elementos significativos e importantes del código fuente en los tokens con los que el compilador puede trabajar. 
  2. Análisis de sintaxis: el segundo paso en el proceso de compilación envía los tokens del analizador léxico al analizador del compilador. Un analizador es un programa que verifica el código en busca de errores sintácticos y garantiza que el código fuente siga correctamente las reglas del lenguaje fuente. Si el analizador no detecta errores durante el análisis, genera una representación abstracta de la estructura general del código denominada árbol de sintaxis abstracta (AST).
  3. Análisis semántico: luego de verificar la sintaxis del código, un compilador realiza un análisis semántico del código analizado para deducir la función prevista del código fuente. En este paso, el compilador realiza comprobaciones para detectar errores lógicos como variables no declaradas o uso incorrecto de operadores.
  4. Optimización: aunque no es necesariamente necesaria para producir código que funcione, la optimización es un paso opcional común a muchos compiladores para mejorar el rendimiento general del código compilado. La optimización puede identificar y eliminar código innecesario y dar como resultado programas más rápidos, eficientes y estables, así como acortar el proceso final de depuración. 
  5. Generación de código: en el paso final del proceso, el compilador convierte el AST en código legible por máquina. El resultado final de la generación de código es un código en lenguaje ensamblador que luego puede convertir en código binario y ser ejecutado por el sistema informático. 
Academia de IA

Cómo lograr la preparación para la IA con la nube híbrida

Dirigida por los principales líderes de opinión de IBM, el plan de estudios está diseñado para ayudar a los líderes empresariales a obtener los conocimientos necesarios para priorizar las inversiones en IA que pueden impulsar el crecimiento.

Estructura del compilador de tres etapas

Es posible que algunos compiladores no se adhieran estrictamente a la estructura anterior. Sin embargo, aunque algunos compiladores pueden contener más o menos pasos, todas las fases de compilación se pueden atribuir a una de tres etapas: un front end, un middle end y un back end.

Esta estructura de tres etapas permite a los compiladores adoptar un enfoque modular. Permite combinar múltiples front-end para diferentes lenguajes con backend para diferentes CPU, al tiempo que comparte las capacidades de optimización de varios middle end aplicables.

Las tres etapas de un compilador implican la siguiente distribución:

  1. Interfaz: la interfaz de un compilador incluye aspectos de análisis léxico, análisis de sintaxis y análisis semántico. Esta etapa verifica la sintaxis y la semántica según las reglas del lenguaje de origen y puede identificar y señalarizar errores en el código fuente. Suponiendo que no se encuentren errores, el front end del compilador convierte el código fuente en una representación intermedia (IR), una conversión temporal de nivel inferior del código fuente, para el middle end. 
  2. Extremo intermedio: la etapa intermedia de un compilador realiza varias optimizaciones de código en el IR independientemente de la arquitectura de CPU a la que se dirija el proceso de compilación general. Al promulgar optimizaciones en el código fuente independientemente del código máquina de destino, el compilador puede aplicar optimizaciones generalizadas que pueden mejorar el rendimiento del código en múltiples versiones. Estas mejoras se pueden realizar independientemente del lenguaje o la arquitectura de hardware compatibles. 
  3. Backend: la etapa de back-end utiliza la salida de la etapa de extremo medio y podría realizar otras optimizaciones y conversiones específicas de la CPU. En esta etapa final del proceso de compilación, el compilador produce resultados de código de ensamblaje dependiente del destino, incluyendo asignaciones de registros y programación de instrucciones. La etapa de back-end suele dar como resultado un código de máquina especializado para los sistemas operativos y el hardware de destino. 

Beneficios de usar un compilador

Si bien los compiladores no son explícitamente necesarios para producir código viable, la amplia variedad y complejidad tanto de los lenguajes de programación como de los entornos de máquina hacen que los compiladores sean una necesidad práctica para crear software ejecutable. Estos son los cuatro beneficios principales de emplear compiladores de software.

Facilite la programación de lenguaje de alto nivel

Los lenguajes de programación de alto nivel utilizan una sintaxis y palabras clave más cercanas a los lenguajes hablados, lo que facilita mucho su uso para los desarrolladores. Los compiladores convierten este código legible por humanos en el código de máquina más complejo necesario para ejecutar aplicaciones de software optimizadas.

Algunos ejemplos de lenguajes de alto nivel incluyen los siguientes lenguajes:

  • Python (utilizado para desarrollo web, ciencia de datos y otros)
  • Java (utilizado para el desarrollo de Android, aplicaciones empresariales y otros)
  • C++ (utilizado para el desarrollo de juegos, sistemas operativos y otros)
  • JavaScript (utilizado para el desarrollo web dinámico e interactivo)
  • PHP (utilizado para scripts del lado del servidor en desarrollo web)
  • C# (utilizado para aplicaciones Windows, desarrollo de juegos del motor Unity)
Reducir la repetición

Los compiladores ayudan a mejorar la eficiencia al convertir código de alto nivel en código de máquina ejecutable. La salida del compilador se almacena con un archivo .exe extensión de archivo, que luego es ejecutada directamente por una computadora. Debido al compilador, escribir un programa ejecutable se convierte en una tarea de esfuerzo único.

Una vez completado, el código compilado se puede ejecutar tantas veces como sea necesario. Este proceso ayuda a que los programas generalmente se ejecuten de manera más rápida y eficiente, ya que ciertas aplicaciones o partes de las aplicaciones se pueden ejecutar por separado de las tareas de software en tiempo de ejecución.

Mejore la portabilidad

No todos los sistemas pueden ejecutar todos los tipos de código de programación. Los compiladores se emplean para convertir los tipos de código que los desarrolladores prefieren emplear en los tipos de código que los sistemas necesitan para funcionar. De este modo, los compiladores mejoran la portabilidad de los programas al convertir el software en una amplia variedad de lenguajes compatibles que pueden almacenar, transferir y ejecutar fácilmente en diversos sistemas operativos y arquitecturas de hardware.

Promover la optimización general

Durante el proceso de compilación, los compiladores se pueden utilizar para identificar y abordar errores y fallas de software, lo que da como resultado programas más estables y mejor optimizados. Los compiladores también pueden ayudar a mejorar la seguridad del software al prevenir errores relacionados con la memoria, como desbordamientos de búfer, y generar advertencias si se detectan posibles problemas de memoria. 

Compiladores versus intérpretes

Mientras que los compiladores se emplean para convertir el código fuente en código máquina ejecutable, los intérpretes son otro tipo de programa que puede proporcionar una funcionalidad similar, pero a través de un mecanismo diferente.

En lugar de convertir el código fuente, los intérpretes ejecutan directamente el código fuente o utilizan un código intermedio conocido como bytecode, una representación del código fuente de bajo nivel e independiente de la plataforma. Bytecode sirve como intermediario entre el código fuente legible por humanos y el código de máquina, diseñado para ser ejecutado por una máquina virtual (VM) en lugar de directamente en el hardware de una computadora. 

En teoría, cualquier lenguaje de programación se puede ejecutar con un compilador o un intérprete. Sin embargo, los lenguajes de programación individuales tienden a ser más adecuados para la compilación o la interpretación.

En la práctica, la distinción entre lenguajes compiladores y lenguajes de intérprete a veces puede ser borrosa, al igual que la distinción entre compiladores e intérpretes mismos, ya que ambos tipos de programas pueden presentar funcionalidades superpuestas. Si bien algunos lenguajes son más comúnmente compilados y otros más comúnmente interpretados, es posible escribir un compilador para un lenguaje que se interpreta comúnmente y viceversa.

Los lenguajes de alto nivel generalmente se crean con un tipo de conversión (ya sea compilación o interpretación) en mente, pero estas son más sugerencias que limitaciones estrictas. Por ejemplo, BASIC a menudo se conoce como un lenguaje interpretado y C un lenguaje compilado, pero existen compiladores para BASIC al igual que hay intérpretes de C. 

La principal diferencia entre intérpretes y compiladores radica en el tiempo y la optimización. Ambos tipos de programas intentan convertir el código fuente en código de destino que primero sea funcional y luego optimizado.

Dependiendo del entorno operativo, el código compilado o interpretado puede ser más adecuado para ejecutar de manera eficiente teniendo en cuenta la capacidad del hardware, la memoria y la capacidad de almacenamiento. Dependiendo de las limitaciones de cada programa, aplicación y hardware específico, la compilación, la interpretación o una combinación de ambas podrían producir los mejores resultados. 

Como tal, la interpretación no puede sustituir por completo a la compilación, pero puede mover las tareas de compilación a un segundo plano a través de un proceso de conversión gradual. Los compiladores emplean una estrategia de conversión anticipada (AOT) que convierte el código fuente en código de destino por completo antes de crear un archivo ejecutable.

Los intérpretes, alternativamente, ejecutan el código directamente como lo requiere una aplicación o utilizan bytecode como intermediario para generar el código fuente ejecutable de las máquinas virtuales. De esta manera, los intérpretes pueden proporcionar algunas aceleraciones o flexibilidad, pero en algún momento, se debe proporcionar un conjunto de instrucciones de máquina ejecutadas directamente hacia el final de la pila de ejecución.

En algunos casos, cuando la eficiencia ligera es una prioridad, los intérpretes especiales pueden ser preferibles a los compiladores por su capacidad para realizar la conversión justo a tiempo (JIT). JIT es una estrategia que compila fragmentos de código fuente en código de destino en un búfer de memoria para su ejecución inmediata. La interpretación JIT compila código a pedido, combinando la eficiencia de compilación única de un compilador tradicional con la flexibilidad de ejecutar código repetidamente, a menudo más rápido que los intérpretes de código de bytes estándar.

Sin embargo, a medida que aumentan las tendencias modernas hacia la compilación JIT junto con la interpretación del código de bytes dependiente de la situación, muchos compiladores están siendo diseñados para ofrecer características de compilación e interpretación. Esta superposición difumina aún más las líneas entre estas dos categorías. 

Soluciones relacionadas
IBM Cloud Infrastructure Center 

IBM Cloud Infrastructure Center es una plataforma de software compatible con OpenStack para gestionar la infraestructura de nubes privadas en IBM zSystems e IBM LinuxONE.

Explore Cloud Infrastructure Center
Soluciones de infraestructura de TI

Descubra los servidores, el almacenamiento y el software diseñados para la nube híbrida y su estrategia de IA.

Explore las soluciones de infraestructura de TI
Soluciones de infraestructura en la nube

Encuentre una solución de infraestructura en la nube que sea adecuada para las necesidades de su negocio y escale los recursos bajo demanda.

Soluciones en la nube
Dé el siguiente paso

Transforme la infraestructura de su empresa con las soluciones de IBM, tanto de nube híbrida como preparadas para la IA. Descubra los servidores, el almacenamiento y el software diseñados para proteger, escalar y modernizar su negocio o acceder a insights de expertos para mejorar su estrategia de IA generativa.

Explore las soluciones de infraestructura de TI Descargue el ebook