Sunteți pe pagina 1din 72

PROGRAMACIN DE SISTEMAS I UNIDAD I INTRODUCCION A LA PROGRAMACION DE SISTEMAS 1.1 QU ES Y QUE ESTUDIA LA PROGRAMACIN DE SISTEMAS?

PROGRAMACIN DE SISTEMAS: Conjunto de reglas para crear soluciones a problemas computables. Conjunto de herramientas que nos permiten crear software de base que son de utilidad para interactuar con la mquina. SOFTWARE DE BASE: Compilador, Querys, Sistema Operativo, Cargador. AUTMATA: Son las cadenas posibles que aceptan un lenguaje. EXPRESIONES REGULARES: Conjunto de smbolos que aceptan una palabra reservada. GRAMTICA: Reglas para escribir las sentencias del lenguaje. 1.2 HERRAMIENTAS DESARROLLADAS CON LA TEORA DE LA PROGRAMACIN DE SISTEMAS? Desarrolla software de base como: Traductores Cargadores Ligadores Herramientas Utileras DBMS Generadores de cdigo 1.3 LENGUAJES LENGUAJE DE PROGRAMACIN: Es la notacin formal para la descripcin de algoritmos, basada en un conjunto de instrucciones en alto nivel, que finalmente pasarn a bajo nivel para interactuar con el hardware y generar herramientas de trabajo. Los lenguajes son sistemas de comunicacin. Un lenguaje de programacin consiste en todos los smbolos, caracteres y reglas de uso que permiten a las personas "comunicarse" con las computadoras. Existen por lo menos varios cientos de lenguajes y dialectos de programacin diferentes. Algunos se crean para una aplicacin especial, mientras que otros son herramientas de uso general ms flexibles que son apropiadas para muchos tipos de aplicaciones. En todo caso los lenguajes de programacin deben tener instrucciones que pertenecen a las categoras ya familiares de entrada/salida, clculo/manipulacin de textos, lgica/comparacin y almacenamiento/recuperacin.

PROGRAMACIN DE SISTEMAS

EJEMPLO DE SMBOLOS QUE COMPONEN UN PROGRAMA:


SIMBOLOS ESPECUALES FUNCIONES SIMBOLOS QUE RECHAZA EL LENGUAJE IDENTIFICADORES

ARITMETICOS LENGUAJE PASCAL LOGICOS

+, -,*,/,MOD AND NOT OR < > > < = = :=

DELIMITADORES OPERACIONALES RELACIONALES

ASIGNACION

PALABRAS RESERVADAS

CICLOS DECLARACION DE VARIABLES DECLARACION DE CONSTANTES

No obstante, aunque todos los lenguajes de programacin tienen un conjunto de instrucciones que permiten realizar dichas operaciones, existe una marcada diferencia en los smbolos, caracteres y sintaxis de los lenguajes de mquina, lenguajes ensambladores y lenguajes de alto nivel. 1.3.1 LENGUAJES NATURALES Este tipo de lenguaje es el que nos permite el designar las cosas actuales y razonar a cerca de ellas, fue desarrollado y organizado a partir de la experiencia humana y puede ser utilizado para analizar situaciones altamente complejas y razonar muy sutilmente. La riqueza de sus componentes semnticos da a los lenguajes naturales su gran poder expresivo y su valor como una herramienta para razonamiento sutil. Por otro lado la sintaxis de un LN puede ser modelada fcilmente por un lenguaje formal, similar a los utilizados en las matemticas y la lgica. Otra propiedad de los lenguajes naturales es la polisemntica, es decir la posibilidad de que una palabra en una oracin tenga diversos significados. En un primer resumen, los lenguajes naturales se caracterizan por las siguientes propiedades: Desarrollados por enriquecimiento progresivo antes de cualquier intento de formacin de una teora. La importancia de su carcter expresivo debido grandemente a la riqueza del componente semntico(polisemantica). Dificultad o imposibilidad de una formalizacin completa.

PROGRAMACIN DE SISTEMAS

1.3.2 LENGUAJES ARTIFICIALES LENGUAJES DE INTELIGENCIA ARTIFICIAL Podemos distinguir tres grandes estilos o subfamilias de los lenguajes de inteligencia artificial. Los tres estilos de programacin son los siguientes: programacin funcional, programacin relacional y programacin por objetos. El lenguaje ms representativo del estilo funcional es el LISP, LOGO por su identificacin con LSIP, cae de lleno dentro de este estilo. El lenguaje ms representativo del estilo relacional PROLOG. El lenguaje ms representativo del estilo de programacin por objetos es el SMALLTALK, pero existen varios dialectos de LISP que permite programar en esta forma. 1.3.3 PROCESO DE COMUNICACIN

1.4 TRADUCTOR Y SU ESTRUCTURA

PROGRAMACIN DE SISTEMAS Un traductor se define como un programa que traduce o convierte desde un texto o programa escrito en un lenguaje fuente hasta un texto o programa equivalente escrito en un lenguaje destino produciendo, si cabe, mensajes de error. Los traductores engloban tanto a los compiladores (en los que el lenguaje destino suele ser cdigo mquina) como a los intrpretes (en los que el lenguaje destino est constituido por las acciones atmicas que puede ejecutar el intrprete). Programa de Entrada escrito en Lenguaje Fuente TRADUCTOR Programa de Salida escrito en Lenguaje Destino

Mensaje de Error ESQUEMA PRELIMINAR DE TRADUCTOR

Es

importante destacar la velocidad con la que hoy en da se puede construir un compilador. En la dcada de 1950, se consider a los traductores como programas notablemente difciles de escribir. El primer compilador de Fortran (Formula Translator), por ejemplo, necesit para su implementacin el equivalente a 18 aos de trabajo individual (realmente no se tard tanto puesto que el trabajo se desarroll en equipo). Hasta que la teora de autmatas y lenguajes formales no se aplic a la creacin de traductores, su desarrollo ha estado plagado de problemas y errores. Sin embargo, hoy da un compilador bsico puede ser el proyecto fin de carrera de cualquier estudiante universitario de Informtica. Estructura: Un traductor divide su labor en dos etapas: una que analiza la entrada y genera estructuras intermedias y otra que sintetiza la salida a partir de dichas estructuras. Por tanto, el esquema de un traductor pasa de ser el de la anterior, a ser el de la siguiente figura:

PROGRAMACIN DE SISTEMAS Fuente Destino

ANALISIS

SINTESIS

Error en el Programa Fuente

Error al Generar Cdigo

ESQUEMA POR ETAPAS DE UN TRADUCTOR

Bsicamente los objetivos de la etapa de anlisis son: a) controlar la correccin del programa fuente, y b) generar las estructuras necesarias para comenzar la etapa de sntesis. Para llevar esto a cabo, la etapa de anlisis consta de las siguientes fases: Anlisis lexicogrfico. Divide el programa fuente en los componentes bsicos del lenguaje a compilar. Cada componente bsico es una subsecuencia de caracteres del programa fuente, y pertenece a una categora gramatical: nmeros, identificadores de usuario (variables, constantes, tipos, nombres de procedimientos, palabras reservadas, signos de puntuacin, etc). Anlisis sintctico. Comprueba que la estructura de los componentes bsicos sea correcta segn las reglas gramaticales del lenguaje que se compila. Anlisis semntico. Comprueba que el programa fuente respeta las directrices del lenguaje que se compila (todo lo relacionado con el significado): chequeo de tipos, rangos de valores, existencia de variables, etc. Cualquiera de estas tres fases puede emitir mensajes de error derivados de fallos cometidos por el programador en la redaccin de los textos fuente. Mientras ms errores controle un compilador, menos problemas dar un programa en tiempo de ejecucin. Por ejemplo, el lenguaje C no controla los lmites de un array, lo que provoca que en tiempo de ejecucin puedan producirse comportamientos del programa de difcil explicacin. La etapa de sntesis construye el programa objeto deseado (equivalente semnticamente al fuente) a partir de las estructuras generadas por la etapa de anlisis. Para ello se compone de tres fases fundamentales: Generacin de cdigo intermedio. Genera un cdigo independiente de la mquina muy parecido al ensamblador. No se genera cdigo mquina directamente porque as es ms fcil hacer pseudocompiladores y adems se facilita la optimizacin de cdigo independientemente del microprocesador.

PROGRAMACIN DE SISTEMAS Generacin del cdigo mquina. Crea un bloque de cdigo mquina ejecutable, as como los bloques necesarios destinados a contener los datos. Fase de optimizacin. La optimizacin puede realizarse sobre el cdigo intermedio (de forma independiente de las caractersticas concretas del microprocesador), sobre el cdigo mquina, o sobre ambos. Y puede ser una aislada de las dos anteriores, o estar integrada con ellas. 1.4.1 ENSAMBLADORES Que es ensamblador y para que sirve? Cuando se empezaron a utilizar smbolos nemotcnicos, se escribieron programas para traducir automticamente los programas escritos en lenguaje ensamblador a lenguaje mquina. A estos programas traductores se les llamo ensambladores. La entrada para un ensamblador es un programa fuente escrito en lenguaje ensamblador. La salida es un programa objeto, escrito en lenguaje de mquina. El programa objeto incluye tambin la informacin necesaria para que el cargador pueda preparar el programa objeto para su ejecucin. Para evitar confusiones, de aqu en adelante llamaremos lenguaje ensamblador al conjunto de nemotcnicos y a las reglas para su manejo. Al programa que traduce un programa objeto a partir de un programa escrito en lenguaje ensamblador lo llamaremos ensamblador. Motivos para utilizarlo: Rapidez Mayor control de la computadora Independencia del lenguaje La mayora de las computadoras pueden ensamblarlo Motivo para no utilizarlo: Dependencia de hardware Mayor tiempo de codificacin Comprensin ms profunda de la computadora Errores ms frecuentes en el programa Tipos de Ensambladores Aunque todos los ensambladores realizan bsicamente las mismas tareas, podemos clasificarlos de acuerdo a caractersticas.

Ensambladores Cruzados (Cross-Assembler). Se denominan as los ensambladores que se utilizan en una computadora que posee un procesador diferente al que tendrn las computadoras donde va a ejecutarse el programa objeto producido. El empleo de este tipo de traductores permite aprovechar el soporte de medios fsicos (discos, impresoras, pantallas, etc.), y de programacin que ofrecen las

PROGRAMACIN DE SISTEMAS mquinas potentes para desarrollar programas que luego los van a ejecutar sistemas muy especializados en determinados tipos de tareas.

Ensambladores Residentes. Son aquellos que permanecen en la memoria principal de la computadora y cargan, para su ejecucin, al programa objeto producido. Este tipo de ensamblador tiene la ventaja de que se puede comprobar inmediatamente el programa sin necesidad de transportarlo de un lugar a otro, como se haca en cross-assembler, y sin necesidad de programas simuladores. Sin embargo, puede presentar problemas de espacio de memoria, ya que el traductor ocupa espacio que no puede ser utilizado por el programador. Macroensambladores .
Son ensambladores que permiten el uso de macroinstrucciones (macros). Debido a su potencia, normalmente son programas robustos que no permanecen en memoria una vez generado el programa objeto. Puede variar la complejidad de los mismos, dependiendo de las posibilidades de definicin y manipulacin de las macroinstrucciones, pero normalmente son programas bastantes complejos, por lo que suelen ser ensambladores residentes.

Microensambladores.
Generalmente, los procesadores utilizados en las computadoras tienen un repertorio fijo de instrucciones, es decir, que el intrprete de las mismas interpretaba de igual forma un determinado cdigo de operacin. El programa que indica al intrprete de instrucciones de la UCP cmo debe actuar se denomina microprograma. El programa que ayuda a realizar este microprograma se llama microensamblador. Existen procesadores que permiten la modificacin de sus microprogramas, para lo cual se utilizan microensambladores.

Ensambladores de una fase.


Estos ensambladores leen una lnea del programa fuente y la traducen directamente para producir una instruccin en lenguaje mquina o la ejecuta si se trata de una pseudoinstruccin. Tambin va construyendo la tabla de smbolos a medida que van apareciendo las definiciones de variables, etiquetas, etc. Debido a su forma de traduccin, estos ensambladores obligan a definir los smbolos antes de ser empleados para que, cuando aparezca una referencia a un determinado smbolo en una instruccin, se conozca la direccin de dicho smbolo y se pueda traducir de forma correcta. Estos ensambladores son sencillos, baratos y ocupan poco espacio, pero tiene el inconveniente indicado.

Ensambladores de dos fases.


Los ensambladores de dos fases se denominan as debido a que realizan la traduccin en dos etapas. En la primera fase, leen el programa fuente y construyen una tabla de smbolos; de esta manera, en la segunda fase, vuelven a

PROGRAMACIN DE SISTEMAS leer el programa fuente y pueden ir traduciendo totalmente, puesto que conocen la totalidad de los smbolos utilizados y las posiciones que se les ha asignado. 1.4.2 COMPILADORES Hoy en da, un compilador es un traductor que facilita la comunicacin entre el programador y la mquina, por medio de un proceso de transformacin. Un compilador es un programa que lee las lneas escritas en un lenguaje de programacin (como Pascal) y las traduce a otro que pueda ejecutar la computadora. Los programas compilados se ejecutan ms rpido que los interpretados, debido a que han sido completamente traducidos a lenguaje de mquina y no necesitan compartir memoria con el intrprete. A grandes rasgos un compilador es un programa que lee un programa escrito es un lenguaje, el lenguaje fuente, y lo traduce a un programa equivalente en otro lenguaje, el lenguaje objeto. Como parte importante de este proceso de traduccin, el compilador informa a su usuario de la presencia de errores en el programa fuente. El programa compilador traduce las instrucciones en un lenguaje de alto nivel a instrucciones que la computadora puede interpretar y ejecutar. Para cada lenguaje de programacin se requiere un compilador separado. El compilador traduce todo el programa antes de ejecutarlo. Los compiladores son, pues, programas de traduccin insertados en la memoria por el sistema operativo para convertir programas de cmputo en pulsaciones electrnicas ejecutables (lenguaje de mquina).

Estructura de un Compilador:
La estructura de un compilador, esta dividida en cuatro grandes mdulos, cada uno independiente del otro, se podra decir que un compilador esta formado por cuatros mdulos mas a su vez. El primero de ellos es el preprocesador , es el encargado de transformar el cdigo fuente de entrada original en el cdigo fuente puro. El segundo modulo es el de compilacin que recibe el cdigo fuente puro, este es l modulo principal de un compilador, pues si ocurriera algn error en esta etapa el compilador no podra avanzar. En esta etapa se somete al cdigo fuente puro de entrada a un anlisis lxico grfico, a un anlisis sintctico, a un anlisis semntico, que construyen la tabla de smbolos, se genera un cdigo intermedio al cual se optimiza para as poder producir un cdigo de salida generalmente en algn lenguaje ensamblador. El tercer modulo es el llamado modulo de ensamblado , este modulo no es ni ms mi menos que otro compilador pues recibe un cdigo fuente de entrada

PROGRAMACIN DE SISTEMAS escrito en ensamblador, y produce otro cdigo de salida, llamado cdigo binario no enlazado. El cuarto y ultimo modulo es el encargado de realizar el enlazado del cdigo de fuente de entrada (cdigo maquina relocalizable) con las libreras que necesita, como as tambin de proveer al cdigo de las rutinas necesarias para poder ejecutarse y cargarse a la hora de llamarlo para su ejecucin, modifica las direcciones relocalizables y ubica los datos en las posiciones apropiadas de la memoria.

Tipos de Compiladores: Una sola pasada: Examina el cdigo fuente una vez, generando el cdigo o programa objeto. Pasadas mltiples: Requieren pasos intermedios para producir un cdigo en otro lenguaje, y una pasada final para producir y optimizar el cdigo producido durante los pasos anteriores. Optimacin: Lee un cdigo fuente, lo analiza y descubre errores potenciales sin ejecutar el programa. Compiladores incrementales: generan un cdigo objeto instruccin por instruccin (en vez de hacerlo para todo el programa) cuando el usuario teclea cada orden individual. El otro tipo de compiladores requiere que todos los enunciados o instrucciones se compilen conjuntamente. Ensamblador: El lenguaje fuente es lenguaje ensamblador y posee una estructura sencilla. Compilador cruzado: se genera cdigo en lenguaje objeto para una mquina diferente de la que se est utilizando para compilar. Es perfectamente normal construir un compilador de Pascal que genere cdigo para MS-DOS y que el compilador funcione en Linux y se haya escrito en C++. Compilador con montador: compilador que compila distintos mdulos de forma independiente y despus es capaz de enlazarlos. Autocompilador: Compilador que est escrito en el mismo lenguaje que va a compilar. Evidentemente, no se puede ejecutar la primera vez. Sirve para hacer ampliaciones al lenguaje, mejorar el cdigo generado, etc. Metacompilador: Es sinnimo de compilador de compiladores y se refiere a un programa que recibe como entrada las especificaciones del lenguaje para el que se desea obtener un compilador y genera como salida el compilador para ese lenguaje. El desarrollo de los metacompiladores se encuentra con la dificultad de unir la generacin de cdigo con la parte de anlisis. Lo que s se han desarrollado son generadores de analizadores lxicos y sintcticos. desarrollados para UNIX. Los inconvenientes que tienen son que los analizadores que generan no son muy eficientes. Descompilador: Es un programa que acepta como entrada cdigo mquina y lo traduce a un lenguaje de alto nivel, realizando el proceso inverso a la compilacin.
1.4.3 INTERPRETES Es como un compilador, solo que la salida es una ejecucin. El programa de entrada se reconoce y ejecuta a la vez. No se produce un resultado fsico (cdigo

PROGRAMACIN DE SISTEMAS mquina) sino lgico (una ejecucin). Hay lenguajes que slo pueden ser interpretados, como p.ej. SNOBOL (StriNg Oriented SimBOlyc Language), LISP (LISt Processing), algunas versiones de BASIC (Beginners All-purpose Symbolic Instruction Code), etc. Su principal ventaja es que permiten una fcil depuracin. Entre los inconvenientes podemos citar, en primer lugar, la lentitud de ejecucin , ya que al ejecutar a la vez que se traduce no puede aplicarse un alto grado de optimizacin; por ejemplo, si el programa entra en un bucle y la optimizacin no est muy afinada, las mismas instrucciones se interpretarn y ejecutarn una y otra vez, dilatando la ejecucin del programa. Otro inconveniente es que durante la ejecucin, el intrprete debe residir en memoria, por lo que consumen ms recursos. Adems de que la traduccin optimiza el programa acercndolo a la mquina, los lenguajes interpretados tienen la caracterstica de que permiten construir programas que se pueden modificar a s mismos.

Fuente

Pseudoejecutable TRADUCTOR MOTOR DE EJECUCION

Ejecucin

Esquema de traduccin/ejecucin de un programa interpretado

1.5 GENERADORES DE CDIGO PARA COMPILADORES (COMPILADOR DE COMPILADORES, HERRAMIENTAS)

Estructura del proceso de Compilacin: Analizando en detalle el proceso de compilacin, se divide en dos grandes fases, una de Anlisis y la otra de Sntesis. Fase de Anlisis: En el llamado anlisis lexicogrfico o lxico, el compilador revisa y controla que las "palabras" estn bien escritas y pertenezcan a algn tipo de token (cadena) definido dentro del lenguaje, como por ejemplo que sea algn tipo de palabra reservada, o si es el nombre de una variable que este escrita de acuerdo a las pautas de definicin del lenguaje. En esta etapa se crea la tabla de

PROGRAMACIN DE SISTEMAS smbolos, la cual contiene las variables y el tipo de dato al que pertenece, las constantes literales, el nombre de funciones y los argumentos que reciben etc. En el anlisis sintctico como su nombre lo indica se encarga de revisar que los tokens estn ubicados y agrupados de acuerdo a la definicin del lenguaje. Dicho de otra manera, que los tokens pertenezcan a frases gramaticales validas, que el compilador utiliza para sintetizar la salida. Por lo general las frases gramaticales son representadas por estructuras jerrquicas, por medio de rboles de anlisis sintctico. En esta etapa se completa la tabla de smbolos con la dimensin de los identificadores y los atributos necesarios etc. El anlisis semntico se encarga de revisar que cada agrupacin o conjunto de token tenga sentido, y no sea un absurdo. En esta etapa se rene la informacin sobre los tipos para la fase posterior, en esta etapa se utiliza la estructura jerrquica de la etapa anterior y as poder determinar los operadores, y operandos de expresiones y preposiciones. Estructura del proceso de Compilacin: Fase de Sntesis: Etapa de generacin de cdigo intermedio, aunque algunos compiladores no la tienen, es bueno saber de su existencia, en esta etapa se lleva el cdigo del programa fuente a un cdigo interno para poder trabajar mas fcilmente sobre l. Esta representacin interna debe tener dos propiedades, primero debe ser fcil de representar y segundo debe ser fcil de traducir al cdigo objeto. En la etapa de optimizacin de cdigo , se busca obtener el cdigo mas corto y rpido posible, utilizando distintos algoritmos de optimizacin.

Etapa de generacin de cdigo, se lleva el cdigo intermedio final a cdigo maquina o cdigo objeto, que por lo general consiste en un cdigo maquina relocalizable o cdigo ensamblador. Se selecciona las posiciones de memoria para los datos (variables) y se traduce cada una de las instrucciones intermedias a una secuencia de instrucciones de maquina puro. La tabla de smbolos no es una etapa del proceso de compilacin, sino que una tarea, una funcin que debe realizar el proceso de compilacin. En ella se almacenan los identificadores que aparecen en el cdigo fuente puro, como as tambin los atributos de los mismos, su tipo, su mbito y en el caso de los procedimientos el nmero de argumentos el tipo de los mismos etc. En otras palabras una tabla de smbolos es una estructura de datos, que contiene un registro por cada identificador, y sus atributos. La tabla de smbolo es accedida tanto para escritura como parar lectura por todas las etapas. Detector de errores o manejador de errores, al igual que la tabla de smbolos no es una etapa del proceso de compilacin, si no que es una funcin, muy importante, pues al

PROGRAMACIN DE SISTEMAS ocurrir un error esta funcin debe tratar de alguna forma el error para as seguir con el proceso de compilacin (la mayora de errores son detectados en las etapas de anlisis lxico, anlisis sintctico, anlisis semntico). UNIDAD II INTRODUCCIN AL DISEO DE LOS LEGUAJES DE PROGRAMACIN 2.1 Visin del Problema En los ltimos aos, una de las artes ms predominantes en el mundo de la programacin ha sido el diseo de lenguaje de programacin. El numero de lenguajes de programacin propuestos y diseados son extremadamente grandes. Aun el numero de de lenguajes para el que un compilador ha aplicado es inmenso. Sammet (1976) indica 167 en su lista 19741975. Aun que los primeros lenguajes de programacin primitivos nacieran cerca 25 aos atrs, hasta que reciente mente hubiesen un pequeo proceso en el diseo de nuevos lenguajes de programacin. Los primeros lenguajes fueron los pioneros, explorando un nuevo campo. No es de sorprenderse que carecieran de un buen diseo. No se debera criticar a los diseadores o FORTRAN; puesto que suficientes problemas tenan con disear y aplicar uno de los primeros lenguajes de alto nivel Si hay cualquier crtica de ser concedida con respecto a FORTRAN, Nadie razonablemente los podra esperar que a la crtica sean concedidos con respecto a 25 aos ms tarde, sus objetivos deben ser los usuarios que se han adherido tan tenazmente a ciertos diseadores cados en desuso del lenguaje que tienen tan perpetuaron con entusiasmo los desperfectos de FORTRAN. Se debe notar que nuestras referencias a FORTRAN en el prrafo anterior y a travs de este captulo se refieren a FORTRAN IV antes que FORTRAN 77. Despus que el desarrollo inicial del lenguaje de alto nivel y la implementacin de los primeros pocos compiladores, all result un perodo bastante largo en el que las tentativas conscientes se hicieron para disear nuevos lenguajes sin los desperfectos de los viejos. La mayor parte de estas tentativas eran los fracasos, no tanto de una falta de ideas en cmo disear mejores lenguajes como de un supervit de ideas. Una buena ampliacin de este proceso es la nocin que si podra significar algo, debera (Radin y Rogoway, 1965), que llev a PL/YO. Ms recientemente, la experiencia de errores pasados haba llevado al conocimiento verdadero acerca de cmo construir mejores lenguajes de programacin. Las ideas y los principios bsicos se establecen suficientemente bien para indicar las pautas explcitas para el diseo del lenguaje. Esas reas que aun no han sido comprendidas se encuentran bajo investigacin.

PROGRAMACIN DE SISTEMAS Esta discusin procurar por consiguiente acentuar un sistema. El enfoque ordenado al diseo del lenguaje, se debe recordar, sin embargo, hacer la justificacin apropiada a muchos temas que a menudo son necesarios para discutir detalles as como generalidades. El campo del diseo del lenguaje no es de ninguna manera completamente desarrollada, y muchas reas no han sido bien unificadas. Tambin, muchas reas interrelacionan y son difcil de discutirlos separadamente. Por la necesidad, esta discusin sin embargo, restringe su alcance. Las descripciones elaboradas de las caractersticas posibles del lenguaje se limitarn se asume que el diseador potencial del lenguaje tiene las bases suficientes en lenguajes de programacin para estar enterado de las ideas prinsipales. Las caractersticas especficas se discutirn para especificar razones , pero ninguna tentativa se har para dar un catlogo general. Hay ya varios catlogos , como: (Elson, 1973; Pratt, 1975; Nlcholls, 1975). Una proposicin bsica de este captulo entero es que un buen lenguaje no es apenas una coleccin casual de caractersticas de un total unificado. Se asumir que los lenguajes, bajo la discusin son de alto nivel los idiomas. La discusin ser restringida tambin en gran parte a idiomas procesales para escribir software (software se utiliza aqu en sus la mayora de los sentidos generales para significar los programas para ser utilizados por otra persona). Mucho de lo que se dice ser aplicable a otras clases de lenguajes. El disear completamente un lenguaje. Si es que es el enfoque se toma, como sea, se debe tomar con cuidado para no hacer una extensin tan grande y compleja como se llega a ser, el hecho, de un nuevo lenguaje. En tales casos, la necesidad de retener algunas interfaces con un viejo lenguaje probablemente ceder gravemente el diseo de la extensin. Tambin, si uno extiende un lenguaje existente, es necesario escoger cuidadosamente un lenguaje base para que el trabajo de la extensin se aminorare y la extensin elegantemente quede dentro del lenguaje. El objetivo debe ser el de producir un lenguaje el cual se ms grande aun que igualmente bien construido. Sera posible el modificar un lenguaje existente, utilizando posiblemente un macroprocessor o algo similar? Aun que con facilidad un macro contrario de menor parmetro (sustituyendo simplemente un texto especificado para cada ocurrencia de una identificacin definida) podra producir modificaciones mayores en la sintaxis de un lenguaje, si se utilizara diestramente (por ejemplo, RATFOR definido por Kernighan y Plauger, 19746) sin embargo, el poder de este enfoque para una tarea ms compleja, tal como la introduccin de nuevas estructuras de datos, se limitan. Algunas consideraciones serias deben ser dadas a estas tcnicas como alternativas para un nuevo lenguaje, con el simple motivo de aminorar el trabajo y el tiempo implicado. Quizs no haya ningn otro problema relacionado con la computadora que observe tan tentadoramente fcil y sea sumamente terrible un buen trabajo de diseo de lenguaje. Prescinda de la nocin que es posible agitar

PROGRAMACIN DE SISTEMAS un diseo el fin de semana y el comenzar aplicando un traductor para el lunes. Un mes luego habr de asentarse todava los puntos secundarios del diseo del idioma y la implementacin no habr obtenido casi en ningn lugar. Asumiendo la decisin que se ha hecho de que ninguno de los enfoques anteriores seria suficiente, el prximo punto interesante es: Cul es el propsito de un lenguaje? Un lenguaje es diseado a menudo para su aplicacin en un rea especfica. La mayor atencin es dada a restringir el rea de la aplicacin del lenguaje, el mejor lenguaje ser para problemas en esa rea. De hecho no es conveniente el procurar disear un lenguaje de uso general conveniente para ningn problema. Todo intento ha sido desilusionando (notablemente PL/YO y ALGOL 68). Actualmente, toda evidencia indica que nadie sabe cmo hacer un trabajo apropiado de disear un idioma que ser bueno para todo. Finalmente, la relacin de un nuevo lenguaje hacia lenguajes existentes se debe considerar. Weinberg (1971) discute el fenmeno psicolgico de la inhibicin, que ocurre cuando un viejo lenguaje y un lenguaje nuevo no son semejantes pero idnticos. El usuario es susceptible a confundirse gravemente con la incertidumbre acerca de cunto del viejo lenguaje conservara en el nuevo. Por ejemplo. Los programadores de FORTRAN que aprende que PL/YO formatear E/S tiene gran problema con E- y formatos DE TIPO F, que no son semejantes pero idntico a la construccin del FORTRAN. En el resumen es preferible hacer el nuevo lenguaje claramente diferente que hacerlo semejante a algn lenguaje existente. Si los nuevos y los viejos lenguajes Los lenguajes de programacin existentes pueden ser la fuente para mejores ideas para la programacin de diseadores de lenguaje. Los diseadores deben ser muy cuidadosos inclusive acerca de ideas tales en su propio producto, sin embargo, porque los diseadores del pasado han hecho grandes errores en el pasado. Algunos principios despreciables se pueden pronunciar para distinguir buenas ideas dignas de la perpetuacin y de malas ideas dignas slo de la extincin. Quizs el principal principio deber preguntar por qu se hizo esa manera? Una vez que usted obtiene una respuesta a esta pregunta, se pregunta Es esa razn (todava) vlida a menudo la respuesta a esta pregunta ser no. Para el ejemplo FORTRAN las extraas restricciones en subndices de serie dirigiendo las caractersticas de su hardware y tuvo miedo que esto no se podra hacer si ninguna expresin permitindolo como un subndice. Aunque esto se pueda considerar quizs razonable (u optar menos entendible) en la circunstancia que lo ciertamente no es hoy defendible, acerca de la reduccin grave en valor prctico resultante. Aunque vale la pena para recordar el que incluso si el juicio general en un lenguaje sea (un diseo malo esto no significa que identificacin no oculta las caractersticas que valen la pena en algn lugar mas profundamente. Por

PROGRAMACIN DE SISTEMAS ejemplo, aunque APL se pueda criticar en muchas veces, bien puede valer la pena el copiar sus poderosos operadores. Semejantemente, el hecho que una caractersticas est comnmente disponible no puede implicar que sistema operativo una idea buena. Muchos idiomas han seguido ALGOL 60s principal en permitir el tamao de series para ser decidido en corre tiempo, una caracterstica que introduce los problemas considerables de la implementacin e interviene con verificar de error de compila-tiempo. Esta caracterstica puede ser del valor slo limitado en ciertas reas de aplicaciones. El fenmeno de declaraciones predefinidas, heredado de FORTRAN, es otro ejemplo de palabrotas disea. Esta caracterstica en el detalle ilustra la grasa que algn arte actualmente popular de caractersticas de hecho totalmente perjudicial programar la calidad. Semejantemente, el hecho de que una de las caractersticas estn comnmente disponibles no se puede implicar que sea una buena idea su sistema operativo. Muchos lenguajes han seguido ALGOL 60s principalmente el permitir el tamao de series para ser decididazas con mayor rapidez, caracterstica que presenta considerablemente la implementacin de problemas e interfiere con el tiempo de compilacin del cheque de errores. Esta caracterstica puede ser del valor slo limitado en ciertas reas de aplicacin. El fenmeno de preferido declaraciones, heredado de FORTRAN, es otro ejemplo de un mal diseo de programacin. Esta caracterstica en particular clusula; entonces probablemente sera irrazonable requerir ELSE en todo IF. La nocin relativamente reciente de experimentacin con cambios de diseo en condiciones controladas ofrece bsicamente los mismos tipos de conclusiones indudablemente la investigacin seguir en las reas de medir el empleo de los lenguajes de programacin y experimentar en el diseo de los lenguaje de programacin. 2.2 Consideraciones Preliminares Cual es el propsito del lenguaje? No hay un lenguaje bueno para todo Aplicacin especfica Bases de datos, sistemas expertos, clculo numrico, programacin simblica, diseo algortmico, etc. Es necesario disear un nuevo lenguaje? Ya existe un lenguaje apropiado El nuevo lenguaje se diferencia de los existentes Se consume demasiado tiempo en el diseo e implementacin de un nuevo lenguaje Es demasiado fcil disear un lenguaje incompleto Lenguaje demasiado especializado

PROGRAMACIN DE SISTEMAS Sacrificar caractersticas del lenguaje por un compilador simple. Otras opciones: Un modulo o librera de funciones Ampliar un lenguaje de programacin 2.3 OBJETIVOS Y FILOSOFAS DEL DISEO DE LOS LENGUAJES DE PROGRAMACIN. Comunicacin humana: Se busca una comunicacin eficiente entre el programador y el ordenador Un buen nivel de comunicacin se da cuando los programas son lebles No ha de ser necesaria una documentacin externa al programa (minimizar) Es ms importante que un programa sea leble que escribible Un programa se escribe una vez, pero se lee muchas durante su depuracin, documentacin y mantenimiento. Tendencia actual a separar la interfaz de la implementacin de un mdulo La sintaxis ha de reflejar la semntica Reducir las manipulaciones implcitas Prevencin y deteccin de errores: Hay que prevenir los errores Hay que facilitar su deteccin, identificacin y correccin Redundancia Evitar coerciones inductoras de errores Comprobaciones en tiempo de ejecucin

Usabilidad Efectividad: Los detalles de implementacin no han de oscurecer las intenciones del programador Soportar abstraccin Modularidad: Separar especificacin de implementacin Los Efectos de un cambio han de quedar localizados Evitar los trucos (programas ilegible) Compilabilidad Se ha de poder compilar programa en un tiempo reducido Se ha de poder depurar o aplicar otras herramientas de anlisis

PROGRAMACIN DE SISTEMAS Eficiencia: La ejecucin ha de ser rpida. Independencia de la mquina: Simplicidad: Uniformidad: Lenguaje predecible Ortogonalidad: Todas las caractersticas del lenguaje se han de poder combinar Generalizacin y especializacin: La generalizacin dice que algo similar tambin es correcto, pero es difcil de implementar Hay que especializar para facilitar la implementacin sin perder la utilidad del lenguaje 2.4 DISEO DETALLADO En esta etapa se adecua el anlisis a las caractersticas especficas del ambiente de implementacin y se completan las distintas aplicaciones del sistema con los modelos de control, interfaz o comunicaciones, segn sea el caso. Microestructura Estructura de las expresiones Estructuras de datos Estructuras de control Estructura de compilacin Estructura de la entrada/salida

2.5 CASO DE ESTUDIO.

UNIDAD III ANLISIS LXICO

PROGRAMACIN DE SISTEMAS 3.1 INTRODUCCIN A LOS AUTMATAS FINITOS Y EXPRESIONES REGULARES Los autmatas finitos. Son las posibles cadenas que acepta un lenguaje. Se compila una expresin regular en un reconocedor construyendo un diagrama de transicin que es una instrumentacin de un modelo formal denominado autmatas finitos, conocidos tambin como mquinas de estado finito o (con menos frecuencia en la actualidad) mquinas secuenciales. Es la representacin grfica de las posibles cadenas que acepta un lenguaje dentro de un conjunto de smbolos, se conforma por una quntupla donde: Las expresiones regulares.

Es el conjunto de posibles estados Representa al alfabeto Representa la funcin de transicin y los estados por los que se acepta cada uno de los smbolos qo Estado inicial F Conjunto de estados finales

Son los posibles smbolos que puede aceptar un lenguaje los cuales se pueden representar con un autmata. Conjunto de smbolos para aceptar una palabra reservada. Una expresin regular es una frmula para denotar "ciertos" lenguajes. Advirtase que decimos lenguaje, no cadena de caracteres. Una expresin regular nica denota un conjunto de cadenas, es decir un lenguaje, no una simple cadena. Las expresiones regulares se pueden usar para especificar unidades lxicas presentes en un lenguaje de programacin. No todos los lenguajes pueden ser expresados utilizando una expresin regular. Sea un alfabeto . La expresin regular sobre y los conjuntos que denotan se definen de manera recursiva como sigue: es una expresin regular y denota al conjunto vaco {}. Para cada a , a es una expresin regular y denota al conjunto {a}. Si r y s son expresiones regulares que denotan a los lenguajes R y S respectivamente, entonces tenemos lo siguiente.

PROGRAMACIN DE SISTEMAS r+s (r) rs es una expresin regular que denota a los conjuntos R S. es una expresin regular que denota al conjunto R. es una expresin regular que denota a los conjuntos RS.

r* es una expresin regular que denota al conjunto R*, equivale desde cero a ms repeticiones del lenguaje R. r+ es una expresin regular que denota al conjunto R+, equivale a una o ms repeticiones del Lenguaje R. ri es una expresin regular que denota al conjunto Ri, a s mismo. 3.2 ANLIZADOR LXICO El analizador lxico lee los caracteres del programa fuente, y verifica que correspondan a una secuencia lgica (identificador, palabra reservada etc.). Esta secuencia de caracteres recibe el nombre componente lxico o lexema. FUNCIN DEL ANALIZADOR LXICO Su principal funcin consiste en leer los caracteres de entrada y elabora como salida una secuencia de componentes lxicos (tokens) que utiliza el analizador sintctico para hacer el anlisis. Es la parte del compilador que lee el texto fuente. Recibida la orden "obtn el siguiente componente lxico" del analizador sintctico, el analizador lxico lee los caracteres de entrada hasta que pueda identificar el siguiente componente lxico. Elimina del programa fuente comentarios, espacios en blanco, caracteres TAB y de lnea nueva. Otra funcin es relacionar los mensajes de error del compilador con el programa fuente. En algunos compiladores, el analizador lxico se encarga de hacer una copia del programa fuente en el que estn marcados los mensajes de error.

PROGRAMACIN DE SISTEMAS Analizador Lxico dentro de un Compilador

En algunas ocasiones, los analizadores lxicos se dividen en dos fases; la primera llamada "examen", y la segunda, "anlisis lxico". El examinador se encarga de realizar tareas sencillas, mientras que el analizador lxico es el que realiza las operaciones ms complejas. El objetivo del anlisis lxico es gestionar el "bajo nivel" de la entrada (en este caso, texto) y suministrarle al analizador sintctico la misma ya "filtrada", es decir, conteniendo solamente terminales de la gramtica a definir. La relacin entre el analizador lxico y el sintctico son los tokens y la tabla de smbolos, ya que la funcin principal del anlisis lxico es leer los caracteres de entrada y genera como salida una secuencia de componentes lxicos previamente definidos en expresiones regulares. ASPECTOS A CONSIDERAR PARA EL ANLISIS LXICO Un diseo sencillo de un analizador lxico corresponde a unas reglas del lenguaje meramente sencillas, sin embargo estas son algunas consideraciones importantes: Mientras menos complicadas sean las gramticas, ms fcil ser realizar un compilador, slo que previamente se deben considerar las expresiones regulares. Hay que considerar si se debe o compilador. puede mejorar la eficiencia del

Tambin mejorar la transportabilidad del compilador, ya que las letras del alfabeto y los errores propios de los dispositivos pueden limitar al analizador lxico.

El trabajo bsico es reconocer los terminales (que podemos llamar ya unidades lxicas), y para ello podemos hacer una tabla con todas las posibilidades que encontraremos en el fichero de la entrada y agruparlos en los tipos necesarios. 3.3 MANEJO DE LOCALIDADES TEMPORALES DE MEMORIA (BUFFERS). El uso de localidades temporales de memoria es para agilizar el tiempo de compilacin, el manejo de este es por medio de estructuras de datos utilizando memoria dinmica, como se vio en materias anteriores como estructura de datos,

PROGRAMACIN DE SISTEMAS usando esta implementacin de diferentes formas que pueden clasificarse de acuerdo a su argumento de bsqueda.

3.4 CREACIN DE TABLAS DE SMBOLOS TABLAS DE SMBOLOS Es una estructura de datos que contiene un registro por cada token o identificador que define los atributos de ellos mismos. La estructura de datos permite encontrar rpidamente el registro para ser almacenado o consultado por otras fases. Cuando el anlisis lxico detecta un token en el programa fuente, este se introduce en la tabla de smbolos, sin embargo, sus atributos no pueden determinarse durante el anlisis lxico. Por ejemplo, dada la siguiente instruccin: Var inicial, velocidad: integer ;

El tipo entero no se conoce cuando el analizador lxico pasa por toda la instruccin, las fases restantes introducen informacin sobre los tokens en la tabla y despus hace uso de ella.

PROGRAMACIN DE SISTEMAS Cuando se hace el anlisis semntico y la generacin de cdigo intermedio se necesita saber los tipos de cada uno de los identificadores para comprobar si el programa fuente los usa en forma vlida y as generar las operaciones apropiadas con ellos.

3.5 MANEJO DE ERRORES LXICOS Errores Lxicos Son pocos los errores detectables en el analizador lxico porque se tiene una visin restringida del programa, ya que no se puede distinguir entre un error de escritura de un identificador y una palabra reservada, as como la declaracin y utilizacin de una funcin, porque todas las consideran en esta fase como un identificador vlido y los errores se empiezan a detectar entre el analizador semntico o el analizador sintctico, segn sea el caso. Tcnicas de correccin de errores Existen algunas tcnicas de correccin que son utilizadas en compiladores, sin embargo no es conveniente modificar la idea original, ni la lgica de programacin del usuario. Las tcnicas son las siguientes: Modo de pnico. Donde se guardan los caracteres sucesivos de la entrada restante, hasta encontrar un componente lxico vlido. Borrar un carcter extrao que no haya sido declarado o definido dentro del lenguaje. Insertar un carcter que falte. Reemplazar un carcter faltante Intercambiar caracteres adyacentes

3.6 GENERADORES DE CDIGO LXICO: LEX, FLEX, JFLEX, JAVACC, ANTLR. Generador de Cdigo Lex El lex es un generador de programas diseado para el proceso lxico de cadenas de caracteres de entrada. El programa acepta una especificacin, orientada a resolver un problema de alto nivel para comparar literales de caracteres, y produce un programa C que reconoce expresiones regulares. Estas expresiones las especifica el usuario en las especificaciones fuente que se le dan al lex. El cdigo lex reconoce estas expresiones en una cadena de entrada y divide esta entrada en cadenas de caracteres que coinciden con las expresiones. En los

PROGRAMACIN DE SISTEMAS bordes entre los literales, se ejecutan las secciones de programas proporcionados por el usuario. El fichero fuente lex asocia las expresiones regulares y los fragmentos de programas. Puesto que cada expresin aparece en la entrada del programa escrito por el lex, se ejecuta el fragmento correspondiente. El usuario proporciona el cdigo adicional necesario para completar estas funciones, incluyendo cdigo escrito por otros generadores. El programa que reconoce las expresiones se genera en forma de fragmentos de programa C del usuario, El lex no es un lenguaje completo sino un generador que representa una cualidad de un nuevo lenguaje que se aade al leguaje de programacin C. Formato fuente del Lex El formato general de la fuente lex es: {definiciones} %% /* seccin de definiciones*/ {reglas} %% /* seccin de reglas*/ {Seccin de rutinas auxiliares} a) Seccin de definiciones La seccin de definiciones contiene la siguiente informacin:

Cdigo C encerrado entre los delimitadores % y %, que se copia literalmente en el fichero de salida lex.yy.c antes de la definicin de la funcin yylex (). Habitualmente, esta seccin contiene declaraciones de variables y funciones que se utilizaran posteriormente en la seccin de reglas, as como directivas #include.

Definiciones propias de Lex, que permiten asignar nombre a una expresin regular o a una parte de ella, para utilizarlo posteriormente en lugar de una expresin. Para dar nombre a una expresin regular, se escribe el nombre en la primera columna de una lnea, seguido por uno o ms espacios en blanco y por la expresin regular que representa a los dgitos del 0 al 9 de la siguiente forma: DIGITO [0-9]
b) Seccin de Reglas La seccin de reglas contiene, para cada unidad sintctica, la expresin regular que la describe, seguida de uno o ms espacios en blanco y del cdigo C que debe ejecutarse cuando se localice en la entrada dicha unidad sintctica. Este cdigo C debe aparecer encerrado entre llaves. Como ejemplo, consideremos un analizador morfolgico que reconozca en la entrada las constantes numricas y las palabras reservadas begin y end. Cada

PROGRAMACIN DE SISTEMAS vez que localice una de ellas debe mostrar en la salida un mensaje de aviso de unidad sintctica reconocida. c) Seccin de rutinas auxiliares Habitualmente, esta seccin contiene las funciones escritas por el usuario para utilizarlas en la seccin de reglas, es decir, funciones de soporte. En esta seccin tambien se incluyen las funciones de lex que el usuario puede redefinir, como, por ejemplo, la funcion yywrap (). El contenido de esta seccin se copia literalmente en el fichero lex.yy.c que genera lex. Generador de Cdigo JFlex JFlex es un generador de analizadores lexicogrficos desarrollado por Gerwin Klein como extensin a la herramienta JLex desarrollada en la Universidad de Princeton. JFlex est desarrollado en Java y genera cdigo Java. Los programas escritos para JFlex tienen un formato parecido a los escritos en PCLex; de hecho todos los patrones regulares admisibles en Lex tambin son admitidos por JFlex, por lo que en este apartado nos centraremos tan slo en las diferencias y extensiones, tanto de patrones como del esqueleto que debe poseer el fichero de entrada a JFlex. La instalacin y ejecucin de JFlex es trivial. Una vez descomprimido el fichero dispondremos del fichero JFlex.jar que tan slo es necesario en tiempo de metacompilacin, siendo el analizador generado totalmente independiente. La clase Main del paquete JFlex es la que se encarga de metacompilar nuestro programa .jflex de entrada; de esta manera, una invocacin tpica es de la forma: java JFlex.Main fichero.jflex lo que generar un fichero Yylex.java que implementa al analizador lexicogrfico. Generador de Cdigo Javacc JavaCC (Java Compiler Compiler - Metacompilador en Java) es el principal metacompilador en JavaCC, tanto por sus posibilidades, como por su mbito de difusin. Se trata de una herramienta que facilita la construccin de analizadores lxicos y sintcticos por el mtodo de las funciones recursivas, aunque permite una notacin relajada muy parecida a la BNF. De esta manera, los analizadores generados utilizan la tcnica descendente a la hora de obtener el rbol sintctico. Caractersticas Generales: JavaCC integra en una misma herramienta al analizador lexicogrfico y al sintctico, y el cdigo que genera es independiente de cualquier biblioteca externa, lo que le confiere una interesante propiedad de independencia respecto al entorno. A grandes rasgos, sus principales caractersticas son las siguientes:

PROGRAMACIN DE SISTEMAS Genera analizadores descendentes, permitiendo el uso de gramticas de propsito general y la la utilizacin de atributos tanto sintetizados como heredados durante la construccin del rbol sintctico. Las especificaciones lxicas y sintcticas se ubican en un solo archivo. De esta manera la gramtica puede ser leda y mantenida ms fcilmente. No obstante, cuando se introducen acciones semnticas, recomendamos el uso de ciertos comentarios para mejorar la legibilidad. Admite el uso de estados lxicos y la capacidad de agregar acciones lxicas incluyendo un bloque de cdigo Java tras el identificador de un token. Caractersticas Generales: Incorpora distintos tipos de tokens: normales (TOKEN), especiales (SPECIAL_TOKEN), espaciadores (SKIP) y de continuacin (MORE). Ello permite trabajar con especificaciones ms claras, a la vez que permite una mejor gestin de los mensajes de error y advertencia por parte de JavaCC en tiempo de metacompilacin. Los tokens especiales son ignorados por el analizador generado, pero estn disponibles para poder ser procesados por el desarrollador. La especificacin lxica puede definir tokens de manera tal que no se diferencien las maysculas de las minsculas bien a nivel global, bien en un patrn concreto. Adopta una notacin BNF propia mediante la utilizacin de smbolos propios de expresiones regulares, tales como (A)*, (A)+. Genera por defecto un analizador sintctico LL(1). No obstante, puede haber porciones de la gramtica que no sean LL(1), lo que es resuelto en JavaCC mediante la posibilidad de resolver las ambigedades desplazar/desplazar localmente en el punto del conflicto. En otras palabras, permite que el a.si. Se transforme en LL(k) slo en tales puntos, pero se conserva LL(1) en el resto de las reglas mejorando la eficiencia. De entre los generadores de analizadores sintcticos descendentes, JavaCC es uno de los que poseen mejor gestin de errores. Los analizadores generados por JavaCC son capaces de localizar exactamente la ubicacin de los errores, proporcionando informacin diagnstica completa. Generador de Cdigo ANTLR Antlr permite construir rboles de sintaxis abstracta (ASA) mediante anotaciones en la gramtica indicando qu tokens deben tratarse como races de subrboles, cules son tokens hojas y cules deben ignorarse. Tipo de analizador: Descendente recursivo, LL(k).

PROGRAMACIN DE SISTEMAS Cdigo generado: Java, C++, C#. Caractersticas adicionales: Construccin de ASTs.

UNIDAD IV ANALISIS SINTACTICO 4.1 INTRODUCCIN A LAS GRAMTICAS LIBRES DE CONTEXTO Y RBOLES DE DERIVACIN. A partir de alguna clase de gramticas se puede construir automticamente un analizador sintctico eficiente que determine si un programa fuente esta sintacticamente bien formado. Una gramtica diseada adecuadamente imparte una estructura a un lenguaje de programacin til para la traduccin de programas fuente a cdigo objeto correcto y para la deteccin de errores Todo lenguaje de programacin tiene reglas que prescriben la estructura sintctica de programas bien formados. La tarea del anlisis sintctico es determinar la estructura sintctica de un programa a partir de de los tokens producidos por el analizador lxico y, ya sea de manera implcita o explicita, construir un rbol de anlisis gramatical o sintctico que represente esta estructura. De este modo, se puede ver el analizador sintctico como una funcin que toma como su entrada la secuencia de tokens producidos por el analizador lxico y que produce como su salida el rbol sintctico.

El Analizador Sintctico dentro del modelo de un compilador. GRAMTICAS Y LENGUAJES SENSIBLES AL CONTEXTO. Una Gramtica Libre de Contexto es un conjunto finito de smbolos o variables que representan categoras aplicables a elementos de lxico. La gramtica libre de contexto es muy til para definir relaciones entre objetos sintcticos tales como la sintaxis de un lenguaje de programacin. Una gramtica libre de contexto tiene un smbolo de arranque o de objetivo. Son smbolos terminales

PROGRAMACIN DE SISTEMAS que representan ejemplos de variables y son reglas de produccin que combinan entre s para el logro del objetivo. Las gramticas libres al contexto consta de: Los terminales son smbolos bsicos con que se forman las cadenas. Los no terminales son variables sintcticas que denotan conjuntos de cadenas. En una gramtica, un no terminal es considerado como el smbolo inicial, y el conjunto de cadenas que representan es el lenguaje definido por la gramtica. Las producciones de una gramtica especifican como se pueden combinar los terminales y los no terminales para formar las cadenas.

Notacin BNF La notacin ms frecuentemente utilizada para expresar gramticas libres de contexto es la forma Backus-Naur. Las gramticas libres de contexto tienen mtodos alternativos tiles para desplegar las producciones. Una alternativa que se encuentra con frecuencia es la notacin BNF (forma Backus-Naur). Se sabe que los lados izquierdos de todas las producciones en una gramtica de tipo 2 son smbolos no terminales nicos. Para cada uno de tales smbolos w, se combina todas las producciones que tienen a w como lado izquierdo. El smbolo w permanece a la izquierda, y todos los lados derechos asociados con w son enumerados juntos, separados por el smbolo |. El smbolo relacional se reemplaza por el smbolo ::=. Por ltimo, los smbolos no terminales, cuando aparezcan, sern encerrados entre parntesis agudos < >. Ejemplo:

RBOLES DE DERIVACION Derivaciones por la izquierda y derecha: Existen bsicamente dos formas de describir como en una cierta gramtica una cadena puede ser derivada desde el smbolo inicial. La forma ms simple es listar las cadenas de smbolos consecutivas, comenzando por el smbolo inicial y finalizando con la cadena y las reglas que han sido aplicadas. Si introducimos estrategias como reemplazar siempre el no terminal de ms a la izquierda

PROGRAMACIN DE SISTEMAS primero, entonces la lista de reglas aplicadas es suficiente. A esto se le llama derivacin por la izquierda. Por ejemplo, si tomamos la siguiente gramtica: (1) S S + S (2) S 1

Y la cadena "1 + 1 + 1", su derivacin a la izquierda est en la lista [ (1), (1), (2), (2), (2) ]. Anlogamente, la derivacin por la derecha se define como la lista que obtenemos si siempre reemplazamos primero el no terminal de ms a la derecha. En ese caso, la lista de reglas aplicadas para la derivacin de la cadena con la gramtica anterior sera la [ (1), (2), (1), (2), (2)]. La distincin entre derivacin por la izquierda y por la derecha es importante porque en la mayora de analizadores la transformacin de la entrada es definida dando una parte de cdigo para cada produccin que es ejecutada cuando la regla es aplicada. De modo que es importante saber que derivacin aplica el analizador, por que determina el orden en el que el cdigo ser ejecutado. Una derivacin tambin puede ser expresada mediante una estructura jerrquica sobre la cadena que est siendo derivada. Por ejemplo, la estructura de la derivacin a la izquierda de la cadena "1 + 1 + 1" con la gramtica anterior sera: SS+S (1) SS+S+S (1) S1+S+S (2) S1+1+S (2) S1+1+1 (2) { { { 1 }S + { 1 }S }S + { 1 }S }S donde { ... }S indica la subcadena reconocida como perteneciente a S. Esta jerarqua tambin se puede representar mediante un rbol sintctico:

La derivacin por la derecha: S S S S S S + S (1) 1 + S (2) 1 + S + S (1) 1 + 1 + S (2) 1 + 1 + 1 (2)

define el siguiente rbol sintctico:

PROGRAMACIN DE SISTEMAS

4.2 DIAGRAMAS DE SINTAXIS Un diagrama de sintaxis (tambin llamados diagramas de Conway) es un grafo dirigido donde los elementos no terminales aparecen como rectngulos, y los terminales como crculos o elipses. Todo diagrama de sintaxis posee un origen y un destino, que no se suelen representar explcitamente, sino que se asume que el origen se encuentra a la izquierda del diagrama y el destino a la derecha. Cada arco con origen en " y destino en $ representa que el smbolo " puede ir seguido del $ (pudiendo ser " y $ tanto terminales como no terminales). De esta forma todos los posibles caminos desde el inicio del grafo hasta el final, representan formas sentenciales vlidas. Demostraremos que los diagramas de sintaxis permiten representar las mismas gramticas que la notacin BNF, por induccin sobre las operaciones bsicas de BNF:

4.3 PRECEDENCIA DE OPERADORES

La precedencia de un operador indica qu tan "cerca" se agrupan dos expresiones. Por ejemplo, en la expresin 1 + 5 * 3, la respuesta es 16 y no 18,

PROGRAMACIN DE SISTEMAS ya que el operador de multiplicacin ("*") tiene una mayor precedencia que el operador de adicin ("+"). Los parntesis pueden ser usados para marcar la precedencia, si resulta necesario. Por ejemplo: (1 + 5) * 3 evala a 18. Si la precedencia de los operadores es la misma, se utiliza una asociacin de izquierda a derecha. La siguiente tabla lista la precedencia de los operadores, con aquellos de mayor precedencia listados al comienzo de la tabla. Los operadores en la misma lnea tienen la misma precedencia, en cuyo caso su asociatividad decide el orden para evaluarlos. Tabla de Precedencia de Operadores Asociatividad Operadores no-asociativo new izquierda [ no-asociativos ++ -no-asociativos ! ~ - (int) (float) (string) (array) (object) @ izquierda */% izquierda +-. izquierda << >> no-asociativos < <= > >= no-asociativos == != === !== izquierda & izquierda ^ izquierda | izquierda && izquierda || izquierda ?: derecha = += -= *= /= .= %= &= |= ^= <<= >>= izquierda and izquierda xor izquierda Or izquierda , Informacin Adicional new array() incremento/decremento tipos aritmtica aritmtica, y cadena manejo de bits comparacin comparacin manejo de bits, y referencias manejo de bits manejo de bits lgicos lgicos ternario asignacin lgicos lgicos lgicos varios usos

Por ejemplo, la siguiente expresin produce un resultado diferente dependiendo de si se realiza la suma o divisin en primer lugar: x + y / 100 Si no se indica explcitamente al compilador el orden en que se quiere que se realicen las operaciones, entonces el compilador decide basndose en la precedencia asignada a los operadores. Como el operador de divisin tiene mayor precedencia que el operador de suma el compilador evaluar y/100 primero.

PROGRAMACIN DE SISTEMAS As: x + y / 100 Es equivalente a: x + (y / 100) 4.4 ANALIZADOR SINTCTICO Tipos de anlisis sintctico Segn la aproximacin que se tome para construir el rbol sintctico se desprenden dos tipos o clases de analizadores: Descendentes: Parten del axioma inicial, y van efectuando derivaciones a izquierda hasta obtener la secuencia de derivaciones que reconoce a la sentencia. Pueden ser: Con retroceso. Con funciones recursivas. De gramticas LL(1).

Ascendentes: Parten de la sentencia de entrada, y van aplicando derivaciones inversas (desde el consecuente hasta el antecedente), hasta llegar al axioma inicial. Pueden ser: "Con retroceso. "De gramticas LR(1). 4.4.1 ANALIZADOR SINTCTICO DESCENDENTE (LL) Analiza una cadena de tokens de entrada mediante bsquedas de los pasos de una derivacin por la izquierda. Este mtodo se denomina descendente debido al que el recorrido implicado del rbol de anlisis gramatical es un recorrido de preorden y, de este modo, se presenta desde la raz hacia las hojas. Existen 2 formas: Analizadores sintctico inverso o en reversa y analizadores sintctico predictivos. El analizador sintctico predictivo intenta predecir la siguiente construccin en la cadena de entrada utilizando uno o mas tokens de bsquedas por adelantado, mientras que un analizador sintctico inverso intentara las diferentes posibilidades para un anlisis sintctico de la entrada, respaldando un a cantidad arbitraria en la entrada una posibilidad falla, el inverso es mucho mas exacto que el preventivo, pero, su procesamiento es demasiado lento y eso lo hace inadecuado para compiladores prcticos.

PROGRAMACIN DE SISTEMAS Las dos clases de algoritmos de anlisis sintctico descendente se denomina anlisis sintctico descendente recursivo y el anlisis sintctico LL (1). Por ejemplo considere la gramtica:

Y la cadena de entrada w = cad. Para construir un rbol de anlisis sintctico descendente para esta cadena, primero se crea un rbol formado por un solo nodo etiquetado con S. Un apuntador a la entrada apunta a c, el primer smbolo de w. Ejemplo:

4.4.2 ANALIZADOR SINTCTICO ASCENDENTE (LR) La L indica que la entrada se procesa de izquierda a derecha, y la R indica que se produce una derivacin por la derecha. Incluir la construccin de los DFA, as como la construccin de las tablas de anlisis sintctico que se asocian con ellas. Este analizador utiliza una pila explicita para realizar un anlisis sintctico de manera semejante como lo hace un analizador sintctico descendente no recursivo. La pila de anlisis sintctico contendr tanto tokens como no terminales y tambin alguna informacin de estado adicional que analizaremos

PROGRAMACIN DE SISTEMAS posteriormente. La pila esta vaca al principio de un anlisis sintctico ascendente y al final de un anlisis sintctico exitoso contendr el smbolo inicial. Un esquema de anlisis sintctico ascendente es:

Donde la pila de anlisis sintctico esta a la izquierda, la entrada esta en el centro y las acciones del analizador sintctico estn a la derecha. Un analizador sintctico ascendente tiene dos posibles acciones: 1.- DESPLAZAR: o transferir un terminal de la parte frontal de la entrada hasta la parte superior de la pila. 2.- REDUCIR: una cadena & en la parte superior de la pila a un no terminal A, dada las elecciones BNF A --> &. Por esta razn el analizador sintctico ascendente se conoce como analizador sintctico de reduccin por desplazamiento. Diferencias entre los Mtodos Ascendente y Descendente Ambos son mtodos que nos sirve para el anlisis sintcticos, pero una la mas importante diferencia que hay entre los 2 mtodos : 1.- Es en la forma que recorren el rbol gramaticales el descendente lo recorre en forma de preorden de la raz a las hojas empezando por la izquierda y el ascendente lo recorrer en forma contraria empezando de las hojas hacia la raz. 2.- El ascendente utiliza una pila. No es sensible me da chance para aceptar mas cadenas y mas alternativa. 4.5 ADMINISTRACIN DE TABLAS DE SMBOLOS Tabla de Smbolos (TDS): Estructura de datos usada por el compilador para asociar a cada smbolo (nombre) del programa una representacin de su contenido semntico (atributos). 1. 2. 3. 4. Funcin anloga a un diccionario. Mecanismo para representar el contexto en un programa. Mantiene la informacin que se ha recogido acerca de un smbolo desde el momento de su declaracin. Mecanismo utilizado en A. Semntico para implementar las restricciones tpicas de los lenguajes de programacin:

PROGRAMACIN DE SISTEMAS Control de unicidad de identificadores. Asegurar que toda variable fue declarada antes de ser usada. Verificacin de tipos. Implementacin de reglas de mbito (en lenguaje con estructura de bloques).

TDSs slo existen durante compilacin, no suelen incorporarse al fichero objeto. 1. Se puede incorporar para facilitar depuracin (acceso a variables nombre, etc.). 2. Tambin, se incorpora en los interpretes (alternan compilacin y ejecucin). La informacin guardada (campos) depende del elemento almacenado, del lenguaje y de la estructura del compilador:

Atributos en TDS
1. Nombre del smbolo: string: 2. Direccin en memoria: direccin donde se guardarn los valores de las variables durante la ejecucin. No direccin absolutas, sino relativas a una zona de memoria durante la ejecucin. No contiene valores, solo informacin de almacenamiento. 3. Tipo: codificacin correspondiente al tipo de dato asociado al smbolo. 4. Localizacin (numero lnea, nombre fichero): informacin auxiliar para depuracin. TDS puede estar inicializada con informacin sobre smbolos especiales del lenguaje (palabras reservadas, funciones de librera, constantes predefinidas, etc...)

Operaciones en TDS (interfaz)


1. 2. 3. 4. 5. Insertar un smbolo en la tabla (comprobando). Buscar y recuperar informacin de un smbolo. Modificar informacin de un smbolo. Borrar. En lenguajes con estructura de bloques: NuevoBloque: inicio de un bloque. FinBloque: fin del mbito de un bloque.

PROGRAMACIN DE SISTEMAS 4.6 MANEJO DE ERRORES SINTCTICOS Y SU RECUPERACIN A menudo, gran parte de la deteccin y recuperacin de errores en un compilador se centra en la fase de anlisis sintctico. Una razn es que muchos errores son de naturaleza sintctica o se manifiestan cuando la cadena de componentes lxicos que proviene del analizador lxico desobedece la reglas gramaticales que definen el lenguaje de programacin. Otra razn es la precisin de los mtodos modernos de anlisis sintctico, que pueden detectar la presencia de errores dentro de los programas de una forma muy eficiente. La deteccin exacta de la presencia de errores semnticos y lgicos en el momento de la compilacin es mucho ms difcil. El manejador de errores en un analizador sintctico tiene objetivos fciles de establecer: Debe de informar de la presencia de errores con claridad y exactitud. Se debe de recuperar de cada error con la suficiente rapidez como para detectar errores posteriores. No de be retrazar de manera significativa el procesamiento de programas correctos.

Afortunadamente lo errores ms comunes son simples y a menudo basta con un mecanismo sencillo de manejo de errores. sin embargo, en algunos casos un error pudo haber ocurrido mucho antes de la posicin en que se detect su presencia, y puede ser muy difcil deducir su naturaleza precisa de error. En los casos difciles, el manejador de errores quiz tenga que adivinar qu tena en mente el programador cuando escribi el programa. Cmo debe informar un manejador de errores de la presencia de un error ?, al menos debe informar del lugar en el programa fuente donde se detecta el error, porque es muy probable que el error real se haya producido en alguno de los componentes lxicos anteriores. Una estrategia comn empleada por muchos compiladores e imprimir la lnea errnea con un apuntador a la posicin donde se detecta el error. Si hay una posibilidad razonable de saber cul es realmente el error, tambin se incluye un mensaje de diagnstico informativo y comprensible; por ejemplo "Falta punto y coma en esta posicin". Una vez detectado el error, Cmo se debe de recuperar el analizador sintctico ?, En la mayora de los casos, no es adecuado que el analizador sintctico abandone despus de detectar el primer error, porque el posterior procesamiento de la entrada podra revelar ms errores. Normalmente, hay alguna forma de recuperacin del error donde el analizador sintctico intenta volver l mismo a un estado en el que el procesamiento de la entrada pueda continuar con una esperanza razonable de que har el anlisis de la entrada correcta o de que ser manejada correctamente por el compilador. Hay muchas estrategias generales distintas que puede emplear un analizador sintctico para recuperarse de un error sintctico. Aunque ninguna de ellas ha demostrado ser la aceptacin universal, algunos mtodos tienen una amplia aplicabilidad. Mencionaremos algunas estrategias, entre las cuales estn:

PROGRAMACIN DE SISTEMAS

Recuperacin en modo de pnico: Este es el mtodo ms sencillo de implantar y pueden utilizarlo la mayora de los mtodos de anlisis sintctico. Al descubrir un error, el analizador sintctico desecha smbolo de entrada, de uno en uno, hasta que encuentra uno perteneciente a un conjunto designado de componente lxicos de sincronizacin. Estos componente lxicos de sincronizacin son generalmente delimitadores, como el punto y coma o la palabra clave end, cuyo papel en el programa fuente est claro. Es evidente que quien disea el compilador debe seleccionar los componentes lxicos de sincronizacin adecuados para el lenguaje fuente. Aunque la correccin en modo de pnico a menudo omite una cantidad considerable de entrada sin comprobar la existencia de errores adicionales, tiene la ventaja de la sencillez y, a diferencia de otros mtodos, esta garantizado contra lazos infinitos. En situaciones en donde son raros los errores mltiples en la misma proposicin, este mtodo puede resultar bastante adecuado. Recuperacin a nivel de frase: Al descubrir un error, el analizador sintctico puede realizar una correccin local de la entrada restante; es decir, puede sustituir un prefijo de la entrada restante por alguna cadena que permita continuar al analizador sintctico. Una correccin local tpica sera sustituir una coma por un punto y coma, suprimir un punto y coma sobrante e insertar un punto y coma que falta. La eleccin de la correccin local corresponde al
diseador del compilador. Por supuesto se debe de tener cuidado de elegir sustituciones que no conduzcan a lazos infinitos.

Producciones de error: Si se tiene una buena idea de los errores comunes que puede encontrarse, se puede aumentar la gramtica del lenguaje con producciones que generen las construcciones errneas. Entonces se usa esta gramtica aumentada con las producciones de error para construir el analizador sintctico. Si el analizador sintctico usa una produccin de error, se pueden generar diagnsticos de error apropiados para indicar la construccin errnea reconocida en la entrada. Correccin global: Idealmente, sera deseable que un compilador hiciera el mnimo de cambios posibles al procesar una cadena de entrada incorrecta. Existen algoritmos para elegir una secuencia mnima de cambios para obtener una correccin global de menor costo. Dada una cadena de entrada incorrecta x y la gramtica G, estos algoritmos encontrarn un rbol de anlisis sintctico para una cadena relacionada y, tal que el nmero de inserciones, supresiones y modificaciones de componentes lxicos necesarios para transformar x en y sea el mnimo posible. Por desgracia, la implantacin de estos mtodos es en general demasiado costosa en trminos de tiempo y espacio, as que estas tcnicas en la actualidad slo son de inters terico.
Se debe sealar que un programa correcto ms parecido al original puede no ser lo que el programador tena en mente. Sin embargo, la nocin de correccin de costo mnimo proporciona una escala para evaluar las tcnicas de recuperacin de errores, y se ha usado para encontrar cadenas de sustitucin ptimas para recuperacin a nivel de frase.

PROGRAMACIN DE SISTEMAS

4.7 GENERADORES DE CDIGO PARA ANALIZADORES SINTCTICOS: YACC, BISON, BYACC, ANTLR, JAVACC.

UNIDAD V ANALISIS SEMANTICO 5.1 ANALIZADOR SEMNTICO La fase de anlisis semntico de un procesador de lenguaje es aqulla que computa la informacin adicional necesaria para el procesamiento de un lenguaje, una vez que la estructura sintctica de un programa haya sido obtenida. Es por tanto la fase posterior a la de anlisis sintctico y la ltima dentro del proceso de sntesis de un lenguaje de programacin. Sintaxis de un lenguaje de programacin es el conjunto de reglas formales que especifican la estructura de los programas pertenecientes a dicho lenguaje. Semntica de un lenguaje de programacin es el conjunto de reglas que especifican el significado de cualquier sentencia sintcticamente vlida. Finalmente, el anlisis semntico de un procesador de lenguaje es la fase encargada de detectar la validez semntica de las sentencias aceptadas por el analizador sintctico. Dado el siguiente ejemplo en cdigo c: Superficie = base * altura / 2; La sintaxis del lenguaje C indica que las expresiones se pueden formar con un conjunto de operadores y un conjunto de elementos bsicos. Entre los operadores, con sintaxis binaria infija, se encuentran la asignacin, el producto y la divisin. Entre los elementos bsicos de una expresin existen los identificadores y las constantes enteras sin signo (entre otros). Su semntica identifica que en el registro asociado al identificador superficie se le va a asociar el valor resultante del producto de los valores asociados a base y altura, divididos por dos (la superficie de un tringulo). Finalmente, el anlisis semntico del procesador de lenguaje, tras haber analizado correctamente que la sintaxis es vlida, deber comprobar que se satisfacen las siguientes condiciones: Que todos los identificadores que aparecen en la expresin hayan sido declarados en el mbito actual, o en alguno de sus mbitos (bloques 2) previos.

PROGRAMACIN DE SISTEMAS Que la subexpresin de la izquierda sea semnticamente vlida, es decir, que sea un lvalue3. Que a los tipos de los identificadores base y altura se les pueda aplicar el operador de multiplicacin. Un registro en C, por ejemplo, no sera vlido. Deber inferirse el tipo resultante de la multiplicacin anterior. Al tipo inferido se le deber poder aplicar el operador de dividir, con el tipo entero como multiplicando. Deber inferirse el tipo resultante de la divisin y comprobarse si ste es compatible con el tipo de superficie para llevar a cabo la asignacin. Como ejemplo, si superficie fuese entera y divisin real, no podra llevarse a cabo la asignacin.

El objetivo principal del analizador semntico de un procesador de lenguaje es asegurarse de que el programa analizado satisfaga las reglas requeridas por la especificacin del lenguaje, para garantizar su correcta ejecucin. El tipo y dimensin de anlisis semntico requerido vara enormemente de un lenguaje a otro. En lenguajes interpretados como Lisp o Smalltalk casi no se lleva a cabo anlisis semntico previo a su ejecucin, mientras que en lenguajes como Ada, el analizador semntico deber comprobar numerosas reglas que un programa fuente est obligado a satisfacer. Vemos, pues, cmo el anlisis semntico de un procesador de lenguaje no modela la semntica o comportamiento de los distintos programas construidos en el lenguaje de programacin, sino que, haciendo uso de informacin parcial de su comportamiento, realiza todas las comprobaciones necesarias no llevadas a cabo por el analizador sintctico para asegurarse de que el programa pertenece al lenguaje. Otra fase del compilador donde se hace uso parcial de la semntica del lenguaje es en la optimizacin de cdigo, en la que analizando el significado de los programas previamente a su ejecucin, se pueden llevar a cabo transformaciones en los mismos para ganar en eficiencia. 5.2 VERIFICACIN DE TIPOS EN EXPRESIONES

Sistema de Tipos
Reglas de un lenguaje que permiten asignar tipos a las distintas partes de un programa y verificar su correccin. Formado por las definiciones y reglas que permiten comprobar el dominio de un identificador, y en qu contextos puede ser usado. Cada lenguaje tiene un sistema de tipos propio, aunque puede variar de una a otra implementacin. La comprobacin de tipos es parte del anlisis semntico.

Funciones Principales:
Reglas de un lenguaje que permiten asignar tipos a las distintas partes de un programa y verificar su correccin.

PROGRAMACIN DE SISTEMAS Inferencia de tipos: calcular y mantener la informacin sobre los tipos de datos. Verificacin de tipo: asegurar que las partes de un programa tienen sentido segn las reglas de tipo del lenguaje.

La informacin de tipos puede ser esttica o dinmica:


LISP, CAML o Smalltalk utilizan informacin de tipos dinmica. En ADA, Pascal o C la informacin de tipos es esttica. Tambin puede ser una combinacin de ambas formas.

Cuantas ms comprobaciones puedan realizarse en la fase de compilacin, menos tendrn que realizarse durante la ejecucin.
Mayor eficiencia del programa objeto.

Es parte de la comprobacin de tipos:


Conversin de tipos explcita: transformacin del tipo de una expresin con un propsito determinado. Coercin: conversin de tipos que realiza de forma implcita el compilador.

Conversin de tipos explcita: el programador indica el tipo destino:


Funciona como una llamada a funcin: recibe un tipo y devuelve otro.

Conversin de tipos implcita: el compilador convierte automticamente elementos de un tipo en elementos de otro:
La conversin se lleva a cabo en la accin semntica de la regla donde se realiza.

Comprobador de tipos seguro: Durante la compilacin (comprobacin esttica) detecta todos los posibles errores de tipo. Lenguaje fuertemente tipado: Si un fragmento de cdigo compila es que no se van a producir errores de tipo. En la prctica, ningn lenguaje es tan fuertemente tipado que permita una completa comprobacin esttica. Informacin de tipos dinmica: El compilador debe generar cdigo que realice la inferencia y verificacin de tipos durante la ejecucin del programa que se est compilando.

PROGRAMACIN DE SISTEMAS

Informacin de tipos esttica:


Se utiliza para verificar la exactitud del programa antes de la ejecucin. Permite determinar la asignacin de memoria necesaria para cada variable.

Tipo de datos = conjunto de valores + operaciones aplicables En el mbito de los compiladores, un tipo se define mediante una expresin de tipo (informacin de tipos explcita): Nombre de tipo: float. Expresin estructurada explcita: set of integer. Estas expresiones se utilizan en la construccin de otros tipos o para declarar variables.

Tambin es posible incluir informacin de tipos implcita:

La informacin de tipos, implcita o explcita, se mantiene en la tabla de smbolos:


Esta informacin se recupera de la tabla de smbolos mediante el verificador de tipo cuando se hace referencia al nombre asociado.

Ejemplo:

Un lenguaje de programacin contiene un conjunto de tipos predefinido denominados tipos simples:

PROGRAMACIN DE SISTEMAS

Algunos lenguajes permiten definir nuevos tipos simples: enumerado, subrango.

Todos los lenguajes permiten crear nuevos tipos complejos a partir de otros ms simples mediante constructores de tipos: Matrices, productos, registros, punteros, funciones, En Pascal: array, set, record, ... En C++: struct, class, union, ....

Para analizar los diferentes tipos que intervienen dentro de un programa, el compilador debe contar con una estructura interna que le permita manejar cmodamente las expresiones de tipos.

Esta estructura interna:


Debe ser fcilmente manipulable, pues su creacin se realizar conforme se hace la lectura del programa fuente. Debe permitir comparar fcilmente las expresiones asignadas a distintos trozos de cdigo, especialmente a los identificadores de variables..

La forma ms habitual de representacin son los grafos acclicos dirigidos (GADs).


La ventaja de estas representaciones es que ocupan poca memoria y por tanto la comprobacin de equivalencia se efecta con rapidez.

Ejemplos:

PROGRAMACIN DE SISTEMAS

5.3 GRAMTICAS DE ATRIBUTOS Un atributo es cualquier propiedad de una construccin de un lenguaje de programacin. Varan en funcin del tipo de informacin que contienen, su complejidad de clculo y el momento en el que son calculados (en tiempo de compilacin (atributos estticos) o de ejecucin (dinmicos). Ejemplos tpicos son: El nombre de una variable. El tipo de una variable. El mbito de una variable. El valor de una expresin. El nmero de argumentos de una funcin. La posicin en memoria de una variable. Un fragmento de cdigo. Una gramtica con atributos es una generalizacin de las gramticas libres de contexto, denominada definicin dirigida por la sintaxis: Cada smbolo gramatical puede tener asociado un conjunto finito de atributos, que pueden ser de los siguientes tipos: Su valor se calcula en funcin de los atributos de los nodos hijos. Heredados: su valor se calcula en funcin de los atributos de los hermanos y/o del nodo padre.

PROGRAMACIN DE SISTEMAS Cada atributo tomara valores de un dominio. Cada produccin llevara asociadas un conjunto de reglas semnticas. Las relaciones de dependencia entre atributos, establecidas por las reglas semnticas, se representaran mediante el Grafo de Dependencias.

Atributos Heredados Una gramtica con atributos se denomina Gramtica L-Atribuida si cada atributo que se evala cumple una de las siguientes condiciones: Es un atributo sintetizado. Dada una produccin A --> X1, X2XjXn, el atributo heredado asociado a Xj depende nicamente de los atributos de X1,, Xj-1 y/o de atributos heredados asociados al smbolo A.

Atributos Sintetizados En el caso de los smbolos terminales de la gramtica, su atributo no es ms que el lexema asociado al token reconocido por el analizador lxico. Una gramtica con atributos se denomina Gramtica S-Atribuida si todos los atributos son sintetizados. Siempre es posible transformar una Gramtica con Atributos en una Gramtica S-Atribuida. Ejemplos: 1. Atributos SINTETIZADOS y reglas para evaluacin de expresiones aritmticas.

2. Atributos HEREDADOS y reglas para propagacin de tipos.

PROGRAMACIN DE SISTEMAS

5.4 MANEJO DE ERRORES SEMNTICOS Errores semnticos, como operaciones realizadas sobre tipos incompatibles. Entre estos se incluyen los errores relacionados con el uso de la tabla de smbolos, como uso de identificadores no declarados o declaracin doble de un identificador en la misma regin de alcance.

UNIDAD VI GENERACIN DE CDIGO INTERMEDIO 6.1 Lenguajes Intermedios Una estructura de datos que representa el programa fuente durante la traduccin se denomina REPRESENTACION INTERMEDIA o IR. Aunque un rbol sintctico abstracto es una representacin adecuada del cdigo del cdigo fuente, incluso para la generacin de cdigo, no se parece ni remotamente al cdigo objeto. Una representacin intermedia de esta naturaleza que se parece al cdigo objeto se denomina CODIGO INTERMEDIO. El cdigo intermedio puede tomar muchas formas: existen casi tantos estilos de cdigo intermedio como compiladores. Sin embargo, todos representan alguna forma de LINEALIZACION del rbol sintctico, es decir, una representacin del rbol sintctico en forma secuencial. El cdigo intermedio puede ser de muy alto nivel, representar todas las operaciones de manera casi tan abstracta como un rbol sintctico, o parecerse mucho al cdigo objeto.

PROGRAMACIN DE SISTEMAS El cdigo intermedio es particularmente til cuando el objetivo del compilador es producir cdigo muy eficiente, ya que para hacerlo as se requiere una cantidad importante del anlisis de las propiedades del cdigo objeto, y esto e facilita mediante le uso del cdigo intermedio El cdigo intermedio tambin puede ser til al hacer que un compilador sea mas fcilmente redirigidle: si el cdigo intermedio es hasta cierto punto independiente de la maquina objeto, entonces generar cdigo para una maquina objetivo diferente solo requiere volver a escribir el traductor de cdigo intermedio a cdigo objeto y por lo regular esto es mas fcil que volver a escribir todo un generador de cdigo. 6.2 NOTACIONES Las notaciones son una forma especial en la que se pueden expresar una expresin matemtica y puedan ser de 3 formas: infija, prefija y postfija. Los prefijos, Pre - Pos - In se refieren a la posicin relativa del operador con respecto a los dos operandos. Existen varias notaciones para representar expresiones matemticas, que se diferencian en el orden en que se escriben los argumentos (operandos) de los operadores. Las ms relevantes son:

Notacin infija: La notacin habitual. El orden es primer operando, operador, segundo operando. Notacin prefija: El orden es operador, primer operando, segundo operando. Notacin postfija: El orden es primer operando, segundo operando, operador. 6.2.1 NOTACION INFIJA

Es la que se utiliza en la mayora de los casos. Ejemplo: Ir con la mas familiar de todas las notaciones, la infija si yo deseo sumar 5 mas 4; en notacin infija quedara: 5+4 En notacin prefija quedara: +54 En notacin postfija: 54+

PROGRAMACIN DE SISTEMAS

Pero ahora veamos una expresin infija mas complicada como la siguiente: 5+2*(7+8)-(15-2/(20+(5/8))) Ahora escribamos esto en forma prefija: (+ 5 (- (* 2(+ 7 8)) (- 15 (/ 2 (+ 20 (/ 5 8)))))) La formula se ve complicada y surge la natural pregunta: Qu ventaja tiene esto? La principal ventaja es que podemos no hacer uso de las reglas de precedencia. 6.2.2 NOTACION POSTFIJA La notacin postfija es una notacin muy simple en la cual se coloca un operador en el extremo derecho de una expresin, es decir, despus de los operadores, en vez de estar entre ellos. Por ejemplo: x + y x* y en notacin postfija es x y + x y* ya que x y + representa la expresin infija x + y y xy* representa x * y, etc. Por lo regular, la notacin postfija se emplea en maquinas de pilas, ya que puede manejarse con gran facilidad usando una pila. Al analizar una notacin postfija de izq., a der., cada vez que se detecta un operador se mete en la pila. La ocurrencia de un operador con n operadores significa que el n esimo operando estar en la cima de la pila. Despus se sacan los operandos de la pila y se mete el resultado de la operacin. 6.2.3 NOTACION PREFIJA El operador binario aparece justo antes de sus dos operandos: +AB Una gramtica que define una notacin prefija puede ser: <expr_pref> := <letra> | <operador><expr_pref><expr_pref> <letra> := A | B | C | ... | Z <operador> := + | - | * | / Ejemplos en infija y su correspondiente prefija:

PROGRAMACIN DE SISTEMAS

A+(B*C) (A+B)*C

+A*BC *+ABC

6.3 REPRESENTACIN DE CDIGO INTERMEDIO 6.3.1 NOTACIN POLACA La notacin polaca es una manera de definir expresiones en las que el orden en la que aparecern los operadores trae implcita la prioridad. Expresiones sin parntesis Algoritmo:

1. Si es operando, PUSH(VP) Expresiones con parntesis Algoritmo: 2. Si es operador, 2.1 Mientras prioridad(TOP(AUX))>=prioridad(operador) POP(AUX) y PUSH(VP) Ejemplo: 1. Si es2.2 PUSH(AUX) del operador operando, PUSH(VP) 3. Si es es operador, fin de expresion, 2. Si 3.12.1 Mientras prioridad(TOP(AUX))>=prioridad(operador) Mientras AUX no est vaca, POP(AUX) y PUSH(VP) POP(AUX) y PUSH(VP) 2.2 PUSH(AUX) del operador 3. Si es (, PUSH(AUX) una marca 4. Si es ), 4.1 Mientras TOP(AUX) < > marca POP(AUX) y PUSH(VP) 4.2 POP(AUX) para quitar la marca 5. Si es fin de expresion, 5.1 Mientras AUX no est vaca, POP(AUX) y PUSH(VP)

6.3.2 CDIGO P 6.3 REPRESENTACIN DE CDIGO INTERMEDIO 6.3.3 TRIPLES O EN 3 DIRECCIONES La instruccin bsica del cdigo de tres direcciones esta diseada para representar la evaluacin de expresiones aritmticas y tiene la siguiente forma general: X = Y op Z

PROGRAMACIN DE SISTEMAS

Esta instruccin expresa la aplicacin del operador op a los valores de Y y Z, y la asignacin de esta valor para que sea el nuevo valor X. Aqu op puede ser un operador aritmtico como + o o algn otro operador que pueda actuar sobre los valores de X y Y. El nombre cdigo en tres direcciones viene de esta forma de instruccin, ya que por lo general cada uno de los nombres X, Y y Z representan una direccin de memoria. Sin embargo, observen que el uso de la direccin de X difiere del uso de las direcciones de Y y Z, y que por tanto Y como Z pueden representar constante o valores de literales sin direccin de ejecucin. Para ver como las secuencias de cdigo de tres direcciones de esta forma pueden representar el clculo de una expresin, considere la expresin aritmtica. 2*a+(b-3) Con rbol sintctico:

Sin embargo, la forma del cdigo de tres direcciones no basta para representar todas las caractersticas. Por ejemplo, los operadores unitarios, como la negacin requieren de una variacin del cdigo de tres direcciones que contenga solo dos direcciones, tal como t2 = - t1 Si se desea tener capacidad para todas las construcciones de un lenguaje de programacin estndar, ser necesario variar la forma del cdigo de tres direcciones en cada construccin. Si un lenguaje contiene caractersticas poco habituales, puede ser necesario incluso inventar nuevas formas del cdigo de tres direcciones para expresarlas.

PROGRAMACIN DE SISTEMAS Estas son unas de las razones por las que no existe una forma estndar para el cdigo de tres direcciones. 6.3.4 CUDRUPLOS Un cudruplo es una estructura tipo registro con cuatro campos. Por ejemplo:

Por ejemplo la expresin a*b+c*d, para transformarlas a su equivalente en cudruplos, podemos separar en unidades ms pequeas a la expresin. Primero: a*b Segundo: c*d Tercero: Hacer la suma de ambas Ahora pasemos a hacer los cudruplos correspondientes:

Como podemos darnos cuenta, a diferencia de los tripletes, los cudruplos hacen uso de una variable temporal para realizar las expresiones. Los tripletes tienen la ventaja obvia de ser ms consistente, pero ellos dependen de su posicin y hace que la optimizacin presente cambios o eliminacin de cdigo mucho ms complejo.

PROGRAMACIN DE SISTEMAS 6.4 ESQUEMAS DE GENERACIN 6.4.1 EXPRESIONES Toda expresin es una sentencia. El operador de asignacin forma parte de una expresin. Deber comprobarse la validez semntica de la parte izquierda de una asignacin. Asignaciones de expresiones con tipos construidos por el usuario (registros y arrays). Conversiones de Expresiones. Se realizarn implcitamente las conversiones de char a entero y real y las de entero a real. S Conversiones explcitas entre tipos simples, realizadas por el programador mediante un ahormado (cast). Conversiones explcitas de expresiones a tipos definidos por el usuario typedef). Operadores Mnimos Los operadores obligatorios que deber incluir el lenguaje son: Aritmticos: +, -, *, /, resto y menos unario. Comparacin: mayor, mayor o igual, menor, menor o igual, igual y distinto. Lgicos: And, Or y Not. Sentencias de control de flujo. Sentencia condicional IF ELSE. Sentencias iterativas WHILE S Sentencia iterativa FOR Sentencias condicional mltiple CASE. Entrada y Salida. Sentencias de lectura y escritura mltiple por la entrada y salida estndar para todos los tipos primitivos con las instrucciones read y write. Debern permitirse la entrada y salida de mltiples valores (separndolos mediante comas). Escritura de cadenas de caracteres para no tener que estar escribiendo carcter a carcter. Ejemplo: write Escriba un nmero; Tratamiento de archivos binarios que permita: Abrir un archivo para lectura y para escritura. Leer bytes de un archivo. Escribir bytes en un archivo. Cerrar el archivo. Su tratamiento binario implica que la lectura y escritura de valores se realizar a travs de direcciones de memoria (punteros o arrays), indicando en nmero de bytes a leer o escribir (ver las funciones read y write del C) 6.4.2 DECLARACIN DE VARIABLES, CONSTANTES Las constantes de tipos: Constantes de tipo entero. Constantes de tipo carcter. Constantes de tipo real.

PROGRAMACIN DE SISTEMAS Constantes de tipo cadena de caracteres. Declaracin de variables.: Declaracin mltiple de variables, separadas por comas. Declaracin de variables globales simples (carcter, entero y real) y construidas por el usuario (arrays y registros). Declaracin de variables locales simples y construidas por el usuario. S Declaracin de variables locales en cualquier parte del cuerpo de la funcin (no necesariamente al principio de ste). S Definicin de tipos construidos por el usuario (type o typedef). La definicin de estos tipos se realizar siempre con mbito global. Su uso (declaracin de variables) permitir declarar tanto variables locales como globales, de los tipos definidos. F Bloques y declaracin de variables locales a bloques. Ejemplos: ... int i; i=3; { int i; // OK i=4; ... } // i==3 Inicializacin de variables en su definicin. int i=3; float r=12E-3; Declaracin de variables locales a sentencias de control. 6.4.3 ESTATUTO DE ASIGNACIN La forma tpica de las reglas sintcticas que regulan la asignacin de un valor a una variable es la sig: <asignacin> ::=<id> := <exp> | <dereference> := <exp> La primera regla corresponde a la asignacin de valor a una variable ordinaria; la segunda a la asignacin de un valor (una direccin) a un puntero. Dependiendo del lenguaje que se trate, pueden exigirse condiciones semnticas especiales a las variables afectadas por una asignacin a un puntero. 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 expresiones booleanas se componen de los operadores booleanos and, or, not aplicados a variables booleanas o expresiones relacionales. A su vez, las expresiones relacionales son de la forma E1 oprel E2, donde E1 y E2 son expresiones aritmticas y oprel es cualquier operador relacional <, >, <=, >=,....

PROGRAMACIN DE SISTEMAS Consideremos expresiones booleanas generadas por la gramtica:

Uno de los mtodos para traducir expresiones booleanas a cdigo de 3direcciones consiste en codificar numricamente los valores true y false y evaluar una expresin booleana como una expresin aritmtica, siguiendo unas prioridades. A menudo se utiliza 1 para indicar true y 0 para indicar false. Las expresiones booleanas se evalan de manera similar a una expresin aritmtica de izquierda a derecha. Supongamos el ejemplo: a or b and not c. La secuencia de cdigo de 3-direcciones correspondiente es: t1 = a or b t2 = not c t3 = t1 and t2 6.4.4 ESTATUTO CONDICIONAL Pasemos a considerar ahora la traduccin de proposiciones de control if-then, ifthen-else, while-do, generadas por la siguiente gramtica:

Proposicin if-then
Supongamos una sentencia if-then de la forma S if E then S1 _ , ver diagrama de flujo de la figura de abajo. Para generar el cdigo correspondiente a esta proposicin habra que aadir a la funcin genera cdigo () un nuevo caso para la sentencia switch que contemple este tipo de nodo en el rbol sintctico, nodo n_if-then.

PROGRAMACIN DE SISTEMAS

TAC datos; TAC aux1, aux2; lista_codigo *cod; datos.cod=NULL; direcciones dir; // usamos direccin al salto, en vez de etiquetas case n_if-then: // childs [0]=E, childs[1]=S1 aux1=genera_codigo (childs [0]); cod=gen cuad(if_false,--, aux1.lugar, dir?); // an no se sabe la direc. de salto aux2=genera_codigo (childs[1]); dir=sgtedirlibre (); // relleno de retroceso rellena (cod,arg3,dir) datos.cod=concatena_codigo(aux1.cod,cod,aux2.cod); break; Supondremos que tenemos una funcin, sigtedirlibre (), que guarda el ndice de la siguiente instruccin libre (la funcin gen cuad() incrementa ese contador). En la implantacin se ha optado por utilizar direcciones directamente a las instrucciones en vez de usar etiquetas. Proposicin 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

PROGRAMACIN DE SISTEMAS la figura de abajo. Para generar el cdigo correspondiente a esta proposicin habra que aadir a la funcin genera_cdigo () un nuevo caso para la sentencia switch que contemple este tipo de nodo en el rbol sintctico, nodo n_ifthenelse. Este fragmento de cdigo se podra implantar de forma similar a como hemos hecho en la seccin anterior.

Proposicin while-do Una sentencia while - do tiene la forma S while E do S1, cuyo diagrama de flujo viene representado en la figura de abajo. Para generar el cdigo correspondiente a esta proposicin habra que aadir a la funcin genera_cdigo () un nuevo caso para la sentencia switch que contemple este tipo de nodo en el rbol sintctico.

Supondremos que tenemos una funcin, sigtedirlibre (), que guarda el ndice de la siguiente instruccin libre (se asume que la funcin gen_cuad () incrementa ese contador).

PROGRAMACIN DE SISTEMAS

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]= 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 rellena (cod1,arg3,dir2) datos.cod=concatena_codigo(aux1.cod, cod1,aux2.cod, cod2); break; Se ha optado por utilizar direcciones directamente a las instrucciones en vez de etiquetas.

6.4.5 ESTATUTO DE CICLOS Ciclo For Qu decir del for. Es la sentencia ms complicada puesto que hay que ejecutar cada cosa en su debido tiempo y las acciones de la gramtica no se disparan en el orden que nos gustara. Hemos usado una vez ms la pila y cinco etiquetas diferentes a las que vamos saltando y colando tercetos oportunamente. Primeramente hay que ejecutar la inicializacin, generar apilar y emitir una etiqueta que ser a la que se salte en la parte de abajo del for una vez se haya terminado de ejecutar el bloque. Tambin hay que destacar que la actualizacin del for se tiene que producir despus de ejecutar el cuerpo puesto que en l se puede alterar el valor de las variables de control. Como funcionalidad extra, mencionar que permitimos tener mltiples inicializaciones y mltiples actualizaciones al estilo de lo que se puede hacer en C: for(a=0, b=0 ;a<5, b<3; a++, b+=1){}

PROGRAMACIN DE SISTEMAS

Este Cdigo: for(x=1;true;x++) { x=1; break; } [...] generar: 0000.- 0000.0001.- 0001.0002.- 0002.0003.- 0004.0004.- 0003.0005.- 0022.0006.- 0007.* <ASIGN , entero: 1 -> simbolo: x> /* inicializacion */ <ETIQUETA, e_0000> <BRANCH , entero: 1 -> e_0001> /* condicion */ <GOTO , e_0003> /* salto al cuerpo */ <ETIQUETA, e_0002> <PUSHN , 2> /* actualizacion */ <OP , SUM , simbolo: x, entero: 1 -> temporal: 0>

PROGRAMACIN DE SISTEMAS 0007.- 0008.- <ASIGN , temporal: 0 -> simbolo: 0008.- 0023.- <POPN , 2> 0009.- 0012.- * <GOTO , e_0000> 0010.- 0011.- <ETIQUETA, e_0003> 0011.- 0013.- <ETIQUETA, e_0006> 0012.- 0000.- * <ASIGN , entero: 1 -> simbolo: 0013.- 0015.- <GOTO , e_0004> 0014.- 0016.- <ETIQUETA, e_0005> 0015.- 0019.- <GOTO , e_0002> 0016.- 0012.- * <GOTO , e_0000> 0017.- 0017.- <ETIQUETA, e_0007> 0018.- 0018.- <ETIQUETA, e_0004> 0019.- 0020.- <ETIQUETA, e_0001> 6.4.6 ARREGLOS Una referencia de arreglos involucra la subindizacin de una variable de arreglo mediante una expresin para obtener una referencia o valor de un simple elemento, como en el cdigo en c. int a [SIZE]; int i,j; a[i+1] = a [j*2]+3; En esta asignacin la subindizacin de a mediante la expresin i +1 produce una direccin, mientras que la subindizacin de a mediante la expresin j * 2 produce el valor de la direccin calculada del tipo de elemento de a ( a saber , int). Los arreglos son almacenados de manera secuencial en la memoria, cada direccin debe ser calculada desde la direccin base de a y un desplazamiento que depende linealmente del valor del subndice. Cuando se deseara obtener el valor mas que la direccin, se debe generar un paso de indireccin extra para obtener el valor de la direccin calculada. De manera general, la direccin de un elemento de arreglo a [t] en cualquier lenguaje es: direccin _ base(a) + (t- lmite _ inferior (a))* tamao _ elemento(a) Por ejemplo, la direccin de la referencia de un arreglo en C a[i+1] es: a + ( i + 1 ) * sizeof (int) 6.4.7 ESTATUTO FUNCIONES El diseo del manejo de funciones por un compilador implica dar respuesta a las siguientes preguntas: x> /* salto a condicion */ x> /* cuerpo del for */ /* break */ /* salto a actualizacion */

PROGRAMACIN DE SISTEMAS Cmo se comunican los argumentos desde el programa que invoca a la funcin invocada? Cmo se comunican los resultados desde la funcin invocada al programa que invoca?

En general, se utiliza una pila para almacenar las variables locales de la funcin (variables automticas) y los argumentos de llamada a la funcin. En algunos lenguajes, como C y C++, los argumentos se guardan en la pila de orden inverso (de derecha a izquierda). En otros lenguajes se hace al revs. Para pasar el resultado de la funcin al programa que la invoc, se suele utilizar el registro EAX, siempre que dicho resultado quepa en l. De lo contrario se puede utilizar la pila, o bien la memoria esttica. UNIDAD VII OPTIMIZACIN 7.1 TIPOS DE OPTIMIZACIN Objetivo: Mejorar cdigo objeto final, preservando significado del programa.

Factores a Optimizar:
Se

Velocidad de ejecucin Tamao del programa Necesidades de memoria

sigue una aproximacin conservadora No se aplican todas las posibles optimizaciones, solo las seguras CLASIFICACIN DE LAS OPTIMIZACIONES: 1. En funcin de la dependencia de la arquitectura: Dependientes de la mquina: Aprovechan caractersticas especficas de la mquina. Objetivo: Asignacin de registros, uso de modos de direccionamiento Uso instrucciones especiales (IDIOMS) Relleno de pipelines, prediccin de saltos, aprovechamiento de estrategias de memoria cach, etc. Independientes de la mquina: Aplicables en cualquier tipo de mquina. Objetivo: Ejecucin en tiempo de compilacin Eliminacin de redundancias Cambios de orden de ejecucin, etc. 2. En funcin del mbito de aplicacin

PROGRAMACIN DE SISTEMAS

Optimizaciones locales: Aplicadas dentro de un Bloque Bsico. Slo estudian las instrucciones del B.B. actual Optimizaciones globales: Aplicadas a ms de un B.B. Consideran contenido y flujo de datos entre todos o parte de los B.B. Necesidad de recoger info. sobre los B.B. y sus interrelaciones.

7.1.1 LOCALES 1. Ejecucin en tiempo de compilacin. Precalcular expresiones constantes (con constantes o variables cuyo valor no cambia).

i=2+3 j=4 f = j + 2.5 a=b+c d=ad e=b+c f=ad

i=5 j=4 f = 6.5 a=b+c d=a-d e=a f=a-d

2. Reutilizacin de expresiones comunes.

3. Propagacin de copias. Ante instrucciones f = a, sustituir todos los usos de f por a

a=3+i f=a b=f+c d=a+m m=f+d

a=3+i b=a+c d=a+m m=a+d

4. Eliminacin redundancias en acceso matrices. Localizar expresiones comunes en clculo direcciones de matrices Cod. fuente: A: array [1..4, 1..6, 1..8] of integer A[i,j,5] := A[i,j,6] + A[i,j,4] Sin optimizacin: direc(A[i,j,5]) = direc(A[1,1,1]) + (i-1)*6*8 + (j-1)*8 + (5-1) direc(A[i,j,6]) = direc(A[1,1,1]) + (i-1)*6*8 + (j-1)*8 + (6-1) direc(A[i,j,4]) = direc(A[1,1,1]) + (i-1)*6*8 + (j-1)*8 + (4-1)

PROGRAMACIN DE SISTEMAS Con optimizacin: k := direc(A[1,1,1]) + (i-1)*6*8 + (j-1)*8 + (5-1) direc(A[i,j,5]) = k + 4 direc(A[i,j,6]) = k + 5 direc(A[i,j,4]) = k + 3 5. Transformaciones algebraicas: Aplicar propiedades matemticas para simplificar expresiones a) Eliminacin secuencias nulas

x+0 1*x x/1

x x x

b) Reduccin de potencia. Reemplazar una operacin por otra equivalente menos costosa.

x2 x*x 2*x x + x (suma); x<<1 (despl. izq.) 4*x, 8*x,... x<<2, x<<3,... x / 2 x>>2
c) Reacondicionamiento de operadores. Cambiar orden de evaluacin aplicando propiedades conmutativa, asociativa y distributiva.

A := B*C*(D + E) A := (D + E)*B*C MOV B,R0 MUL C,R0 MOV D,R0 MOV Ro, t1 ADD E,R0 5 instrucciones MOV D,R0 MUL B,R0 0 temporales ADD E, R0 MUL C,R0 MUL t1,R0 MOV R0,A MOV R0,A
7.1.2 BUCLES Los bucles son una parte del cdigo muy propensa a la ineficiencia. Su naturaleza multiplica la diferencia de rendimiento entre dos versiones de cdigo equivalentes, que fuera de un bucle presentaran una mejora significativa. Por esta razn es importante generar el cdigo de manera cuidadosa, para introducir en los cuerpos de los bucles slo lo que sea estrictamente necesario, en versiones que minimicen el costo para la maquina. El primer enfoque indica los invariantes del bucle; el segundo se llama reduccin de fuerza. Una operacin es

PROGRAMACIN DE SISTEMAS invariante respecto a un bucle si ninguno de los operndos de los que depende cambia de valor durante la ejecucin del bucle. La optimizacin consiste en sacar la operacin fuera del bucle. Para estudiar la reduccin de fuerza, ser conveniente considerar un ejemplo previo. Considere el siguiente bucle, escrito en lenguaje C: For (i=a; i<c; i+=b) {d=i*k;} Se supone que: b y k no se modifican dentro del cuerpo del bucle. i, variable del bucle, solo se modifica para incrementarla. La nica modificacin del valor de la variable d dentro del cuerpo del bucle es la que se muestra. Se puede comprobar que los valores que toma la variable d son los siguientes: a*k (a + b) * k (a + 2 * b) * k Es posible obtener una versin equivalente del bucle, que realice menos trabajo en cada iteracin, reduciendo el calculo del valor siguiente de la variable d a un incremento, que se le sumar como si se tratase de una variable del bucle (como la variable i ):

d = a * k; t1 = b * k; for (i=a; i<c; i+=b, d+=t1) {}


Obsrvese: La aparicin de una nueva variable (t1), que se hace cargo de parte del calculo del valor de d. La conversin de d en una variable del bucle, que en lugar de calcularse por completo en el cuerpo del bucle simplemente se incrementa. Que los valores que recibe la variable d en cada ejecucin del bucle coinciden con los indicados anteriormente. La optimizacin consiste en que el clculo que se repite dentro del bucles es una suma, en lugar de un producto, y los productos suelen ser mas costosos para el sistema. 7.1.3 GLOBALES Optimizaciones entre Bloques Bsicos Optimizaciones tpicas: Identificacin de expresiones comunes entre bloques Optimizacin de llamadas a procedimientos

PROGRAMACIN DE SISTEMAS Optimizacin de bucles

Optimizacin Llamadas a Procedimientos: Llamadas a procedimientos son muy costosas Cambios del mbito de referencias Gestin de Registros de Activacin Paso de parmetros + asignacin de datos locales Mejoras 1. Optimizar manejo de Registro de Activacin Minimizar copia de parmetros y n. registros a salvar Uso almacenamiento esttico si no hay llamadas recursivas 2. Expansin en lnea. Idea: Eliminar llamadas a procedimientos copiando el cuerpo del procedimiento en el lugar donde es llamado. Evita sobrecarga asociada con llamadas a procedimientos. Permite optimizaciones adicionales. El cdigo llamado pasa a ser parte del cdigo que lo llama

Limitaciones: Aumenta uso de memoria til en procedimientos pequeos y llamados desde pocos lugares. Si se llama en un nico lugar (es frecuente), no supone costo de espacio adicional No aplicable en procedimientos recursivos Ejemplos: Directiva inline en C++ y Java En C puede simularse con macros #define 7.1.4 DE MIRILLA Aplicable en cdigo intermedio o cdigo objeto. Constituye una nueva fase aislada. Idea Bsica: Se recorre el cdigo buscando combinaciones de instrucciones que puedan ser reemplazadas por otras equivalentes ms eficientes. Se utiliza una ventana de n instrucciones y un conjunto de patrones de transformacin (patrn, secuencias reemplazan). Si las instrucciones de la ventana encajan con algn patrn se reemplazan por la secuencia de emplazamiento asociada.

PROGRAMACIN DE SISTEMAS Las nuevas instrucciones optimizaciones son reconsideradas para las futuras

Ejemplos: Eliminacin de cargas innecesarias

Reduccin de potencia Eliminacin de cadenas de saltos

7.2 COSTOS 7.2.1 COSTOS DE EJECUCION Un generador de cdigo no solo debera buscar opciones innecesarias, sino que debera tomar ventaja de las oportunidades para reducir el costo de las operaciones que son necesarias, pero que se pueden implementar de maneras mas econmicas que lo que puede indicar el cdigo fuente o una implementacin simple. Un ejemplo tpico de esto es el reemplazo de las operaciones aritmticas por operaciones mas econmicas. Por ejemplo, la multiplicacin por 2 puede implementarse como una operacin de desplazamiento, y una potencia entera pequea, tal como x3, puede implementarse como una multiplicacin, tal como x*x*x. Esta optimizacin se conoce como reduccin de potencia. Una operacin que en ocasiones puede ser relativamente costosa es la llamada de procedimientos, donde se deben realizar muchas operaciones de secuencia de llamada. Los procesadores modernos han reducido este costo de manera sustancia, ofreciendo apoyo a hardware para secuencias de llamada estndar, pero la eliminacin de llamadas frecuentes a procedimientos pequeos an puede producir aumentos de velocidad mensurables. Durante la generacin de cdigo final se pueden encontrar algunas ltimas oportunidades para reducir el costo de ciertas operaciones utilizando instrucciones especiales disponibles en la maquina objetivo. 7.2.2 CRITERIOS PARA MEJORAR EL CODIGO

PROGRAMACIN DE SISTEMAS

Existen tantas y diversas tcnicas de optimizacin de cdigo que solo podemos dar una pequea visin fugaz de las mas importantes y las mas ampliamente utilizadas. Al juzgar si la implementacin de una tcnica de optimizacin en particular es demasiada compleja respecto a sus resultados en la mejora real del cdigo, es importante determinar no solo la complejidad de la implementacin en trminos de las estructuras de datos y cdigo de compilador extra, sino tambin es el efecto que el paso de optimizacin pueda tener sobre la velocidad de ejecucin del compilador mismo. Dentro de los criterios para mejorar nuestro cdigo tenemos: Asignacin de Registro.- El buen uso de los registros es la caracterstica ms importante de cdigo eficiente. Operaciones Innecesarias.- La segunda fuente principal de mejoramiento de cdigo es el evitar la generacin de cdigo para las operaciones que sean redundantes o innecesarias. Operaciones Costosas.- Un generado de cdigo no slo debera buscar operaciones innecesarias, sino que debera tomar ventaja de las oportunidades para reducir el costo de operaciones que son necesarias, pero que se pueden implementar de maneras ms econmicas que lo que puede indicar el cdigo fuente o una implementacin simple.

UNIDAD VIII GENERACION DE CODIGO OBJETO 8.1 LENGUAJE MAQUINA Es un conjunto de instrucciones restringido y sencillo, que puede ser interpretado y ejecutado directamente por el computador. Que estudia el Nivel del Lenguaje Maquina? Registros Programables que hay en la CPU Numero de Registros Tamao Utilidad de cada uno Memoria Principal Cantidad de memoria principal que se puede direccionar (n de palabras)

PROGRAMACIN DE SISTEMAS Longitud de palabra Unidad mnima redireccionable

Instrucciones maquinas Tipos de instrucciones maquinas Repertorio o conjunto de instrucciones Formato de las instrucciones --Cdigo de operacin --Direccionamiento Modos de direccionamiento 8.1.1 CARACTERSTICAS Las instrucciones se almacenan y tratan en el computador como cadenas de unos y ceros, aunque se representen en hexadecimal o mediante nemotcnicos. Las instrucciones maquinan suelen, en general, cumplir las siguientes propiedades: 1.- Realizan funcin: una nica y sencilla

Su interpretacin sencilla

es

2.- Emplean un numero fijo de operndoos, que podrn ser implcitos o estar representados explcitamente en la instruccin. 3.- La codificacin de las instrucciones es bastante sistemtica.

Para que su codificacin sea sencilla 4.- Las instrucciones son autocontenidas e independientes. Contiene toda la informacin necesaria para Autocontenidas ejecutarse No requieren informacin de otras instrucciones Independientes Su interpretacin es independiente de la posicin que ocupan en el programa o en la memoria. 8.1.2 MODOS DE DIRECCIONAMIENTO

PROGRAMACIN DE SISTEMAS La denominacin de modos de direccionamiento proviene que normalmente se especifica la direccin donde se encuentra el dato o la instruccin.

Son las diversas formas de determinar el valor de un operando o la posicin de un operando o una instruccin.
OBJETO Instruccin, operando o resultado que se desea direccionar.

La propia instruccin Puede residir en Un registro En la memoria principal Cuando se utiliza una posicin de memoria, la direccin real de memoria especificada por el modo de direccionamiento se denomina DIRECCION EFECTIVA (EA, Effective Addres). El modo de direccionamiento esta codificado en algn/algunos campos de la instruccin. TIPOS DE DIRECCIONAMIENTO

Direccionamiento Implcito Direccionamiento Inmediato A registro (Direccionamiento Registro) Direccionamiento Directo A memoria (Direccionamiento Directo o Absoluto A travs de registro Direccionamiento Indirecto A travs memoria

A Registro Base A Registro ndice Direccionamiento Relativo

Preautoincremento Preautodecremento Postautoincremento Postautodecremento

Indexado Respecto a Base Al contador del Programa A Pila

PROGRAMACIN DE SISTEMAS

8.2 LENGUAJE ENSAMBLADOR La comunicacin en lenguaje de mquina es particular de cada procesador que se usa, y programar en este lenguaje es muy difcil y tedioso, por lo que se empez a buscar mejores medios de comunicacin con sta. A principios de la dcada de 1950, y con el fin de facilitar la labor de los programadores, se desarrollaron cdigos mnemotcnicos para las operaciones y direcciones simblicas. Uno de los primeros pasos para mejorar el proceso de preparacin de programas fue sustituir los cdigos de operacin numricos del lenguaje de mquina por smbolos alfabticos, que conforman un lenguaje mnemotcnico. Todas las computadoras actuales tienen cdigos mnemotcnicos aunque, naturalmente, los smbolos que se usan varan en las diferentes marcas y modelos. La computadora sigue utilizando el lenguaje de mquina para procesar los datos, pero los programas ensambladores traducen antes los smbolos de cdigo de operacin especificados a sus equivalentes en lenguaje de mquina. Los lenguajes ensambladores tienen ventajas sobre los lenguajes de mquina. Ahorran tiempo y requieren menos atencin a detalles. Se incurren en menos errores y los que se cometen son ms fciles de localizar. Adems, los programas en lenguaje ensamblador son ms fciles de modificar que los programas en lenguaje de mquina. Pero existen limitaciones. La codificacin en lenguaje ensamblador es todava un proceso lento. Adems, una desventaja importante de estos lenguajes es que tienen una orientacin a la mquina. Es decir, estn diseados para la marca y modelo especfico de procesador que se utiliza. En el principio de la computacin este era el lenguaje que tena que "hablar" el ser humano con la computadora y consista en insertar en un tablero miles de conexiones y alambres y encender y apagar interruptores. Aunque en la actualidad ya no se emplea, es importante reconocer que ya no es necesario que nos comuniquemos en este lenguaje de "unos" y "ceros", pero es el que internamente una computadora reconoce o "habla". 8.2.1 CARACTERISTICAS Dentro de las caractersticas ms primordiales que encontramos en el Lenguaje Ensamblador tenemos las siguientes las cuales se pueden tomar como ventajas respecto a los lenguajes de alto nivel:

PROGRAMACIN DE SISTEMAS Velocidad Eficiencia de tamao Flexibilidad

Velocidad: El proceso de traduccin que realizan los intrpretes, implica un proceso de cmputo adicional al que el programador quiere realizar. Por ello, nos encontraremos con que un intrprete es siempre ms lento que realizar la misma accin en Lenguaje Ensamblador, simplemente porque tiene el costo adicional de estar traduciendo el programa, cada vez que lo ejecutamos. De ah nacieron los compiladores, que son mucho ms rpidos que los intrpretes, pues hacen la traduccin una vez y dejan el cdigo objeto, que ya es Lenguaje de Mquina, y se puede ejecutar muy rpidamente. Aunque el proceso de traduccin es ms complejo y costoso que el de ensamblar un programa, normalmente podemos despreciarlo, contra las ventajas de codificar el programa ms rpidamente. Sin embargo, la mayor parte de las veces, el cdigo generado por un compilador es menos eficiente que el cdigo equivalente que un programador escribira. La razn es que el compilador no tiene tanta inteligencia, y requiere ser capaz de crear cdigo genrico, que sirva tanto para un programa como para otro; en cambio, un programador humano puede aprovechar las caractersticas especficas del problema, reduciendo la generalidad pero al mismo tiempo, no desperdicia ninguna instruccin, no hace ningn proceso que no sea necesario. Para darnos una idea, en una PC, y suponiendo que todos son buenos programadores, un programa para ordenar una lista tardar cerca de 20 veces ms en Visual Basic (un intrprete), y 2 veces ms en C (un compilador), que el equivalente en Ensamblador. Por ello, cuando es crtica la velocidad del programa, Ensamblador se vuelve un candidato lgico como lenguaje. Ahora bien, esto no es un absoluto; un programa bien hecho en C puede ser muchas veces ms rpido que un programa mal hecho en Ensamblador; sigue siendo sumamente importante la eleccin apropiada de algoritmos y estructuras de datos. Por ello, se recomienda buscar optimizar primero estos aspectos, en el lenguaje que se desee, y solamente usar Ensamblador cuando se requiere ms optimizacin y no se puede lograr por estos medios. Eficiencia de Tamao: Por las mismas razones que vimos en el aspecto de velocidad, los compiladores e intrpretes generan ms cdigo mquina del necesario; por ello, el programa ejecutable crece. As, cuando es importante reducir el tamao del ejecutable, mejorando el uso de la memoria y teniendo tambin beneficios en velocidad, puede convenir usar el lenguaje Ensamblador. Entre los programas que es crtico el uso mnimo de memoria, tenemos a los virus y manejadores de dispositivos (drivers). Muchos de ellos, por supuesto, estn escritos en lenguaje Ensamblador. Flexibilidad: Las razones anteriores son cuestin de grado: podemos hacer las cosas en otro lenguaje, pero queremos hacerlas ms eficientemente. Pero todos los

PROGRAMACIN DE SISTEMAS lenguajes de alto nivel tienen limitantes en el control; al hacer abstracciones, limitan su propia capacidad. Es decir, existen tareas que la mquina puede hacer, pero que un lenguaje de alto nivel no permite. Por ejemplo, en Visual Basic no es posible cambiar la resolucin del monitor a medio programa; es una limitante, impuesta por la abstraccin del GUI Windows. En cambio, en ensamblador es sumamente sencillo, pues tenemos el acceso directo al hardware del monitor. Resumiendo, la flexibilidad consiste en reconocer el hecho de que Todo lo que puede hacerse con una mquina, puede hacerse en el lenguaje ensamblador de esta mquina; los lenguajes de alto nivel tienen en una u otra forma limitante para explotar al mximo los recursos de la mquina.

Por otro lado, al ser un lenguaje ms primitivo, el Ensamblador tiene ciertas desventajas respecto a los lenguajes de alto nivel: Tiempo de programacin Programas fuente grandes Peligro de afectar recursos inesperadamente Falta de portabilidad

Tiempo de Programacin: Al ser de bajo nivel, el Lenguaje Ensamblador requiere ms instrucciones para realizar el mismo proceso, en comparacin con un lenguaje de alto nivel. Por otro lado, requiere de ms cuidado por parte del programador, pues es propenso a que los errores de lgica se reflejen ms fuertemente en la ejecucin. Por todo esto, es ms lento el desarrollo de programas comparables en Lenguaje Ensamblador que en un lenguaje de alto nivel, pues el programador goza de una menor abstraccin. Programas Fuentes Grandes: Por las mismas razones que aumenta el tiempo, crecen los programas fuentes; simplemente, requerimos ms instrucciones primitivas para describir procesos equivalentes. Esto es una desventaja porque dificulta el mantenimiento de los programas, y nuevamente reduce la productividad de los programadores. Peligro de afectar recursos Inesperadamente: Tenemos la ventaja de que todo lo que se puede hacer en la mquina, se puede hacer con el Lenguaje Ensamblador (flexibilidad). El problema es que todo error que podamos cometer, o todo riesgo que podamos tener, podemos tenerlo tambin en este Lenguaje. Dicho de otra forma, tener mucho poder es til pero tambin es peligroso. En la vida prctica, afortunadamente no ocurre mucho; sin embargo, al programar en este lenguaje vern que es mucho ms comn que la mquina se "cuelgue", "bloquee" o "se le vaya el avin"; y que se reinicialize. Por qu?, porque con este lenguaje es perfectamente posible (y sencillo) realizar secuencias de instrucciones invlidas, que normalmente no aparecen al usar un lenguaje de alto nivel.

PROGRAMACIN DE SISTEMAS En ciertos casos extremos, puede llegarse a sobrescribir informacin del CMOS de la mquina (no he visto efectos ms riesgosos); pero, si no la conservamos, esto puede causar que dejemos de "ver" el disco duro, junto con toda su informacin. Falta de Portabilidad: Como ya se mencion, existe un lenguaje ensamblador para cada mquina; por ello, evidentemente no es una seleccin apropiada de lenguaje cuando deseamos codificar en una mquina y luego llevar los programas a otros sistemas operativos o modelos de computadoras. Si bien esto es un problema general a todos los lenguajes, es mucho ms notorio en ensamblador: yo puedo reutilizar un 90% o ms del cdigo que desarrollo en "C", en una PC, al llevarlo a una RS/6000 con UNIX, y lo mismo si despus lo llevo a una Macintosh, siempre y cuando est bien hecho y siga los estndares de "C", y los principios de la programacin estructurada. En cambio, si escribimos el programa en Ensamblador de la PC, por bien que lo desarrollemos y muchos estndares que sigamos, tendremos prcticamente que reescribir el 100 % del cdigo al llevarlo a UNIX, y otra vez lo mismo al llevarlo a Mac.

8.2.2 ALMACENAMIENTO Dentro del almacenamiento que maneja el lenguaje ensamblador se tiene que este tiene una relacin con los componentes internos del procesador: En la memoria: En donde se almacena la informacin en celdas especiales llamados registros los cuales tienen un nivel alto y un nivel bajo. Unidad aritmtica y lgica: Es la responsable de realizar como su nombre lo indica operaciones aritmticas y lgicas. Unidad de control: Se encarga de coordinar que los otros componentes ejecuten las operaciones correctamente. Bus interno: Son los canales por donde pasa la informacin que la mquina va a procesar (bus de entrada) o procesada (bus de salida). Manejo de la Memoria: Direccionamiento (Interno y Externo) El manejo de la memoria depende de que procesador tenga la mquina, entre los cuales a continuacin se mencionan los siguientes: Memoria de Programa Memoria Externa de Datos

PROGRAMACIN DE SISTEMAS Memoria Interna de Datos Registros de Funciones Especiales Memoria de Bit

El espacio de la Memoria de Programa contiene todas las instrucciones, datos, tablas y cadenas de caracteres (strings) usadas en los programas. Esta memoria se direcciona principalmente usando el registro de 16 bits llamado Data Pointer. El tamao mximo de la Memoria de Programa es de 64 Kbytes. La Memoria Externa de Datos contiene todas las variables y estructuras de datos que no caben en la memoria interna del Microprocesador. Esta memoria se direcciona principalmente por el registro de 16 bits Data Pointer , aunque tambin se puede direccionar un banco de Memoria Externa de Datos de 256 bytes usando los dos primeros registros de propsito general. El espacio de Memoria Interna de Datos funcionalmente es la memoria de datos ms importante, ya que ah es donde residen cuatro bancos de registros

de propsito general; la pila o stack del programa; 128 bits de los 256 bits de un rea de memoria direccionable por bit y todas las variables y estructuras de datos operadas directamente por el programa. El tamao mximo de la Memoria Interna de Datos es de 256 bytes. Contiene un espacio para los denominados Registros de Funciones Especiales destinado para los puertos de entrada/salida, temporizadores y puerto serie del circuito integrado. Estos registros incluyen al Stack Pointer; al registro de la palabra de estado del programa y al Acumulador. La cantidad mxima de Registros de Funciones Especiales es 128. Todos los Registros de Funciones Especiales tienen direcciones mayores a 127 y se ubican en los 128 bytes superiores de la Memoria Interna de Datos. Estas dos reas de la Memoria Interna de Datos se diferencian por el modo de direccionamiento usado para accesarlas. Los Registros de Funciones Especiales solo se pueden accesar usando el modo de direccionamiento Directo, mientras que los 128 bytes superiores solo se pueden accesar con el modo de direccionamiento Indirecto. Por otra parte, el espacio de Memoria de Bit se usa para almacenar variables y banderas de un bit. El tamao mximo de la Memoria de Bit es de 256 bits, 128 de los bits comparten su espacio con 16 bytes del espacio de la Memoria Interna de Datos y los otros 128 bits lo hacen con los Registros de Funciones Especiales. 8.3 OTROS LENGUAJES PARA VIRTUAL MACH (JVM) Los lenguajes basados en una mquina virtual, comnmente son ms rpidos que los totalmente interpretados, debido a que utilizan una arquitectura de cdigo intermedio. La idea es dividir la tarea de ejecutar un programa en dos partes. En la primera, se realiza el anlisis lxico y sintctico del programa

PROGRAMACIN DE SISTEMAS fuente, para generar el programa en instrucciones del procesador virtual (cdigo intermedio) y en el segundo paso, se itera sobre el cdigo intermedio para obtener la ejecucin final del programa. Los lenguajes compilados de cdigo intermedio, pueden llegar a ser un orden de magnitud ms rpido que los lenguajes completamente interpretados, pero, por consiguiente, un orden de magnitud ms lentos que lenguajes optimizados como C o C++.

S-ar putea să vă placă și