Este documento describe la generación de código intermedio y su optimización como parte del proceso de compilación. Explica que el código intermedio es una representación independiente de la máquina que se asemeja al código objeto. Luego detalla dos formas comunes de representación intermedia: el código de tres direcciones y su implementación mediante cuádruplos o tripletes. Finalmente, ilustra un ejemplo de código fuente y su correspondiente código de tres direcciones para el cálculo del factorial.
Este documento resume los conceptos de apuntadores en C, incluyendo la declaración y uso de apuntadores, operaciones con apuntadores como incrementar, restar y comparar, apuntadores a estructuras y arreglos, y el uso de memoria dinámica mediante la función malloc. También cubre la creación de estructuras de datos dinámicas enlazadas usando apuntadores.
Este documento presenta una introducción a los fundamentos de la programación en C. Explica la estructura básica de un programa en C, incluyendo funciones, la función main y la biblioteca estándar. También cubre conceptos clave como tipos de datos, variables, constantes, operadores aritméticos y lógicos, y expresiones.
El documento describe las estructuras básicas de lenguajes de programación como condicionales, bucles y de decisión. Explica operadores lógicos y de comparación usados en estas estructuras. Luego detalla las estructuras if-else, switch-case y bucles while, do-while y for. Finalmente presenta ejemplos sintaxis de sistemas de gestión de bases de datos Oracle, SQL, Access e Informix.
El documento introduce el lenguaje de programación C. Fue creado por Dennis Ritchie en los Laboratorios Bell, basándose en el lenguaje B. Combina elementos de lenguajes de alto y bajo nivel. Posee 32 palabras clave definidas por el estándar ANSI C. Los programas en C contienen elementos como comentarios, identificadores, constantes, variables, operadores e instrucciones.
Si quiere descargar la presentación y los códigos fuente, dirijase a:
http://programaciondecomputadoresunalmzl.wikispaces.com/codigos_y_diapositivas
Le agradecería si me reporta los errores que encuentre en la diapositiva (daalvarez arroba unal punto edu punto co)
El documento explica los apuntadores en C, los cuales son variables que almacenan direcciones de memoria y permiten acceder indirectamente a los valores almacenados en esas direcciones. Los apuntadores son importantes en C porque a veces son la única forma de expresar ciertos cálculos, permiten generar código más compacto y eficiente, y son una herramienta poderosa pero que requiere cuidado al usar. El documento describe la declaración, inicialización y operadores de los apuntadores, así como su uso con arreglos y funciones.
El documento presenta una introducción al lenguaje de programación C, describiendo su historia, características, elementos básicos como variables, operadores, sentencias y estructura de un programa en C. Explica conceptos como tipos de datos, constantes, identificadores, comentarios, declaración de variables, funciones, arreglos y cadenas de caracteres.
El documento presenta una introducción al lenguaje de programación C. Explica que C fue creado por Dennis Ritchie en los años 70 y que en 1983 se estableció el estándar ANSI C. Describe que C combina características de lenguajes de alto y bajo nivel y permite el manejo directo de memoria. Además, detalla elementos clave de un programa en C como comentarios, identificadores, constantes, variables, operadores y estructuras de control.
Este documento resume los conceptos de apuntadores en C, incluyendo la declaración y uso de apuntadores, operaciones con apuntadores como incrementar, restar y comparar, apuntadores a estructuras y arreglos, y el uso de memoria dinámica mediante la función malloc. También cubre la creación de estructuras de datos dinámicas enlazadas usando apuntadores.
Este documento presenta una introducción a los fundamentos de la programación en C. Explica la estructura básica de un programa en C, incluyendo funciones, la función main y la biblioteca estándar. También cubre conceptos clave como tipos de datos, variables, constantes, operadores aritméticos y lógicos, y expresiones.
El documento describe las estructuras básicas de lenguajes de programación como condicionales, bucles y de decisión. Explica operadores lógicos y de comparación usados en estas estructuras. Luego detalla las estructuras if-else, switch-case y bucles while, do-while y for. Finalmente presenta ejemplos sintaxis de sistemas de gestión de bases de datos Oracle, SQL, Access e Informix.
El documento introduce el lenguaje de programación C. Fue creado por Dennis Ritchie en los Laboratorios Bell, basándose en el lenguaje B. Combina elementos de lenguajes de alto y bajo nivel. Posee 32 palabras clave definidas por el estándar ANSI C. Los programas en C contienen elementos como comentarios, identificadores, constantes, variables, operadores e instrucciones.
Si quiere descargar la presentación y los códigos fuente, dirijase a:
http://programaciondecomputadoresunalmzl.wikispaces.com/codigos_y_diapositivas
Le agradecería si me reporta los errores que encuentre en la diapositiva (daalvarez arroba unal punto edu punto co)
El documento explica los apuntadores en C, los cuales son variables que almacenan direcciones de memoria y permiten acceder indirectamente a los valores almacenados en esas direcciones. Los apuntadores son importantes en C porque a veces son la única forma de expresar ciertos cálculos, permiten generar código más compacto y eficiente, y son una herramienta poderosa pero que requiere cuidado al usar. El documento describe la declaración, inicialización y operadores de los apuntadores, así como su uso con arreglos y funciones.
El documento presenta una introducción al lenguaje de programación C, describiendo su historia, características, elementos básicos como variables, operadores, sentencias y estructura de un programa en C. Explica conceptos como tipos de datos, constantes, identificadores, comentarios, declaración de variables, funciones, arreglos y cadenas de caracteres.
El documento presenta una introducción al lenguaje de programación C. Explica que C fue creado por Dennis Ritchie en los años 70 y que en 1983 se estableció el estándar ANSI C. Describe que C combina características de lenguajes de alto y bajo nivel y permite el manejo directo de memoria. Además, detalla elementos clave de un programa en C como comentarios, identificadores, constantes, variables, operadores y estructuras de control.
Este documento explica conceptos básicos de programación como funciones estándar, entrada y salida de datos, funciones definidas por el usuario, paso de parámetros y punteros. Define funciones como printf() y describe cómo se usan funciones estándar y definidas por el usuario, incluido cómo se pasan parámetros y se devuelven valores. También explica la diferencia entre paso por valor y paso por referencia.
Este documento presenta conceptos básicos sobre expresiones lógicas y operadores en el lenguaje de programación C, incluyendo operadores relacionales y lógicos, la función strcat para concatenar cadenas, operadores de asignación, incremento y decremento, y prioridad de operadores. También explica las funciones printf y scanf para entrada y salida estándar, con énfasis en el uso de especificadores de formato y secuencias de escape.
Este documento presenta una introducción al lenguaje de programación C. Explica la historia y características del lenguaje C, incluyendo sus palabras reservadas, elementos de un programa como comentarios, identificadores, constantes y variables. También describe operadores, sentencias, estructura básica de un programa en C y conceptos como arreglos unidimensionales.
Este documento trata sobre registros, archivos y punteros en lenguaje C. Explica que los registros permiten definir nuevos tipos de datos compuestos, los archivos son utilizados para entrada y salida de datos, y los punteros almacenan direcciones de memoria y permiten acceder y modificar valores de variables.
Este documento describe los apuntadores en C. En 3 oraciones o menos:
Los apuntadores son variables que contienen direcciones de memoria y permiten acceder a los valores almacenados en esas direcciones. Se declaran con un tipo de datos seguido de un asterisco y su nombre, y se usan los operadores & y * para obtener la dirección y el valor apuntado. Los apuntadores permiten el uso de estructuras de datos dinámicas mediante funciones como malloc() y free() que asignan y liberan memoria de forma dinámica.
Para convertir un algoritmo en un programa, se deben seguir varias fases: 1) edición del código fuente, 2) preprocesado del código, 3) compilación del código preprocesado que genera el código objeto, y 4) enlace del código objeto con bibliotecas para crear el programa ejecutable.
Este documento describe los elementos del lenguaje C++, incluyendo los caracteres permitidos, tipos de datos fundamentales como enteros y reales, tipos derivados como punteros y estructuras, palabras clave, comentarios, declaración y inicialización de variables, y expresiones numéricas y lógicas.
Este documento explica los conceptos básicos de operadores, expresiones, variables, entrada y salida en C, incluyendo operadores aritméticos, de asignación, incremento, relacionales y lógicos. También cubre la inicialización y declaración de variables, la construcción de expresiones, y el uso de las funciones printf() y scanf() para la entrada y salida formativa de datos.
Este documento trata sobre los apuntadores y direcciones de memoria en lenguajes de programación como C y C++. Brevemente:
1) Los apuntadores son variables que almacenan direcciones de memoria y permiten acceder y manipular datos almacenados en memoria.
2) Los apuntadores son fundamentales en C para manejar datos dinámicos, estructuras, funciones y arreglos.
3) Los arreglos en C son efectivamente punteros a la primera posición del arreglo, por lo que se pueden usar de forma intercambiable.
Este documento describe las funciones de biblioteca en C. Explica que estas funciones realizan operaciones comunes como entrada/salida, cálculos matemáticos y manipulación de cadenas y que se acceden a ellas mediante su nombre entre paréntesis. También cubre cómo incluir archivos de cabecera que definen estas funciones y un ejemplo de uso de la función toupper para convertir una letra minúscula a mayúscula.
Este documento describe las funciones en el lenguaje de programación C. Explica que una función es una porción de código que realiza una tarea específica y puede ser llamada desde otras partes del programa. Detalla la sintaxis básica de una función en C, incluyendo el tipo de datos, nombre, parámetros y cuerpo. Además, distingue entre variables globales y locales y los diferentes tipos de paso de parámetros.
Este documento presenta dos ejemplos de programas en lenguaje C. El primero pide al usuario que ingrese la base y altura de un triángulo, calcula su área, y muestra el resultado. El segundo pide dos números enteros, realiza la división entera del primero entre el segundo, y muestra el cociente y el resto. Ambos programas utilizan las funciones printf, scanf y otras funciones de la biblioteca estándar de C.
Este documento introduce los diferentes tipos de datos que pueden utilizarse en programación, incluyendo datos simples como enteros y caracteres, y datos compuestos como fechas y cadenas. Explica los cinco tipos de datos básicos (entero, flotante, lógico, carácter y cadena) y describe algunos operadores aritméticos comunes como la multiplicación, división y potencia. También cubre conceptos como la prioridad de los operadores y el error de dividir entre cero.
Este documento explica los arreglos de punteros, que son arreglos cuyos elementos son punteros. Cada puntero puede apuntar a cualquier ubicación de memoria. También cubre punteros a punteros y la asignación dinámica de memoria usando operadores como new. Finalmente, proporciona ejemplos de cómo implementar arreglos de punteros, punteros a punteros y asignación dinámica en programas C++.
Este documento resume el capítulo 7 de un libro sobre programación en lenguaje C. Explica los tipos de operadores y expresiones en programación, incluyendo aritméticas, lógicas, de caracteres y de cadenas. Detalla cada tipo de operador, sus tablas de verdad y prioridades, y proporciona ejemplos de expresiones y cómo evaluarlas. También recomienda ejercicios resueltos y propuestos relacionados con el contenido del capítulo.
Un puntero es una variable cuya valor es la dirección de memoria de otra variable. Los punteros permiten acceder y modificar el valor de la variable apuntada. Existen tantos tipos de punteros como tipos de datos, y se declaran anteponiendo un asterisco al tipo de la variable apuntada. Los punteros se inicializan asignando la dirección de una variable mediante el operador &, y se accede a su valor con el operador *.
Este documento presenta una propuesta de intervención para mejorar la enseñanza del curso de Teoría de la Computación en la Universidad Pontificia Bolivariana mediante el uso de tecnologías de la información y la comunicación (TIC). La propuesta busca complementar la enseñanza tradicional con actividades prácticas basadas en proyectos, el desarrollo de prototipos, y el uso de entornos mediados por TIC para promover el aprendizaje colaborativo. El objetivo general es diseñar e implementar un modelo de formación que des
Este documento contiene el código fuente de dos archivos (BabosinCanvas.java y DBVGameCanvas.java) que implementan un videojuego de plataformas 2D en Java ME. El código dibuja sprites, controla la animación y movimiento del personaje principal mediante el teclado, e implementa colisiones para detectar cuando el personaje choca con obstáculos u otros sprites como autos y enemigos.
Este documento explica conceptos básicos de programación como funciones estándar, entrada y salida de datos, funciones definidas por el usuario, paso de parámetros y punteros. Define funciones como printf() y describe cómo se usan funciones estándar y definidas por el usuario, incluido cómo se pasan parámetros y se devuelven valores. También explica la diferencia entre paso por valor y paso por referencia.
Este documento presenta conceptos básicos sobre expresiones lógicas y operadores en el lenguaje de programación C, incluyendo operadores relacionales y lógicos, la función strcat para concatenar cadenas, operadores de asignación, incremento y decremento, y prioridad de operadores. También explica las funciones printf y scanf para entrada y salida estándar, con énfasis en el uso de especificadores de formato y secuencias de escape.
Este documento presenta una introducción al lenguaje de programación C. Explica la historia y características del lenguaje C, incluyendo sus palabras reservadas, elementos de un programa como comentarios, identificadores, constantes y variables. También describe operadores, sentencias, estructura básica de un programa en C y conceptos como arreglos unidimensionales.
Este documento trata sobre registros, archivos y punteros en lenguaje C. Explica que los registros permiten definir nuevos tipos de datos compuestos, los archivos son utilizados para entrada y salida de datos, y los punteros almacenan direcciones de memoria y permiten acceder y modificar valores de variables.
Este documento describe los apuntadores en C. En 3 oraciones o menos:
Los apuntadores son variables que contienen direcciones de memoria y permiten acceder a los valores almacenados en esas direcciones. Se declaran con un tipo de datos seguido de un asterisco y su nombre, y se usan los operadores & y * para obtener la dirección y el valor apuntado. Los apuntadores permiten el uso de estructuras de datos dinámicas mediante funciones como malloc() y free() que asignan y liberan memoria de forma dinámica.
Para convertir un algoritmo en un programa, se deben seguir varias fases: 1) edición del código fuente, 2) preprocesado del código, 3) compilación del código preprocesado que genera el código objeto, y 4) enlace del código objeto con bibliotecas para crear el programa ejecutable.
Este documento describe los elementos del lenguaje C++, incluyendo los caracteres permitidos, tipos de datos fundamentales como enteros y reales, tipos derivados como punteros y estructuras, palabras clave, comentarios, declaración y inicialización de variables, y expresiones numéricas y lógicas.
Este documento explica los conceptos básicos de operadores, expresiones, variables, entrada y salida en C, incluyendo operadores aritméticos, de asignación, incremento, relacionales y lógicos. También cubre la inicialización y declaración de variables, la construcción de expresiones, y el uso de las funciones printf() y scanf() para la entrada y salida formativa de datos.
Este documento trata sobre los apuntadores y direcciones de memoria en lenguajes de programación como C y C++. Brevemente:
1) Los apuntadores son variables que almacenan direcciones de memoria y permiten acceder y manipular datos almacenados en memoria.
2) Los apuntadores son fundamentales en C para manejar datos dinámicos, estructuras, funciones y arreglos.
3) Los arreglos en C son efectivamente punteros a la primera posición del arreglo, por lo que se pueden usar de forma intercambiable.
Este documento describe las funciones de biblioteca en C. Explica que estas funciones realizan operaciones comunes como entrada/salida, cálculos matemáticos y manipulación de cadenas y que se acceden a ellas mediante su nombre entre paréntesis. También cubre cómo incluir archivos de cabecera que definen estas funciones y un ejemplo de uso de la función toupper para convertir una letra minúscula a mayúscula.
Este documento describe las funciones en el lenguaje de programación C. Explica que una función es una porción de código que realiza una tarea específica y puede ser llamada desde otras partes del programa. Detalla la sintaxis básica de una función en C, incluyendo el tipo de datos, nombre, parámetros y cuerpo. Además, distingue entre variables globales y locales y los diferentes tipos de paso de parámetros.
Este documento presenta dos ejemplos de programas en lenguaje C. El primero pide al usuario que ingrese la base y altura de un triángulo, calcula su área, y muestra el resultado. El segundo pide dos números enteros, realiza la división entera del primero entre el segundo, y muestra el cociente y el resto. Ambos programas utilizan las funciones printf, scanf y otras funciones de la biblioteca estándar de C.
Este documento introduce los diferentes tipos de datos que pueden utilizarse en programación, incluyendo datos simples como enteros y caracteres, y datos compuestos como fechas y cadenas. Explica los cinco tipos de datos básicos (entero, flotante, lógico, carácter y cadena) y describe algunos operadores aritméticos comunes como la multiplicación, división y potencia. También cubre conceptos como la prioridad de los operadores y el error de dividir entre cero.
Este documento explica los arreglos de punteros, que son arreglos cuyos elementos son punteros. Cada puntero puede apuntar a cualquier ubicación de memoria. También cubre punteros a punteros y la asignación dinámica de memoria usando operadores como new. Finalmente, proporciona ejemplos de cómo implementar arreglos de punteros, punteros a punteros y asignación dinámica en programas C++.
Este documento resume el capítulo 7 de un libro sobre programación en lenguaje C. Explica los tipos de operadores y expresiones en programación, incluyendo aritméticas, lógicas, de caracteres y de cadenas. Detalla cada tipo de operador, sus tablas de verdad y prioridades, y proporciona ejemplos de expresiones y cómo evaluarlas. También recomienda ejercicios resueltos y propuestos relacionados con el contenido del capítulo.
Un puntero es una variable cuya valor es la dirección de memoria de otra variable. Los punteros permiten acceder y modificar el valor de la variable apuntada. Existen tantos tipos de punteros como tipos de datos, y se declaran anteponiendo un asterisco al tipo de la variable apuntada. Los punteros se inicializan asignando la dirección de una variable mediante el operador &, y se accede a su valor con el operador *.
Este documento presenta una propuesta de intervención para mejorar la enseñanza del curso de Teoría de la Computación en la Universidad Pontificia Bolivariana mediante el uso de tecnologías de la información y la comunicación (TIC). La propuesta busca complementar la enseñanza tradicional con actividades prácticas basadas en proyectos, el desarrollo de prototipos, y el uso de entornos mediados por TIC para promover el aprendizaje colaborativo. El objetivo general es diseñar e implementar un modelo de formación que des
Este documento contiene el código fuente de dos archivos (BabosinCanvas.java y DBVGameCanvas.java) que implementan un videojuego de plataformas 2D en Java ME. El código dibuja sprites, controla la animación y movimiento del personaje principal mediante el teclado, e implementa colisiones para detectar cuando el personaje choca con obstáculos u otros sprites como autos y enemigos.
Este documento presenta la descripción de un curso de Ingeniería de Software I. El curso tiene una carga horaria semanal de 4 horas y no es habilitable. Los objetivos del curso son identificar las fases del desarrollo de software, modelar procesos problemáticos y desarrollar habilidades en buenas prácticas de desarrollo de software. El contenido incluye introducción a metodologías como RUP y XP, así como fases de planteamiento, diseño, desarrollo e implementación utilizando UML. La evaluación
Para subir una aplicación a Google Play, primero debes crear una cuenta de Google, registrarte como desarrollador en la consola de Google Play pagando $25 USD, y registrarte en Google Wallet. Luego, accedes a la consola para desarrolladores, seleccionas "Añadir nueva aplicación", subes el archivo APK y recursos, y especificas detalles como nombre, descripción, categoría e idioma. Finalmente, configuras las opciones de publicación como ubicaciones y contacto antes de publicar la aplicación.
Este documento presenta la descripción de un curso de Lenguajes y Compiladores. El curso cubre temas como análisis léxico, sintáctico y semántico, así como generación de código. Los estudiantes desarrollarán un proyecto que incluye construir un analizador léxico y elaborar la gramática de un lenguaje. El curso usa talleres y autoestudio para cubrir los contenidos.
Este documento presenta la materia Teoría de la Computación que se impartirá en el tercer semestre de la carrera de Ingeniería de Sistemas e Informática. El curso cubrirá temas como lenguajes formales, autómatas, gramáticas, máquinas de Turing y clases de complejidad. Se desarrollará mediante exposiciones del profesor y proyectos de los estudiantes.
El documento describe los procesos de análisis e ingeniería de requisitos en el desarrollo de software. Explica que el análisis implica entender el problema más que iniciar el diseño de la solución, y que la ingeniería de requisitos se enfoca en describir las necesidades del sistema. Además, detalla que no existe una única mejor forma de escribir requisitos, pero que lo más común es usar lenguaje natural complementado con diagramas, y que el documento IEEE 830 estandariza la información que debe contener un documento de requis
El documento presenta el Rational Unified Process (RUP), un proceso de desarrollo de software iterativo e incremental centrado en la arquitectura y dirigido por casos de uso. RUP define fases, hitos, roles, actividades y artefactos. Se compone de cuatro fases principales (Inception, Elaboration, Construction y Transition) donde se desarrollan iteraciones para entregar incrementos del producto.
Este documento describe los conceptos fundamentales de los procesos de ingeniería de software. Explica que un proceso de software es un conjunto de actividades que producen un producto de software, e identifica cuatro actividades fundamentales: especificación, desarrollo, validación y evolución del software. También señala que los procesos de software son importantes para gestionar de manera efectiva el desarrollo de software en diferentes industrias y aplicaciones.
El documento describe varios conceptos clave de la arquitectura de software, incluyendo estilos arquitectónicos como centrado en datos, flujo de datos y llamada y retorno, así como patrones arquitectónicos como tuberías y filtros, pizarrón y cliente-servidor. Explica que los estilos arquitectónicos definen familias de sistemas en términos de componentes, interfaces y restricciones, mientras que los patrones arquitectónicos proveen esquemas genéricos para solucionar problemas recurrentes.
Este documento describe los pasos para configurar una nueva red inalámbrica. Explica cómo elegir un canal de frecuencia libre de interferencias, establecer la seguridad WPA2 y asignar direcciones IP a los dispositivos de la red.
Este documento lista 30 herramientas digitales para crear recursos educativos como infografías, mapas mentales, presentaciones interactivas, e-books, videos y más. Algunas de las herramientas mencionadas incluyen iNFOGR.AM para crear infografías, Mohiomp para visualizar contenido en Dropbox, Evernote y Drive, y Eduteka que ofrece una suite de metodologías y herramientas educativas.
Este documento proporciona una guía sobre cómo instalar y usar el Android SDK, incluyendo información sobre aplicaciones Android, la arquitectura del framework, opciones de instalación, componentes de la instalación y demos para funciones como intents, fragmentos, gráficos 2D y 3D, proveedores de contenido y más.
Este documento describe los conceptos básicos de la programación en Pascal, incluyendo la estructura de un programa en Pascal, los tipos de datos, operadores, ciclos, estructuras de control y datos como arreglos y conjuntos. También cubre conceptos de la unidad gráfica como inicializar colores, mostrar texto en coordenadas y limpiar la pantalla.
El documento describe los conceptos básicos de la programación en Pascal, incluyendo la estructura de un programa en Pascal, los tipos de datos, operadores, ciclos, estructuras de control y estructuras de datos como arreglos y conjuntos.
El documento describe los conceptos básicos de la programación en Pascal, incluyendo la estructura de un programa en Pascal, los tipos de datos, operadores, ciclos, estructuras de control y estructuras de datos como arreglos y conjuntos.
El documento describe los conceptos básicos de la programación en Pascal, incluyendo la estructura de un programa en Pascal, los tipos de datos, operadores, ciclos, estructuras de control y estructuras de datos como arreglos y conjuntos.
El documento describe los conceptos básicos de la programación en Pascal, incluyendo la estructura de un programa en Pascal, los tipos de datos, operadores, ciclos, estructuras de control y estructuras de datos como arreglos y conjuntos.
Este documento discute varias técnicas de optimización que pueden ser aplicadas por un compilador para mejorar el rendimiento de un programa, como la eliminación de subexpresiones comunes y código muerto. También describe conceptos como diagramas de flujo de datos y bloques que representan el flujo de información en un sistema o proceso.
Este documento describe conceptos básicos del lenguaje ensamblador como definición de variables de diferentes tipos (DWORD, SDWORD, QWORD, REAL4), uso de directivas como = y EQU para definir constantes simbólicas, y procesos de ensamblado, enlazado y ejecución de programas ensamblador.
Este documento presenta información sobre el módulo NTIC's II de la carrera de Contabilidad y Auditoría. Incluye definiciones de hoja de cálculo, usos principales de hojas de cálculo en economía, tipos de hojas de cálculo existentes, ventajas de Excel 2007 vs Excel 2003, y explicaciones sobre celdas, barra de fórmulas, hojas y funciones en Excel.
El documento introduce conceptos básicos de programación como lenguajes de programación, variables, constantes, operaciones matemáticas, estructuras de control como if/else y bucles, y estructuras de datos como arreglos. Explica que la programación estructurada utiliza subrutinas y las tres estructuras básicas de secuencia, selección e iteración.
El documento introduce conceptos básicos de programación como lenguajes de programación, variables, constantes, operaciones con variables, estructuras de control como if, while y for, estructuras de almacenamiento como arreglos, y los paradigmas de programación estructurada y orientada a objetos. Explica que la programación es el proceso de diseñar y codificar programas de computadora y que requiere conocimientos en varias áreas.
El documento introduce conceptos básicos de programación como lenguajes de programación, variables, constantes, operaciones matemáticas, estructuras de control como if/else y bucles, y estructuras de datos como arreglos. Luego explica brevemente los paradigmas de programación estructurada y orientada a objetos, describiendo las clases, propiedades, métodos y objetos en este último paradigma.
La programación informática o programación algorítmica, acortadaAeChm-MgMs-NnNm-OpSe
El documento presenta información sobre programación informática. En menos de 3 oraciones, resume lo siguiente: La programación involucra diseñar, codificar y mantener código para crear programas que exhiban comportamientos deseados. Esto requiere conocimientos de lenguajes de programación, algoritmos y lógica formal. El documento también presenta ejemplos de lenguajes de programación como C# y Python, así como conceptos como variables, funciones matemáticas y estructuras de control.
Presentación de matlab electromagnetismo ...SimonCaceres4
Este documento describe las funciones básicas de MATLAB. MATLAB es un lenguaje de programación diseñado para realizar cálculos numéricos con vectores y matrices. El documento explica los elementos básicos de la interfaz de MATLAB como la ventana de comandos y el espacio de trabajo. También describe funciones matemáticas comunes, sentencias de control de flujo y cómo crear gráficos.
El documento describe diferentes tipos de asignaciones en lenguajes de programación. Explica la diferencia entre asignaciones por copia y asignaciones por referencia, mostrando ejemplos en C y Java. También analiza la analogía entre esquemas de asignación y pasaje de parámetros, y describe otras asignaciones como de expresiones y funciones.
1) El documento describe conceptos básicos de programación como funciones, arreglos y cadenas de texto en C#. Explica que una función es un bloque de código que puede o no devolver un valor y que las funciones ayudan a organizar y reutilizar el código.
2) También define los arreglos como conjuntos de datos del mismo tipo ordenados secuencialmente e indica que en C# los arreglos son objetos con propiedades como Length.
3) Por último, resume que una cadena de texto es una secuencia de caracteres que representa información y que las caden
Este documento presenta la información sobre el módulo NTIC's II de la carrera de Contabilidad y Auditoría. Incluye definiciones de hoja de cálculo, usos principales de hojas de cálculo en economía, tipos de hojas de cálculo existentes en el mercado, ventajas de Excel 2007 vs Excel 2003, y explicaciones sobre celdas, barra de fórmulas, hojas y funciones en Excel.
Este documento presenta la información sobre el módulo NTIC's II de la carrera de Contabilidad y Auditoría. Incluye definiciones de hoja de cálculo, usos principales de hojas de cálculo en economía, tipos de hojas de cálculo existentes en el mercado, ventajas de Excel 2007 vs Excel 2003, y explicaciones sobre celdas, barra de fórmulas, hojas y funciones en Excel.
Este documento presenta la información sobre el módulo NTIC's II de la carrera de Contabilidad y Auditoría. Incluye definiciones de hoja de cálculo, usos principales de hojas de cálculo en economía, tipos de hojas de cálculo existentes en el mercado, ventajas de Excel 2007 vs Excel 2003, y explicaciones sobre celdas, barra de fórmulas, hojas y funciones en Excel.
La etiqueta <html> define el documento HTML y es la raíz de cualquier página web. Indica al navegador que todo el contenido entre las etiquetas <html> y </html> es parte de un documento HTML.
Este documento describe los fundamentos de la programación en Visual Basic, incluyendo comentarios, declaración de variables, tipos de datos, operadores, funciones y caracteres ASCII. Explica conceptos básicos como la implementación de algoritmos en lenguajes de programación para crear programas que exhiban un comportamiento deseado.
Este documento presenta una introducción al curso de Ingeniería de Software. Explica que el curso estudiará las actividades del ciclo de vida de un proyecto de software con el objetivo de comprender los procesos y técnicas de desarrollo de software, aplicar enfoques de gestión de requisitos y despliegue de soluciones, y desarrollar habilidades profesionales. El curso cubrirá temas como requisitos, diseño, arquitectura, metodologías y mejores prácticas, y evaluará a los
Este documento describe un módulo de capacitación sobre ambientes virtuales de aprendizaje. El módulo incluye actividades como familiarizarse con las herramientas de comunicación de una plataforma de aprendizaje en línea, aprender conceptos clave sobre la participación en entornos virtuales, y discutir estrategias de moderación y evaluación para cursos en línea. El objetivo general es preparar a los participantes para funcionar con éxito tanto como estudiantes como docentes en entornos de educación virtual.
Este documento describe los conceptos y niveles de pruebas de software. Explica que las pruebas deben realizarse en todas las fases del desarrollo y no solo al final, y que incluyen pruebas de unidad, integración y sistema para verificar el correcto funcionamiento de cada unidad, la integración de unidades y el producto completo.
El documento describe la comunicación como un proceso inherente a las relaciones entre seres vivos que implica la emisión y recepción de señales con la intención de transmitir un mensaje. Explica que para que la comunicación sea exitosa, el receptor debe poder decodificar el mensaje e interpretarlo correctamente, y luego responder, cerrando así el ciclo comunicativo. Además, señala que no es posible no comunicar y que la mediación surge para resolver problemas de comunicación a través de más comunicación.
Este documento describe tres modelos de mediación: el modelo Harvard, el modelo circular-narrativo y el modelo transformativo. Explica los objetivos, valores, rol del mediador, proceso y finalización de cada modelo. También incluye información sobre la negociación colaborativa y sus elementos.
Este documento introduce los lenguajes regulares y expresiones regulares. Explica que los lenguajes regulares son los más simples en la jerarquía de Chomsky y se definen recursivamente usando operaciones como unión, concatenación y clausura. También define formalmente las expresiones regulares, notando que cada expresión regular denota un lenguaje regular.
El documento describe los conceptos clave de Extreme Programming (XP) relacionados con la ingeniería de requerimientos mediante historias de usuario, incluyendo el juego de planificación. Explica cómo las historias de usuario se utilizan para gestionar los requerimientos de manera dinámica y flexible, y cómo se descomponen en tareas de programación. También cubre temas como los niveles de detalle adecuados para las historias de usuario, la información que deben contener, y cómo se estima el esfuerzo asociado a las historias y
Este documento describe el proyecto Semillero Internet of Things de la Universidad Pontificia Bolivariana. El proyecto involucra a varios semilleros de investigación y dependencias de la universidad con el objetivo de desarrollar aplicaciones móviles. Se identifican usos académicos como la organización del tiempo, comunicación, acceso a información y colaboración. Se proponen aplicaciones como un asistente virtual con realidad aumentada, una aplicación de biblioteca y calendario, e integración con sistemas institucionales. El trabajo del semestre
El documento describe los analizadores descendentes predictivos y el método predictivo recursivo LL(1) para el análisis sintáctico. Explica que los analizadores LL(1) determinan la regla de producción a aplicar en cada paso en función del símbolo terminal que se encuentra en la cabeza de lectura, y que requieren que la gramática sea no ambigua, factorizada por la izquierda y no recursiva por la izquierda. También presenta el procedimiento general para la implementación de un analizador LL(1).
El documento describe la arquitectura de sistemas de software, incluyendo los componentes principales, los tres niveles de abstracción (estilo, patrón de diseño y patrón arquitectónico), y ejemplos como el patrón MVC. Explica que el patrón MVC separa la lógica de negocio de la interfaz de usuario a través de los roles de Modelo, Vista y Controlador.
Este documento presenta información general sobre Windows Phone. Detalla algunas de las características clave de la plataforma como su enfoque en las personas y la comunicación, la forma inteligente de usar aplicaciones, e Internet más allá del explorador. También incluye secciones sobre el hardware compatible con Windows Phone y herramientas para desarrolladores.
This document discusses object-oriented modeling and the Unified Modeling Language (UML). It introduces key concepts in modeling including systems, models, and views. Models abstract and simplify a system, while views depict selected aspects of a model. The document then discusses why software needs to be modeled, and introduces concepts, types, and classes in software modeling. It describes the relationship between the application domain and solution domain in object-oriented modeling. Finally, it provides an overview of commonly used UML diagrams including use case diagrams, class diagrams, sequence diagrams, statechart diagrams, and activity diagrams.
El documento describe los conceptos clave de la ingeniería de software, incluyendo el análisis y modelado de problemas, la escritura de requisitos, y la relación entre requisitos y arquitectura. Explica que el análisis del problema es más importante que iniciar el diseño de la solución, y que los requisitos deben expresar las propiedades y comportamiento del sistema dentro de las restricciones de diseño.
Este documento describe las fases iniciales del proceso de ingeniería de software, incluyendo la conceptualización y el análisis del problema. Explica cómo identificar los actores, pasos y eventos de un proceso, y cómo crear diagramas de procesos que representen esta información usando símbolos como actores, procesos, eventos y flujos. También incluye ejemplos de posibles aplicaciones de software.
El curso Fundamentos de Programación tiene como objetivo principal adquirir las habilidades básicas de programación para resolver problemas usando lenguajes de programación. Los objetivos específicos incluyen aplicar destrezas para resolver problemas de ingeniería, conocer técnicas de programación modular, estructurada y orientada a objetos, y utilizar al menos un lenguaje de programación como C. El curso se enfoca en conceptos fundamentales como algoritmos, variables, tipos de datos, estructuras de control y datos, y introduce conceptos de programación orientada a objetos.
Este documento presenta una introducción a las gramáticas y lenguajes libres de contexto. Define formalmente una gramática como G = (VN, VT, S, P), donde VN es el vocabulario no terminal, VT es el vocabulario terminal, S es el símbolo inicial y P es el conjunto de reglas de producción. Explica que una gramática libre de contexto tiene reglas de producción de la forma A → α, donde A es un símbolo no terminal y α es una cadena de símbolos terminales y no terminales. Define un lenguaje libre de contexto como el lengu
The Java Platform, Micro Edition (Java ME) Software Development Kit (SDK) 3.0 integrates Connected Limited Device Configuration (CLDC), Connected Device Configuration (CDC), and Blu-ray Disc Java (BD-J) technology into a single development environment. It includes emulators for different devices, on-device debugging tools, application profiling tools, and a modular architecture. The SDK supports the latest APIs and provides a lightweight development environment for creating Java ME applications.
1. Cap´ıtulo 7
Generaci´on de c´odigo
intermedio. Optimizaci´on
Bibliograf´ıa:
Aho, A.V., Sethi, R., Ullman, J.D. (1990), Compiladores:
principios, t´ecnicas y herramientas, Tema 8, 9, 10 (pag. 478-
666).
Louden, K.C. (1997), Compiler Construction: Principles and
Practice, Tema 8, p´aginas: 398-481.
1. Introducci´on.
2. Tipos de representaciones intermedias: C´odigo de 3-direcciones.
3. C´odigo intermedio como un atributo sintetizado.
4. Generaci´on de c´odigo para expresiones y sentencias de con-
trol:
a) Proposiciones de asignaci´on.
b) Expresiones aritm´eticas.
c) Expresiones booleanas.
d) Sentencias de control.
e) Funciones.
5. Optimizaci´on de c´odigo:
a) Bloques b´asicos y optimizaci´on local.
215
2. 216CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
b) Eliminaci´on de subexpresiones comunes.
c) Eliminaci´on de c´odigo muerto.
d) Transformaciones aritm´eticas.
e) Empaquetamiento de variables temporales.
f ) Mejoras en lazos.
7.1. Introducci´on
Como se coment´o en el primer cap´ıtulo el proceso de la com-
pilaci´on se desglosa en dos partes: la parte que depende s´olo del
lenguaje fuente (etapa inicial o front-end ) y la parte que depende
s´olo del lenguaje objeto (etapa final o back-end).
Etapa inicial: corresponde con la parte de an´alisis (l´exico,
sint´actico y sem´antico).
Etapa final: corresponde con la parte de s´ıntesis (generaci´on
de c´odigo).
La etapa inicial traduce un programa fuente a una representaci´on
intermedia a partir de la cual la etapa final genera el c´odigo ob-
jeto.
De esta forma, los detalles que tienen que ver con las caracter´ısti-
cas del lenguaje objeto (c´odigo ensamblador, c´odigo m´aquina ab-
soluto o relocalizable, . . . ), la arquitectura de la m´aquina (n´umero
de registros, modos de direccionamiento, tama˜no de los tipos de
datos, memoria cache, ...), el entorno de ejecuci´on (estructura de
registros y memoria de la m´aquina donde se va a ejecutar el pro-
grama . . . ) y el sistema operativo se engloban en la etapa final y
se aislan del resto.
La generaci´on de c´odigo es la tarea m´as complicada de un com-
pilador. Las ventajas de utilizar esta representaci´on intermedia,
independiente de la m´aquina en la que se va a ejecutar el progra-
ma, son:
Se puede crear un compilador para una nueva m´aquina dis-
tinta uniendo la etapa final de la nueva m´aquina a una etapa
inicial ya existente. Se facilita la redestinaci´on.
3. 7.2. TIPOS DE REPRESENTACIONES INTERMEDIAS: EL C ´ODIGO DE 3-DIRECCIONES217
Se puede aplicar, a la representaci´on intermedia, un opti-
mador de c´odigo independiente de la m´aquina.
La figura 7.1 muestra las dos etapas y como se relacionan entre
s´ı a trav´es de la representaci´on intermedia.
Componentes
Analizador
Analizador
Arbol
Analizador
Optimizador de
fuente
Programa ETAPA
INICIAL
ETAPA
FINAL
Generador de
Optimizador de
Intermedio
código intermedio
Semántico
Sintáctico
Sintáctico
léxicos
Léxico
Código
código máquina
Código máquina
Código máquina
Figura 7.1: Etapa inicial y final de un compilador
En este cap´ıtulo veremos c´omo traducir las construcciones de los
lenguajes de programaci´on como: las declaraciones, asignaciones
y proposiciones de flujo de control a una representaci´on interme-
dia. La mayor parte de las traducciones de estas proposiciones
se pueden implantar durante el an´alisis sint´actico utilizando las
t´ecnicas de traducci´on vistas en en el dise˜no de esquemas de tra-
ducci´on dirigidos por la sintaxis (ETDS).
7.2. Tipos de representaciones intermedias: el
c´odigo de 3-direcciones
Una representaci´on intermedia es una estructura de datos que
representa al programa fuente durante el proceso de la traduc-
ci´on a c´odigo objeto. Hasta ahora hemos usado el ´arbol de an´ali-
4. 218CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
sis sint´actico como representaci´on intermedia, junto con la tabla
de s´ımbolos que conten´ıa informaci´on sobre los nombres (vari-
ables, constantes, tipos y funciones) que aparec´ıan en el programa
fuente.
Aunque el ´arbol de an´alisis sint´actico es una representaci´on v´ali-
da, no se parece ni remotamente al c´odigo objeto, en el que s´olo
se emplean saltos a direcciones en memoria en vez de construc-
ciones de alto nivel, como sentencias if-then-else. Es nece-
sario generar una nueva forma de representaci´on intermedia. A
esta representaci´on intermedia, que se parece al c´odigo objeto
pero que sigue siendo independiente de la m´aquina, se le llama
c´odigo intermedio.
El c´odigo intermedio puede tomar muchas formas. Todas ellas se
consideran como una forma de linearizaci´on del ´arbol sint´acti-
co, es decir, una representaci´on del ´arbol sint´actico de forma se-
cuencial. El c´odigo intermedio m´as habitual es el c´odigo de 3-
direcciones.
El c´odigo de tres direcciones es una secuencia de proposiciones
de la forma general
x = y op z
donde op representa cualquier operador; x,y,z representan vari-
ables definidas por el programador o variables temporales gener-
adas por el compilador. y,z tambi´en pueden representar con-
stantes o literales. op representa cualquier operador: un operador
aritm´etico de punto fijo o flotante, o un operador l´ogico sobre
datos booleanos.
No se permite ninguna expresi´on aritm´etica compuesta, pues s´olo
hay un operador en el lado derecho. Por ejemplo, x+y*z se debe
traducir a una secuencia, donde t1, t2 son variables temporales
generadas por el compilador.
t1 = y ∗ z
t2 = x + t1
Las expresiones compuestas y las proposiciones de flujo de control
se han de descomponer en proposiciones de este tipo, definiendo
un conjunto suficientemente amplio de operadores. Se le llama
c´odigo de 3-direcciones porque cada proposici´on contiene, en el
5. 7.2. TIPOS DE REPRESENTACIONES INTERMEDIAS: EL C ´ODIGO DE 3-DIRECCIONES219
caso general, tres direcciones, dos para los operandos y una para
el resultado. (Aunque aparece el nombre de la variable, realmente
corresponde al puntero a la entrada de la tabla de s´ımbolos de
dicho nombre).
El c´odigo de tres direcciones es una representaci´on linealizada
(de izquierda a derecha) del ´arbol sint´actico en la que los nom-
bres temporales corresponden a los nodos internos. Como estos
nombres temporales se representan en la memoria no se especifica
m´as informaci´on sobre ellos en este tipo de c´odigo. Normalmente
se asignar´an directamente a registros o se almacenar´an en la tabla
de s´ımbolos.
2*a+b-3
t1 t2
t3
+
* -
a b 32
C´odigo de 3-direcciones:
t1 = 2 * a
t2 = b - 3
t3 = t1 + t2
7.2.1. Tipos de proposiciones de 3-direcciones
La forma de c´odigo de 3-direcciones que hemos visto hasta aho-
ra es insuficiente para representar todas las construcciones de un
lenguaje de programaci´on (saltos condicionales, saltos incondi-
cionales, llamadas a funciones, bucles, etc), por tanto es nece-
sario introducir nuevos operadores. El conjunto de proposiciones
(operadores) debe ser lo suficientemente rico como para poder
implantar las operaciones del lenguaje fuente.
Las proposiciones de 3-direcciones van a ser en cierta manera
an´alogas al c´odigo ensamblador. Las proposiciones pueden tener
etiquetas simb´olicas y existen instrucciones para el flujo de con-
trol (goto). Una etiqueta simb´olica representa el ´ındice de una
proposici´on de 3-direcciones en la lista de instrucciones.
6. 220CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
Las proposiciones de 3-direcciones m´as comunes que utilizaremos:
1. Proposiciones de la forma x = y op z donde op es un op-
erador binario aritm´etico, l´ogico o relacional.
2. Instrucciones de la forma x = op y, donde op es un oper-
ador unario (operador negaci´on l´ogico, menos unario, oper-
adores de desplazamiento o conversi´on de tipos).
3. Proposiciones de copia de la forma x = y, donde el valor de
y se asigna a x.
4. Salto incondicional goto etiq. La instrucci´on con etiqueta
etiq es la siguiente que se ejecutar´a.
5. Saltos condicionales como if false x goto etiq.
6. param x y call f para apilar los par´ametros y llamadas
a funciones (los procedimientos se consideran funciones que
no devuelven valores). Tambi´en return y, que es opcional,
para devolver valores. C´odigo generado como parte de una
llamada al procedimiento p(x 1,x 2,...,x n).
param x1
param x2
...
param xn
call p,n
7. Asignaciones con ´ındices de la forma x = y[i], donde se
asigna a x el valor de la posici´on en i unidades de memoria
m´as all´a de la posici´on y. O tambi´en x[i] = y .
8. Asignaciones de direcciones a punteros de la forma x = &y
(el valor de x es la direcci´on de y), x = *y (el valor de x se
iguala al contenido de la direcci´on indicada por el puntero
y) ´o *x = y (el objeto apuntado por x se iguala al valor de
y).
Ejemplo. Consideremos el c´odigo que calcula el factorial de un
n´umero. La tabla 7.1 muestra el c´odigo fuente y el c´odigo de 3-
direcciones. Existe un salto condicional if false que se usa para
7. 7.2. TIPOS DE REPRESENTACIONES INTERMEDIAS: EL C ´ODIGO DE 3-DIRECCIONES221
traducir las sentencias de control if-then, repeat-until
que contiene dos direcciones: el valor condicional de la expresi´on
y la direcci´on de salto. La proposici´on label s´olo tiene una di-
recci´on. Las operaciones de lectura y escritura, read, write,
con una sola direcci´on. Y una instrucci´on de parada halt que no
tiene direcciones.
read x; read x
if 0<x then t1 = 0 < x
fact:=1; if false t1 goto L1
repeat fact=1
fact:=fact*x; label L2
x:=x-1; t2=fact * x
until x=0; fact=t2
write fact; t3=x-1
end; x=t3
t4=x==0
if false t4 goto L2
write fact
label L1
halt
Cuadro 7.1: C´odigo fuente y c´odigo de 3-direcciones para el c´alculo del factorial
8. 222CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.2.2. Implementaci´on de c´odigo de tres direcciones
Una proposici´on de c´odigo de 3-direcciones se puede implantar
como una estructura tipo registro con campos para el operador,
los operandos y el resultado. La representaci´on final ser´a entonces
una lista enlazada o un vector de proposiciones.
Implementaci´on mediante cu´adruplos
Un cu´adruplo es una estructura tipo registro con cuatro campos
que se llaman (op, result, arg1, arg2). El campo op
contiene un c´odigo interno para el operador.
Por ejemplo, la proposici´on de tres direcciones x = y + z se
representa mediante el cu´adruplo (ADD, x,y, z). Las proposi-
ciones con operadores unarios no usan el arg2. Los campos que
no se usan se dejan vac´ıos o un valor NULL. Como se necesitan
cuatro campos se le llama representaci´on mediante cu´adruplos.
Una posible implantaci´on del programa que calcula el factorial
mediante cu´adruplos se muestra ahora en la parte izquierda de la
tabla 7.2.
9. 7.2. TIPOS DE REPRESENTACIONES INTERMEDIAS: EL C ´ODIGO DE 3-DIRECCIONES223
(a) Cu´adruplos (b) Tripletes
(read,x,–,–) (0) (read,x,–)
(isbigger,t1,x,0) (1) (isbigger,x,0)
(if false,t1,L1,–) (2) (if false, (1), (11))
(assign,fact,1,–) (3) (assign, fact,1)
(label,L2,–,–) (4) (mult, fact,x)
(mult,t2,fact,x) (5) (assign, (4), fact)
(assign,fact,t2,–) (6) (sub, x,1)
(sub,t3,x,1) (7) (assign, (6), x)
(assign,x,t3,–) (8) (isequal, x, 0)
(isequal,t4,x,0) (9) (if false, (8),(4))
(if false,t4,L2,–) (10) (write,fact,–)
(write,fact,–,–) (11) (halt,–,–)
(label,L1,–,–)
(halt,–,–,–)
Cuadro 7.2: C´odigo de 3-direcciones mediante: (a) cu´adruplos y (b) tripletes
Implementaci´on mediante tripletes
Para evitar tener que introducir nombres temporales en la tabla
de s´ımbolos, se hace referencia a un valor temporal seg´un la posi-
ci´on de la proposici´on que lo calcula. Las propias instrucciones
representan el valor del nombre temporal. La implantaci´on se hace
mediante registros de s´olo tres campos (op, arg1, arg2).
La parte derecha de la tabla 7.2 muestra la implantaci´on mediante
tripletes del c´alculo del factorial. Los n´umeros entre par´entesis
representan punteros dentro de la lista de tripletes, en tanto que
los punteros a la tabla de s´ımbolos se representan mediante los
nombres mismos.
En la notaci´on de tripletes se necesita menor espacio y el com-
pilador no necesita generar los nombre temporales. Sin embargo,
en esta notaci´on, trasladar una proposici´on que defina un val-
or temporal exige que se modifiquen todas las referencias a esa
proposici´on. Lo cual supone un inconveniente a la hora de opti-
mizar el c´odigo, pues a menudo es necesario cambiar proposiciones
de lugar.
10. 224CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
A partir de ahora nos vamos a centrar en la notaci´on de cu´adru-
plos, que es la que se implantar´a en la pr´actica 3. La figura 7.2
a continuaci´on muestra en c´odigo C como se podr´ıa implantar la
estructura de datos para los cu´adruplos:
typedef enum {assign, add, mult,if false, goto, label, read, write, isequal, . . . }
OpKind;
typedef struct {
int val;// para valores
char *name;// para identificadores de variables
} Address;
typedef struct {
OpKind op;
Address result, arg1, arg2;
} Quad;
Figura 7.2: Posible implantaci´on en C de la estructura cu´adruplo
Por simplicidad se podrian considerar los campos result, arg1,
arg2 como punteros a caracter. En esta implantaci´on s´olo se per-
mite que un argumento represente una constante entera o una ca-
dena ( la cadena representa el nombre de un temporal o una vari-
able de la tabla de s´ımbolos). Una alternativa a almacenar nom-
bres en el cu´adruplo es almacenar punteros a la tabla de s´ımbolos,
con lo que se evita tener que hacer operaciones de b´usqueda en
un procesado posterior.
7.3. C´odigo intermedio como un atributo sin-
tetizado
El c´odigo intermedio puede ser considerado como un atributo sin-
tetizado. El c´odigo intermedio es visto como una cadena de car-
acteres y se puede dise˜nar un esquema de traducci´on dirigido por
la sintaxis (ETDS) que genere dicho c´odigo al recorrer el ´arbol de
an´alisis sint´actico en orden postfijo.
Consideremos como ejemplo la siguiente gram´atica simplificada
que genera expresiones aritm´eticas. Dada la expresi´on E → E1 +
11. 7.3. C ´ODIGO INTERMEDIO COMO UN ATRIBUTO SINTETIZADO 225
E2 se calcula el valor del no-terminal E en un nombre temporal
t. Por el momento, se crea un nuevo nombre cada vez que se
necesita. M´as tarde veremos un sencillo m´etodo para reutilizar
los nombres temporales.
Cada no-terminal tiene dos atributos:
E.lugar, nombre temporal que contendr´a el valor de E,
(t1, t2, . . .).
E.cod, serie de todas las proposiciones de c´odigo de 3-direcciones
que calculan E.
Ambos atributos son sintetizados. La funci´on nuevotemp() gen-
era nombres distintos t1, t2, ... cada vez que es llamada.
Las llaves indican una instrucci´on de c´odigo de 3-direcciones. El
s´ımbolo // representa la concatenaci´on de los trozos de c´odigo.
Producci´on Regla Sem´antica
S → id := E S.cod = E.cod//{lexema(id) = E.lugar}
E → E1 + E2 E.lugar = nuevotemp();
E.cod = E1.cod//E2.cod//{E.lugar = E1.lugar + E2.lugar}
E → (E1) E.lugar = E1.lugar
E.cod = E1.cod
E → id E.lugar = lexema(id)
E.cod = “ “
E → num E.lugar = lexema(num);
E.cod = “ “
Cuadro 7.3: ETDS para expresiones aritm´eticas
Veamos el ejemplo x=x+3+4. La figura 7.3 muestra el ´arbol sint´acti-
co. El c´odigo de 3-direcciones correspondiente es:
t1 = x + 3
t2 = t1 + 4
x = t2
12. 226CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
lugar=’x’ cod=’ ’ lugar=’3’
cod=’ ’ lugar=’4’lugar=t1
cod=’ ’
cod=’t1=x+3’
lugar=t2cod=’t1=x+3
t2=t1+4’
cod=’t1=x+3
x=t2’
t2=t1+4
id
(x)
S
=
E
E E+
+ EE
id num
num
(x) (3)
(4)
Figura 7.3: ´Arbol sint´actico para el ejemplo x=x+3+4
Reutilizaci´on de los nombres temporales
Hasta ahora se ha supuesto que la funci´on nuevotemp() genera
un nombre temporal cada vez que se necesita un temporal . Sin
embargo, los nombres temporales utilizados para guardar valores
intermedios de los c´alculos de expresiones tienen que ser intro-
ducidos en la tabla de s´ımbolos para guardar sus valores con el
consiguiente aumento de espacio.
Los nombres temporales se pueden reutilizar mediante un sencillo
m´etodo que consiste en llevar una cuenta c, iniciada a cero, de
variables temporales. Cuando se utilice un nombre temporal como
operando hay que decrementar el valor de c en 1. Siempre que se
genere un nuevo nombre temporal se usa el valor del contador
(sprintf(simbolo,‘‘t %d’’,c)) y se incrementa el valor
de c en 1. Consideremos el ejemplo: x = a ∗ b + c ∗ d − e ∗ f
=
id
(x)
-
+ *
e f* *
a b c d
Figura 7.4: ´Arbol sint´actico para el ejemplo x=a*b+c*d-e*f
13. 7.3. C ´ODIGO INTERMEDIO COMO UN ATRIBUTO SINTETIZADO 227
Proposici´on Valor de c
0
t0 = a * b 1
t1 = c * d 2
t0 = t0 + t1 1
t1 = e * f 2
t0 = t0 - t1 1
x = t0 0
Cuidado: este m´etodo no es aplicable para temporales que se
utilizan m´as de una vez. Por ejemplo, al evaluar una expresi´on en
una proposici´on condicional. A estos valores hay que asignarles
nombres temporales creados con un nombre propio.
14. 228CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.4. Traducci´on de proposiciones de asignaci´on
y expresiones aritm´eticas
La tabla 7.4 a continuaci´on muestra como se puede realizar la
traducci´on de expresiones aritm´eticas m´as complejas. La funci´on
gen cuad(op, result, arg1, arg2)
genera el correspondiente c´odigo de 3-direcciones en notaci´on
de cu´adruplos. Cada vez que es llamada genera una lista de c´odigo
con s´olo un cu´adruplo.
Producci´on Reglas Sem´anticas
S → id := E S.cod = E.cod//gen cuad(ASSIGN, id.lugar, E.lugar, −−)
E → E1 + E2 E.lugar = nuevotemp()
E.cod = E1.cod//E2.cod//gen cuad(ADD, E.lugar, E1.lugar, E2.lugar)
E → E1 ∗ E2 E.lugar = nuevotemp()
E.cod = E1.cod//E2.cod//gen cuad(MULT, E.lugar, E1.lugar, E2.lugar)
E → −E1 E.lugar = nuevotemp()
E.cod = E1.cod//gen cuad(UMINUS, E.lugar, E1.lugar, −−)
E → (E1) E.lugar = E1.lugar
E.cod = E1.cod
E → id E.lugar = lexema(id)
E.cod = “ “
Cuadro 7.4: ETDS para expresiones aritm´eticas
En la pr´actica las proposiciones de 3-direcciones se pueden escribir
de forma consecutiva a un archivo de salida en lugar de construir
la lista de proposiciones en el atributo cod, lo que facilita la
implementaci´on.
Veamos ahora como se puede implantar una funci´on recursiva que
genera el c´odigo de 3-direcciones, que llamaremos genera c´odigo().
Al fin y al cabo se trata de un atributo sintetizado y podemos
recorrer el ´arbol en modo postfijo. Supongamos que la funci´on
devuelve un registro llamado TAC (Three-Address-Code),
que contiene dos campos:
lugar (nombre temporal donde se almacena el valor de una
15. 7.4. TRADUCCI ´ON DE PROPOSICIONES DE ASIGNACI ´ON Y EXPRESIONES ARITM´ETICAS2
expresi´on)
cod (puntero a la lista de cu´adruplos que almacena el c´odi-
go).
Se utiliza el lexema, pero ser´ıa en realidad un puntero a la tabla
de s´ımbolos.
16. 230CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
typedef enum {n assign, n mult, n add, n id, ...} NodeKind;
typedef struct streenode {
NodeKind kind;
int nchilds; // n´umero de hijos
struct streenode childs[MAXNUMCHILDS];
// se puede usar una lista con primer hijo que apunta a hermanos
int val; // para constantes num´ericas
char *strval; // para identificadores, deberia ser puntero a la
TS
} STreeNode;
typedef STreeNode * SyntaxTreeRoot;
typedef struct {
char lugar[10];
lista codigo *cod; //puntero a lista de cu´adruplos
} TAC;
=
id E E E
1 2 E E
1 2
n_menos n_mult
E E
1 2
n_mas
n_uminus
E
n_id n_num
Figura 7.5: Tipos de nodo
TAC genera c´odigo (STreeNode *nodo) {
TAC datos;
TAC aux1, aux2;
lista codigo *cod=NULL;
datos.cod=NULL;
switch (node->kind) {
case n assign: // childs[0]=id, childs[1]=E
aux1=genera codigo(childs[1]);
cod=gen cuad(assign, lexema(id), aux1.lugar,--);
datos.cod=concatena codigo(aux1.cod,cod);
break;
case n add: // childs[0]=E1, childs[1]=E2
aux1=genera codigo(childs[0]);
17. 7.4. TRADUCCI ´ON DE PROPOSICIONES DE ASIGNACI ´ON Y EXPRESIONES ARITM´ETICAS2
aux2=genera codigo(childs[1]);
datos.lugar=nuevotemp();
cod=gen cuad(add, datos.lugar,aux1.lugar,aux2.lugar);
datos.cod=concatena codigo(aux1.cod,aux2.cod,cod);
break;
case n mult: // childs[0]=E1, childs[1]=E2
aux1=genera codigo(childs[0]);
aux2=genera codigo(childs[1]);
datos.lugar=nuevotemp();
cod=gen cuad(mult, datos.lugar,aux1.lugar,aux2.lugar);
datos.cod=concatena codigo(aux1.cod,aux2.cod,cod);
break;
case n parentesis: // childs[1]=E
// no haria falta crear este tipo de nodo
datos=genera codigo(childs[1]);
break;
case n id:
datos.lugar=lexema(id);
datos.cod=NULL;
break; }
case n num:
datos.lugar=lexema(num);
datos.cod=NULL;
break; }
return(datos);
}
18. 232CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.5. Traducci´on de expresiones booleanas
Las expresiones booleanas se utilizan principalmente como parte
de las proposiciones condicionales que alteran el flujo de control
del programa, if-then, if-then-else, while-do. Las ex-
presiones booleanas se componen de los operadores booleanos
and,or,not aplicados a variables booleanas o expresiones rela-
cionales.
A su vez, las expresiones relacionales son de la forma E1 oprel
E2, donde E1 y E2 son expresiones aritm´eticas y oprel es cualquier
operador relacional <, >, <=, >=,....
Consideremos expresiones booleanas generadas por la gram´atica:
E → E or E
| E and E
| not E
| ( E )
| id oprel id
| true
| false | id
Uno de los m´etodos para traducir expresiones booleanas a c´odigo
de 3-direcciones consiste en codificar num´ericamente los valores
true y false y evaluar una expresi´on booleana como una expre-
si´on aritm´etica, siguiendo unas prioridades. A menudo se utiliza
1 para indicar true y 0 para indicar false.
Las expresiones booleanas se eval´uan de manera similar a una ex-
presi´on aritm´etica de izquierda a derecha. Supongamos el ejemp-
lo: a or b and not c. La secuencia de c´odigo de 3-direcciones
correspondiente es:
t1 = a or b
t2 = not c
t3 = t1 and t2
La siguiente gram´atica en la tabla 7.5 muestra el ETDS para
producir c´odigo de 3-direcciones para las expresiones booleanas.
La funci´on para generar c´odigo se podr´ıa ampliar a˜nadiendo nuevos
casos a la sentencia switch correspondientes a los tipos de no-
19. 7.5. TRADUCCI ´ON DE EXPRESIONES BOOLEANAS 233
Producci´on Reglas Sem´anticas
E → E1 or E2 E.lugar = nuevotemp()
E.cod = E1.cod//E2.cod//gen cuad(or, E.lugar, E1.lugar, E2.lugar)
E → E1 and E2 E.lugar = nuevotemp()
E.cod = E1.cod//E2.cod//gen cuad(and, E.lugar, E1.lugar, E2.lugar)
E → not E1 E.lugar = nuevotemp()
E.cod = E1.cod//gen cuad(not, E.lugar, E1.lugar, −−)
E → (E1) E.lugar = E1.lugar
E.cod = E1.cod
E → id1 oprel id1 E.lugar = nuevotemp();
E.cod = gen cuad(oprel, E.lugar, lexema(id1), lexema(id2))
E → true E.lugar = nuevotemp();
E.cod = gen cuad(assign, E.lugar, 1, −−)
E → false E.lugar = nuevotemp();
E.cod = gen cuad(assign, E.lugar, 0, −−)
E → id E.lugar = lexema(id)
E.cod = ““
Cuadro 7.5: ETDS para expresiones booleanas utilizando una representaci´on
num´erica
dos asociados a los operadores l´ogicos. Por ejemplo, para el nodo
correspondiente al operador l´ogico and, nodo tipo n and, se in-
sertar´ıa el siguiente trozo de c´odigo:
case n and: // childs[0]=E1, childs[1]=E2
aux1=genera codigo(childs[0]);
aux2=genera codigo(childs[1]);
datos.lugar=nuevotemp();
cod=gen cuad(and, datos.lugar,aux1.lugar,aux2.lugar);
datos.cod=concatena codigo(aux1.cod,aux2.cod,cod);
break;
20. 234CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.6. Traducci´on de proposiciones de control
Pasemos a considerar ahora la traducci´on de proposiciones de con-
trol if-then, if-then-else, while-do generadas por la
siguiente gram´atica:
S → if E then S1
| if E then S1 else S2
| while E do S1
7.6.1. Proposici´on if-then
Supongamos una sentencia if-then de la forma S → if E
then S1, ver diagrama de flujo en figura 7.6. Para generar el
c´odigo correspondiente a esta proposici´on habr´ıa que a˜nadir a
la funci´on genera c´odigo() un nuevo caso para la sentencia
switch que contemple este tipo de nodo en el ´arbol sint´actico,
nodo n ifthen.
SALTO CONDICIONAL
CODIGO S
F
V
Etiqueta 1
CODIGO CALCULO E
n_ifthen
SE
(a) (b)
Figura 7.6: (a) Diagrama de flujo para la proposici´on if-then y (b) tipo de
nodo
TAC datos;
TAC aux1, aux2;
lista codigo *cod;
datos.cod=NULL;
direcciones dir; //usamos direcci´on al salto, en vez de etiquetas
case n ifthen: // childs[0]=E, childs[1]=S1
aux1=genera codigo(childs[0]);
cod=gen cuad(if false,--, aux1.lugar, dir?);
// a´un no se sabe la direc. de salto
aux2=genera codigo(childs[1]);
21. 7.6. TRADUCCI ´ON DE PROPOSICIONES DE CONTROL 235
dir=sgtedirlibre(); //relleno de retroceso
rellena(cod,arg3,dir)
datos.cod=concatena codigo(aux1.cod,cod,aux2.cod);
break;
Supondremos que tenemos una funci´on, sigtedirlibre(), que
guarda el´ındice de la siguiente instrucci´on libre (la funci´on gen cuad()
incrementa ese contador). En la implantaci´on se ha optado por
utilizar direcciones directamente a las instrucciones en vez de usar
etiquetas.
7.6.2. Proposici´on if-then-else
Supongamos una sentencia if-then-else de la forma S → if
E then S1 else S2 , cuyo diagrama de flujo tiene la forma
representada en la figura 7.7. Para generar el c´odigo correspondi-
ente a esta proposici´on habr´ıa que a˜nadir a la funci´on genera c´odigo()
un nuevo caso para la sentencia switch que contemple este tipo
de nodo en el ´arbol sint´actico, nodo n ifthenelse. Este frag-
mento de c´odigo se podr´ıa implantar de forma similar a como
hemos hecho en la secci´on anterior. Ver ejercicios.
´CODIGO CALCULO E
SALTO CONDICIONAL F
V
CODIGO S1
SALTO INCONDICIONAL
CODIGO S2
Etiqueta 1
Etiqueta 2 n_ifthen_else
S2E S1
(a= (b)
Figura 7.7: (a)Diagrama de flujo para la proposici´on if-then-else y (b) tipo
de nodo
22. 236CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.6.3. Proposici´on while-do
Una sentencia while -do tiene la forma S → while E do
S1, cuyo diagrama de flujo viene representado en la figura 7.8.
Para generar el c´odigo correspondiente a esta proposici´on habr´ıa
que a˜nadir a la funci´on genera c´odigo() un nuevo caso para
la sentencia switch que contemple este tipo de nodo en el ´arbol
sint´actico.
´CODIGO CALCULO E
SALTO CONDICIONAL F
V
SALTO INCONDICIONAL
Etiqueta 1
CODIGO S
Etiqueta 2 E
n_while
S
(a= (b)
Figura 7.8: (a)Diagrama de flujo para la proposici´on while do y (b) tipo de
nodo
Supondremos que tenemos una funci´on, sigtedirlibre(), que guar-
da el ´ındice de la siguiente instrucci´on libre (se asume que la
funci´on gen cuad() incrementa ese contador).
TAC datos; datos.cod=NULL;
TAC aux1, aux2;
lista codigo *cod1=NULL, *cod2=NULL;
direcciones dir1,dir2;
case n while: // childs[0]=E, childs[1]=S1
dir1=sgtedirlibre();
aux1=genera codigo(childs[0]);
cod1=gen cuad(if false,--, aux1.lugar, dir?);
aux2=genera codigo(childs[1]);
cod2=gen cuad(goto,--, dir1,--);// salto incondicional
a dir1
dir2=sigtedirlibre();
// rellena argumento de cod1, direccion salto condicional
23. 7.6. TRADUCCI ´ON DE PROPOSICIONES DE CONTROL 237
rellena(cod1,arg3,dir2)
datos.cod=concatena codigo(aux1.cod,cod1,aux2.cod,cod2);
break;
Se ha optado por utilizar direcciones directamente a las in-
strucciones en vez de etiquetas.
24. 238CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.7. Traducci´on de funciones
En esta secci´on se describe en t´erminos generales el mecanismo
de generaci´on de c´odigo de 3-direcciones para funciones. La gen-
eraci´on de c´odigo para las funciones es la parte m´as complicada
porque depende de la m´aquina objeto y de la organizaci´on del
entorno de ejecuci´on. La traducci´on de funciones implica dos eta-
pas:
la definici´on de la funci´on. Una definici´on de funci´on crea
un nombre, par´ametros y c´odigo del cuerpo de la funci´on pero
no se ejecuta la funci´on en ese punto.
la llamada a la funci´on desde una parte del programa
(trataremos a los procedimientos como funciones que no de-
vuelven valores). Una llamada crea los valores actuales para
los par´ametros y realiza un salto al c´odigo de entrada de la
funci´on que se ejecuta y retorna al punto de la llamada.
Supongamos que el sub´arbol sint´actico correspondiente a una fun-
ci´on tiene como ra´ız un nodo de tipo n call, llamada a funci´on,
con una serie de hijos que corresponden a los argumentos, que en
general, ser´an expresiones E1, . . . , En a evaluar para obtener el
valor actual de los n-argumentos.
A continuaci´on se incluye una implantaci´on para generar el c´odi-
go de 3-direcciones correspondiente a la llamada de la funci´on en
primer lugar. Posteriormente analizaremos el caso de la definici´on
de la funci´on. Supondremos que se han comprobado previamente
las condiciones sem´anticas de la llamada (n´umero y tipo de argu-
mentos).
Ejemplo de llamada a la funci´on
La llamada a una funci´on de dos argumentos genera el siguiente
c´odigo intermedio:
Se hace uso de una pila en donde se apilan los valores actuales de
los par´ametros de la funci´on para despu´es, como veremos en el
25. 7.7. TRADUCCI ´ON DE FUNCIONES 239
´Calculo de los param. de F
(paso de parametros)
Apilar argumentos
Llamada CALL/ Salto a F
Recoger valor de retorno
Desapilar valores parametros
Apilar valor de retorno
Punto de entrada a F
Salto retorno
.
.
: Cuerpo de F
Apilar direccion de retorno de F
Figura 7.9: Diagrama de flujo para la llamada a funci´on
ASIGN C t0 147 // asigna la direcci´on de retorno 147 a t0 (la siguiente al CALL)
PUSH t0 – // apila la direcci´on de retorno
PUSH t1 – // apila el valor de t1, primer arg. de la funci´on
PUSH t2 – // apila el valor de t2, segundo arg. de la funci´on
CALL X – // salta a la direcci´on X, entrada a la funci´on
POP t3 – // direccion 147, se desapila el valor devuelto por la funci´on, se almacena en t3
Cuadro 7.6: Ejemplo de c´odigo de llamada a una funci´on
siguiente apartado, en la implantaci´on del cuerpo de la funci´on,
desapilarlos.
Nota: Respecto a la direcci´on de la llamada a la funci´on (´ındice
de la instrucci´on del c´odigo de entrada a la funci´on), se podr´ıa
conocer en el caso de que el c´odigo para la funci´on ya se hubiera
generado antes de la llamada (por ejemplo, se podr´ıa haber al-
macenado en la entrada de la tabla de s´ımbolos correspondiente
a esa funci´on en un campo definido para ese prop´osito).
26. 240CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
En el caso de que a´un no se haya generado el c´odigo para la defini-
ci´on de la funci´on tendr´ıamos que hacer un relleno de retroceso en
todas las llamadas a esa funci´on. Una forma ser´ıa para cada fun-
ci´on almacenar los ´ındices de las instrucciones donde se hace una
llamada a dicha funci´on (por ejemplo, en un vector de ´ındices) y
una vez definida la funci´on que ya se conoce la direcci´on de entra-
da recorremos el vector de ´ındices y rellenamos con la direcci´on
adecuada en todas las proposiciones de llamadas a esa funci´on.
27. 7.7. TRADUCCI ´ON DE FUNCIONES 241
TAC datos;
datos.cod=NULL;
TAC aux[MAXNCHILDS];
cuadruplos cod1, cod2, codpush[MAXNCHILDS], codcall, codpop;
direcciones dir1,dir2; //direcciones a los saltos
char *t0, *t1; // varibales temporales
case n call:
// c´alculo de los par´ametros de la funci´on
for(i = 0; i<nchilds;i++)
aux[i] = genera c´odigo(childs[i]);
t0 = nuevotemp();
//asigna en t0 la direc. de retorno de la func., a´un no se sabe
cod1 = gen cuad(ASSIGN,t0,dir1?);
cod2 = gen cuad(PUSH,–,t0,–); // apilamos la direc. de retorno
// apilamos los argumentos
for(i = 0; i<nchilds;i++)
codpush[i] = gen cuad(PUSH,–, aux[i].lugar,–));
// llamada a la func., no se sabe a´un la direcc. de su cuerpo
codcall = gen cuad(CALL, –, dir2?,–);
// la siguiente direcci´on libre es la de retorno
dir1 = sigtedirlibre();
rellena(cod1,arg3,dir1);
t1 = nuevotemp();
// recogemos el valor devuelto por la funcion
codpop = gen cuad(POP,t1,–,–) ;
datos.cod=concatena(losaux[i].cod,cod1,cod2,loscodpush[i],codcall,codpop);
datos.lugar = t1;
//para relleno de retroceso de dir2, vease Nota
return (datos);
Figura 7.10: Implantaci´on de la llamada a funciones
28. 242CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
Cuerpo de la funci´on
Para traducir el cuerpo de la funci´on bastar´ıa recorrer el ´arbol
hasta encontrar un nodo de tipo n function a partir del cual
colgar´a el bloque de sentencias del cuerpo de la funci´on. No har´ıa
falta generar la parte del ´arbol de los argumentos ya que ´estos
estar´ıan almacenados en la tabla de s´ımbolos. A partir de cierta
direcci´on de c´odigo intermedio deber´ıamos tener un instrucci´on
que ser´ıa la entrada a la funci´on y que contendr´ıa:
POP t10 // recoge el segundo argumento
POP t11 // recoge el primer argumento
. . . // operaciones de la funci´on que almacena el resultado en t20 (por ejemplo)
POP t15 // recoge de la pila el valor de la direcc. de retorno (147) y lo pone en t15 (por ejem.)
RETURN t15 t20 // salida de la funci´on: el entorno de ejecuci´on deber primero saltar a la instrucc.
cuya direcci´on es el valor de t15 y apilar el valor devuelto que es el de t20
Esto implica las siguientes tareas (ver parte derecha de la figura
7.9) :
1. Recoger la direcci´on libre actual y utilizarla como direcci´on
para rellenar (relleno con retroceso) las llamadas a la funci´on
que estamos definiendo.
2. Generar c´odigo para desapilar los argumentos de la funci´on
y meterlos en las variables correspondientes.
3. Generar c´odigo para el bloque de sentencias S.
4. Desapilar la direccion de retorno.
5. Generar la salida de la funcion con RETURN.
6. Unir los trozos de c´odigo para tenerlos en una ´unica lista de
cu´adruplos.
29. 7.7. TRADUCCI ´ON DE FUNCIONES 243
TAC datos;
datos.cod=NULL;
TAC aux[MAXNCHILDS];
cuadruplos codpoparg[MAXNPARAM], codpopdirreturn, codreturn;
direcciones dir; //direccion de retorno
char *t; // varibale temporal
case n function:
dir = sigtedirlibre();
rellena(todas llamadas a la funcion con esta dir);
// desapilamos los argumentos
for(i = 0; i < nparams ;i++)
codpoparg[i] = gen cuad(POP, param[i].lugar, -, -));
//genera codigo para el cuerpo de la funci´on (k intrucciones)
//y calculamos el valor a devolver
for(k = 0; k < nchilds; k++)
aux[k] = genera c´odigo(childs[k]);
t = nuevotemp();
//desapilamos la direccion de retorno de la funci´on
codpopdirreturn = gen cuad(POP, t, -, -);
//salida de la funcion: el entorno de ejecuci´on salta a la
//direcc. de retorno en t y se apila el valor devuelto
codreturn = gen cuad(RETURN, t, valor devuelto, -);
datos.cod=concatena(loscodpoparg[i],losaux[k].cod,codpopdirreturn,codreturn);
datos.lugar = valor devuelto;
return (datos);
Figura 7.11: Implantaci´on del cuerpo de las funciones
VUESTRA pr´actica 3
En la definici´on de la funci´on vais a tener que colgar los
argumentos en el ´arbol para saber cuantos par´ametros teneis
que desapilar cuando implementeis el cuerpo de la funci´on,
pues no teneis la tabla de simbolos con esa informaci´on.
Para la llamada a las funciones tendre´ıs que crear a mano
un nodo n CALL, producci´on FunctionStm → id ( Arg ) . De
lo contrario, lo confundiria´ıs con el nodo n id.
30. 244CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
Para colgar los par´ametros en la definici´on de la funci´on ten-
dre´ıs que crear un nodo a mano n PARAM, producci´on de
Arg.
Vamos a hacer el siguiente ejemplo. Se ha considerado que primero
se genera el c´odigo del programa principal y a continuaci´on el
c´odigo de las funciones.
module Ejemplo ;
var resultado : integer ;
function Suma ( integer a, integer b) : integer ;
var total: integer;
begin
total = a + b ;
return(total) ;
end Suma ;
begin (* programa principal *)
resultado = Suma ( 2, 4*8) ;
write resultado ;
end Ejemplo .
Listado de cuadruplos
00 (ASSIGN C, t1, 2, NULL)
01 (MULT, t2, 4, 8)
02 (ASSIGN C, t3, 7, NULL)
03 (PUSH, t3, NULL, NULL)
04 (PUSH, t1, NULL, NULL)
05 (PUSH, t2, NULL, NULL)
06 (CALL, 11, NULL, NULL)
07 (POP, t4, NULL, NULL)
08 (ASSIGN V, resultado, t4, NULL)
09 (WRITE, resultado, NULL, NULL)
10 (HALT, NULL, NULL, NULL) // final del programa
11 (POP, b, NULL, NULL) // entrada a la funci´on
12 (POP, a, NULL, NULL)
13 (ADD, t5, a, b)
14 (ASSIGN V, total, t5, NULL)
31. 7.7. TRADUCCI ´ON DE FUNCIONES 245
15 (POP, t6, NULL, NULL) // desapilo la direcci´on de retorno, la 07
16 (RETURN, t6, total, NULL) // el entorno de ejecuci´on salta a la direccion
// en t6 (la 07) y apila el valor a devolver
32. 246CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.8. Optimizaci´on de c´odigo intermedio
La optimizaci´on de c´odigo intermedio se puede realizar:
a nivel local: s´olo utilizan la informaci´on de un bloque b´asico
para realizar la optimizaci´on.
a nivel global: que usan informaci´on de varios bloques b´asicos.
El t´ermino optimizaci´on de c´odigo es inadecuado ya que no se
garantiza el obtener, en el sentido matem´atico, el mejor c´odigo
posible atendiendo a maximizar o minimizar una funci´on objetivo
(tiempo de ejecuci´on y espacio). El t´ermino de mejora de c´odigo
ser´ıa m´as apropiado que el de optimizaci´on.
Nos concentraremos b´asicamente en la optimizaci´on de c´odigo de
tres-direcciones, puesto que son siempre transportables a cualquier
etapa final, son optimizaciones independientes de la m´aquina. Las
optimizaciones a nivel de la m´aquina, como la asignaci´on de reg-
istros y la utilizaci´on de instrucciones espec´ıficas de la m´aquina,
se salen del contexto de esta asignatura.
La mayor´ıa de los programas emplean el 90 % del tiempo de eje-
cuci´on en el 10 % de su c´odigo. Lo m´as adecuado es identificar las
partes del programa que se ejecutan m´as frecuentemente y tratar
de que se ejecuten lo m´as eficientemente posible. En la pr´acti-
ca, son los lazos internos los mejores candidatos para realizar las
transformaciones.
Adem´as de la optimizaci´on a nivel de c´odigo intermedio, se puede
reducir el tiempo de ejecuci´on de un programa actuando a otros
niveles: a nivel de c´odigo fuente y a nivel de c´odigo objeto.
Etapa
Inicial
Codigo
ObjetoGenerador
de Codigo
Intermedio
CodigoCodigo
fuente
el programador puede
modificar algoritmos
transformar lazos
el compilador puede
mejorar los lazos
el compilador puede
usar registros
seleccionar instrucciones
Figura 7.12: Niveles en los que el programador y el compilador pueden mejorar
el c´odigo
33. 7.8. OPTIMIZACI ´ON DE C ´ODIGO INTERMEDIO 247
Un bloque b´asico es una unidad fundamental de c´odigo. Es una
secuencia de proposiciones donde el flujo de control entra en el
principio del bloque y sale al final del bloque. Los bloques b´asicos
pueden recibir el control desde m´as de un punto en el programa
(se puede llegar desde varios sitios a una etiqueta) y el control
puede salir desde m´as de una proposici´on (se podr´ıa ir a una
etiqueta o seguir con la siguiente instrucci´on). Cuando aplicamos
optimizaci´on dentro de un bloque b´asico s´olo nos tenemos que
preocupar sobre los efectos de la optimizaci´on en los valores de
las variables a la entrada del bloque y los valores que tienen a
la salida del bloque, que han de ser los mismos que en el c´odigo
original sin transformar.
El algoritmo para particionar un programa en bloques se describe
a continuaci´on:
1. Encontrar todas las proposiciones que comienzan el principio de
un bloque b´asico:
La primera sentencia del programa.
Cualquier proposici´on del programa que es el objetivo de un
salto.
Cualquier proposici´on que sigue a una bifurcaci´on.
2. Para cualquier proposici´on que comienza un bloque b´asico, el bloque
consiste de esa proposici´on y de todas las siguientes hasta el
principio del siguiente bloque o el final del programa.
El flujo de control de un programa puede visualizarse como un
grafo dirigido de bloques b´asicos. A este grafo se le llama grafo
de flujo. Como ejemplo consideremos este trozo de c´odigo escrito
en pseudoC que suma los diez primeros n´umeros que se muestra
en la tabla 7.7 (a):
34. 248CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
void main() i = 10
{ s = 0
int i,s; label l1
i=10; t0 = i > 0
s=0; iffalse t0 goto l2
while i > 0 do s = s + i
{ i = i - 1
s=s+i; goto l1
i=i-1; label l2
} . . .
}
(a) (b)
Cuadro 7.7: Ejemplo (a) c´odigo fuente, (b) c´odigo de 3-direcciones
La figura 7.13 muestra el diagrama de flujo para el ejemplo
anterior. Aparecen 4 bloques b´asicos.
label l1
t0 = i > 0
iffalse t0 goto l2
i = i - 1
s = s + i
goto l1
. . .
s = 0
i = 10
label l2
Figura 7.13: Diagrama de flujo
35. 7.8. OPTIMIZACI ´ON DE C ´ODIGO INTERMEDIO 249
Algunas definiciones previas:
Dada una proposici´on de 3-direcciones de la forma a = b op
c decimos que la proposici´on referencia b y c y que define a.
Se dice que un nombre en un bloque b´asico vive al final del
bloque si su valor es referenciado en otro bloque b´asico en el
programa.
Se dice que un nombre est´a muerto si no es referenciado en
el resto del programa.
Se presentan algunas de las transformaciones m´as ´utiles para
mejorar el c´odigo. Son transformaciones locales, se pueden realizar
observando s´olo las proposiciones de un bloque b´asico.
7.8.1. Eliminaci´on de subexpresiones comunes
Si una expresi´on se calcula m´as de una vez, se puede remplazar
el c´alculo de la segunda por el valor de la primera expresi´on.
Consideremos el siguiente ejemplo del c´odigo 7.8 (a). Vemos que
la expresi´on t3∗t1 se calcula dos veces, por tanto podemos escribir
el c´odigo de la figura 7.8 (b):
t1 = 4 - 2 t1 = 4 - 2
t2 = t1 / 2 t2 = t1 / 2
t3 = a * t2 t3 = a * t2
t4 = t3 * t1 t4 = t3 * t1
t5 = t4 + b t5 = t4 + b
t6 = t3 * t1 t6 = t4
t7 = t6 + b t7 = t6 + b
c = t5 * t7 c = t5 * t5
(a) (b)
Cuadro 7.8: Eliminaci´on de subexpresiones comunes
Esto s´olo es posible si los operandos que est´an implicados en el
c´alculo de la expresi´on no han modificado su valor en las proposi-
ciones intermedias.
36. 250CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.8.2. Propagaci´on de copias
La propagaci´on de copias considera las proposiciones de la forma
a = b. Despu´es de esta sentencia sabemos que a y b tienen el
mismo valor, por tanto, podemos remplazar cada vez que aparezca
a por b, con la esperanza de que podamos remplazar todas las
ocurrencias de a hasta que se convierta en un nombre muerto y
se pueda entonces eliminar la proposici´on de copia.
A partir del c´odigo anterior podemos eliminar la proposici´on de
copia t6 = t4. Sustituimos t6 por t4. Vease figura 7.9 (a). Ahora se
puede ver que hay de nuevo una subexpresi´on com´un que puede
ser eliminada, obteniendo el c´odigo que se muestra en 7.9 (b). Y
finalmente realizando otra vez propagaci´on de copias, obtenemos
7.9 (c):
t1 = 4 - 2 t1 = 4 - 2 t1 = 4 - 2
t2 = t1 / 2 t2 = t1 / 2 t2 = t1 / 2
t3 = a * t2 t3 = a * t2 t3 = a * t2
t4 = t3 * t1 t4 = t3 * t1 t4 = t3 * t1
t5 = t4 + b t5 = t4 + b t5 = t4 + b
t6 = t4 t6 = t4 t6 = t4
t7 = t4 + b t7 = t5 t7 = t5
c = t5 * t7 c = t5 * t7 c = t5 * t5
(a) (b) (c)
Cuadro 7.9: Propagaci´on de copias y eliminaci´on de subexpresiones comunes
Vemos que el haber hecho una optimizaci´on puede dar lugar a
que sea posible aplicar nuevas optimizaciones.
37. 7.8. OPTIMIZACI ´ON DE C ´ODIGO INTERMEDIO 251
7.8.3. Eliminaci´on de c´odigo muerto
Podemos tener proposiciones que definen un nombre que nun-
ca m´as es referenciado, est´a muerto. Estas proposiciones pueden
entonces ser eliminadas. Dada la proposici´on a= b op c, se dice
que es c´odigo muerto o inactivo si a no es referenciada. En gener-
al, el c´odigo muerto aparece como consecuencia de la propagaci´on
de copias y es esto lo que hace que la t´ecnica de propagaci´on de
copias sea tan ´util. Veamos como aplicar esta t´ecnica al ejemplo
anterior en la figura 7.9 (c).
Vemos que t6 y t7 no tienen ninguna referencia a partir de su
definici´on, por tanto pueden ser eliminadas. Obtenemos el c´odigo
que aparece en la figura 7.10. Se ha supuesto que todas las vari-
ables no-temporales est´an vivas, se hace referencia a ellas en el
resto del programa.
t1 = 4 - 2
t2 = t1 / 2
t3 = a * t2
t4 = t3 * t1
t5 = t4 + b
c = t5 * t5
Cuadro 7.10: Eliminaci´on de c´odigo muerto
Aunque es poco probable que el programador introduzca c´odigo
muerto o inactivo, ´este puede aparecer como resultado de trans-
formaciones anteriores.
38. 252CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.8.4. Transformaciones aritm´eticas
Se pueden hacer uso de transformaciones algebraicas simples
para reducir la cantidad de computaci´on transformando opera-
ciones m´as costosas por otras menos costosas. Existen tres tipos
de transformaciones algebraicas b´asicas.
C´alculo previo de constantes
Se trata de calcular a nivel de compilaci´on el valor previo de
constantes en vez de hacerlo en tiempo de ejecuci´on que retar-
dar´ıa la ejecuci´on de un programa. A esta optimizaci´on se le lla-
ma c´alculo previo de constantes (en ingl´es constant folding). El
c´odigo de la figura 7.10 puede ser mejorado dando lugar al c´odigo
de la figura 7.11 (a). Haciendo una propagaci´on de copias y elim-
inaci´on de c´odigo muerto tenemos el c´odigo de la figura 7.11 (b).
Realizando de nuevo un c´alculo previo de constantes obtenemos
7.11 (c). Y finalmente podemos hacer de nuevo la propagaci´on de
copias y la eliminaci´on de c´odigo muerto, obteniendo el c´odigo de
la figura 7.11 (d).
t1 =2 t2 = 2 / 2 t2 = 1 t3 = a * 1
t2 = t1 / 2 t3 = a * t2 t3 = a * t2 t4 = t3 * 2
t3 = a * t2 t4 = t3 * 2 t4 = t3 * 2 t5 = t4 + b
t4 = t3 * t1 t5 = t4 + b t5 = t4 + b c = t5 * t5
t5 = t4 + b c = t5 * t5 c = t5 * t5
c = t5 * t5
(a) (b) (c) (d)
Cuadro 7.11: C´alculo previo de constantes
Hemos pasado de seis proposiciones a tener cuatro, eliminado
una substracci´on y una divisi´on en el proceso.
39. 7.8. OPTIMIZACI ´ON DE C ´ODIGO INTERMEDIO 253
Transformaciones algebraicas
Podemos hacer uso de identidades algebraicas para simplificar el
c´odigo. Las principales identidades son:
x+0 = 0+x = x; x−0 = x; x∗1 = 1∗x = x;
x
1
= x
Partiendo de la figura 7.11 (d) podemos obtener el c´odigo de
la figura 7.12 (a). De nuevo si usamos propagaci´on de copias y
eliminaci´on de c´odigo muerto obtenemos el c´odigo de la figura
7.12 (b) :
t3 = a t4 = a * 2
t4 = t3 * 2 t5 = t4 + b
t5 = t4 + b c = t5 * t5
c = t5 * t5
(a) (b)
Cuadro 7.12: Identidades algebraicas
Reducci´on de intensidad
En la mayor´ıa de las m´aquinas las operaciones de multiplicaci´on
y divisi´on son substancialmente m´as costosas que las operaciones
de suma y resta. Y a su vez, las potencias son m´as costosas que las
multiplicaciones y divisiones. Por tanto, siempre que sea posible
es conveniente sustituir un operador m´as costoso por otro menos
costoso. A esto se le conoce como reducci´on de la intensidad. Las
identidades m´as comunes son:
x2
= x ∗ x; 2 ∗ x = x + x
En nuestro ejemplo de la figura 7.12 (b) podemos obtener el
c´odigo 7.13
t4 = a + a
t5 = t4 + b
c = t5 * t5
Cuadro 7.13: Reducci´on de intensidad
Otra transformaci´on t´ıpica es usar desplazamientos de bits cuando
se divida o se multiplique por potencias de dos.
40. 254CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
7.8.5. Empaquetamiento de temporales
Se trata de reusar los temporales con el fin de ahorrar espacio.
Despu´es de haber optimizado el c´odigo es normal pensar que
se puedan usar menos temporales y ser´ıa conveniente entonces
renombrar estos temporales.
Supongamos que tenemos una tabla de temporales disponibles
(por ejemplo de t1 a t9), de manera que marcamos si un tempo-
ral est´a vivo en un cierto punto del bloque b´asico. En general,
es posible remplazar dos temporales por uno ´unico si no existe
ning´un punto donde los dos temporales est´an vivos a la vez. Para
cada temporal lo remplazamos por el primer temporal en la tabla
que est´a muerto en todos los lugares en el que el temporal bajo
consideraci´on est´a vivo.
Veamos nuestro ejemplo de la figura 7.13. t4 se define en la
primera proposici´on y est´a vivo en la segunda, entonces lo rem-
plazamos por el primer terminal muerto de la tabla, t1, obtenien-
do el c´odigo de la figura 7.14 (a). Por otro lado, t5 es definido
en la segunda proposici´on y vivo en la proposici´on 3. Esto no in-
teracciona con el temporal t1, que esta vivo s´olo en la segunda
proposici´on, por tanto t5 puede ser sustituido por t1. Obteniendo
el c´odigo de la figura 7.14 (b).
t1 = a + a t1 = a + a
t5 = t1 + b t1 = t1 + b
c = t5 * t5 c = t1 * t1
(a) (b)
Cuadro 7.14: Empaquetamiento de temporales
Comparando este c´odigo con el original que ten´ıa ocho proposi-
ciones, siete temporales, dos adiciones, una substracci´on, cuatro
multiplicaciones y una divisi´on, lo hemos reducido a tres proposi-
ciones que implican dos adiciones y una multiplicaci´on.
7.8.6. Mejora de los lazos
Traslado de c´odigo
41. 7.8. OPTIMIZACI ´ON DE C ´ODIGO INTERMEDIO 255
Una modificaci´on importante que disminuye la cantidad de
c´odigo en un lazo es el traslado de c´odigo. Esta transformaci´on
toma una expresi´on que produce el mismo resultado independi-
entemente del n´umero de veces que se ejecute un lazo y la coloca
antes del lazo. Por ejemplo:
while (i<=limite-2) ...
Se puede transformar en:
t=limite -2;
while (i<=t) ...
42. 256CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
Variables de inducci´on
Se trata de identificar las variables que permanecen ligadas
entre s´ı en la ejecuci´on, est´an relacionadas entre s´ı de forma que
conocido el valor de una se puede obtener el de la otra. Supong-
amos el siguiente fragmento de c´odigo donde se ha supuesto que
los elementos de la matriz ocupan 4 bytes y ya se ha realizado
cierta optimaci´on.
suma=0; suma=0;
j=0; j=0;
while j<10 label l1
{ t1= j<10
suma = suma + a[j]; iffalse t1 goto l2
j=j+1; t2=4*j
} t3=a[t2]
. . . suma=suma+t3
j=j+1
goto l1
label l2
. . .
Cuadro 7.15: (a) c´odigo fuente y (b) c´odigo de 3-direcciones
donde a[t2] en la tabla 7.15 (b) significa la direcci´on de a m´as un
desplazamiento t2. Sabemos que t2 no cambia en ning´un momento
salvo en t2 = 4 ∗ j, por tanto justo despu´es de la proposici´on
j = j + 1 se cumple que t2 = 4 ∗ j + 4, y se puede sustituir la
asignaci´on t2 = 4 ∗ j por t2 = t2 + 4, debiendo inicializar el valor
de t2 = 0.
Siempre que haya variables de inducci´on se pueden hacer sustitu-
ciones de este tipo y eliminar todas menos una.
43. 7.9. EJERCICIOS 257
7.9. Ejercicios
1. (0.25 ptos) Escribe el pseudoc´odigo correspondiente, usando
la notaci´on que hemos visto a lo largo del cap´ıtulo, para la
implementaci´on de la generaci´on de c´odigo de tres direcciones
medinate cuadr´uplos para la construccion if-then-else.
2. (0.25 ptos) Escribe el pseudoc´odigo correspondiente, usando
la notaci´on que hemos visto a lo largo del cap´ıtulo, para la
implementaci´on de la generaci´on de c´odigo de tres direcciones
medinate cuadr´uplos para la construcci´on repeat until.
3. (0.25 ptos) Escribe el pseudoc´odigo correspondiente, usando
la notaci´on que hemos visto a lo largo del cap´ıtulo, para la
implementaci´on de la generaci´on de c´odigo de tres direcciones
medinate cuadr´uplos para la construcci´on switch.
4. (0.3 ptos) Supongamos una nueva construcci´on de los lengua-
jes de programaci´on que llamaremos do-while-do (hacer-
mientras-hacer). Esta construcci´on nace de forma natural,
como las construcciones while-do, do-while que ya conoc´eis.
Esta construcci´on surge para implementar la idea en que hay
casos en los que no se desea salir de la iteraci´on al principio,
ni al final de la iteraci´on, sino a la mitad, despu´es de que se
ha hecho cierto procesamiento.
Por ejemplo para implementar el c´odigo:
dowhiledo
read(X);
while (no final fichero)
process(X);
end dowhiledo
La sintaxis de esta construcci´on es:
S → dowhiledo S ∗ while E S ∗ end dowhiledo |
donde se ha usado el operador * para indicar cero o m´as
repeticiones. Se pide:
44. 258CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
Dibujar el diagrama de flujo de esta construcci´on.
Dibujar la forma del ´arbol abstracto de an´alisis sint´acti-
co que usar´ıas para su traducci´on a c´odigo de 3-direcciones.
Escribir el pseudoc´odigo de la funci´on generar c´odigo para
traducir este tipo de sentencias a una lista de cu´adruplos.
Desafortunadamente ning´un lenguaje com´un de progra-
maci´on implementa esta construcci´on. ¿A qu´e crees que
se debe esto?. ¿Qu´e construcci´on(es) usa el lenguaje C
para implementar esta idea?
45. 7.10. EJEMPLO DE GENERACI ´ON DE C ´ODIGO PARA UNA CALCULADORA USANDO PCCTS
7.10. Ejemplo de generaci´on de c´odigo para
una calculadora usando PCCTS
Supongamos una peque˜na calculadora que realizar operaciones
aritm´eticas sencillas seg´un la gram´atica:
entrada → (ecuacion)+
ecuacion → id = expresion ;
expresion → termino ( “+” termino | “-” termino )*
termino → factor ( “*” factor | “/” factor)*
factor → “(“ expresion “)” | dato
dato → num | id | - num | - id
Se pide implementar un traductor que traduzca las expre-
siones aritm´eticas a c´odigo de 3-direcciones, implementado medi-
ante cu´aduplos de la forma (operador, resultado, arg1,
arg2). Los tipos de operadores son:
(ASSIGN, result, arg1,NULL) asigna arg1 a result
(ADD, result, arg1,arg2) suma arg1, arg2 y lo alamacena en result
(SUB, result, arg1,arg2) resta arg1, arg2 y lo alamacena en result
(MULT, result, arg1,arg2) multiplica arg1, arg2 y lo alamacena en result
(DIV, result, arg1,arg2) divide arg1, argg2 y lo alamacena en result
(NEG, result, arg1,NULL) mult. por (-1) arg1, y lo alamacena en result
(HALT,NULL, NULL, NULL) final de programa
46. 260CAP´ITULO 7. GENERACI ´ON DE C ´ODIGO INTERMEDIO. OPTIMIZACI ´ON
Se ha implementado la clase cuadruplo (Cuad.h). Se ha implemen-
tado la clase TAC (Three-Address-Code), a partir de una lista de
cuaduplos y se ha introducido el lugar como un dato protegi-
do adicional. Se ha implementado el m´etodo generar c´odigo en la
clase AST. Fichero con la especificacion de la gram´atica p3.g.
Para la entrada: a=3+2;
b=a*2;
c=a+b+2*6;
d=-1+a;
Obtenemos la salida:
( ENTRADA ( = a ( + 3 2 ) ) ( = b ( * a 2 ) ) ( = c ( + ( +
a b ) ( * 2 6 ) ) ) ( = d ( + ( UMINUS 1 ) a ) ) )
Numero de lineas analizadas 6
(ADD,t0,3,2)
(ASSIGN,a,t0,NULL)
(MULT,t1,a,2)
(ASSIGN,b,t1,NULL)
(ADD,t2,a,b)
(MULT,t3,2,6)
(ADD,t4,t2,t3)
(ASSIGN,c,t4,NULL)
(NEG,t5,1,NULL)
(ADD,t6,t5,a)
(ASSIGN,d,t6,NULL)
(HALT,NULL,NULL,NULL)
Numero de cuadruplos 12