19/09/2013 UNIDAD I.- ANALISIS SEMANTICO 1.1.- Arboles de expresiones. 1.2.- Acciones semánti cas de un analizador sintáctico. 1.3.- Comprobaciones de tipos en expresiones . 1. 4.- Pila semántica en un analizador sintáctico. 1.5.- Esquema de traducción. 1.6.- Gen eración de la tabla de símbolo y de direcciones. 1.7.- Manejo de errores semánticos. 2 MATERIA: LENGUAJES Y AUTÓMATAS II Dra. Miriam Martínez Arroyo Introducción · El lenguaje es un vehículo por el cual se transmiten instrucciones a un procesador para que las ejecute y produzca ciertos resultados. · Es tarea del compilador ext raer el contenido semántico incluido en las sentencias del programa. · Ciertos aspec tos relativos a la corrección de un programa no se pueden expresar claramente medi ante el lenguaje de programación. · Es necesario dotar al compilador de rutinas auxi liares para captar todo lo que no se ha expresado mediante la sintaxis del lengu aje. 4 INTRODUCCIÓN 3 El compilador hasta ahora · Análisis léxico · Detecta entradas de tokens legales 5 Introducción · Semántica: conjunto de reglas que espe significado de cualquier sentencia sintáctica mente correcta y escrita en un determinado lenguaje. · El análisis semántico, a difere ncia de otras no se realiza claramente diferenciado del resto de las tareas del compilador. · ± Fase en la que se obtiene información necesaria para la compilación, tras conocer la estructura sintáctica del programa. · ± Completa las fases de análisis léxico y sintáctico incorporando comprobaciones que no pueden asimilarse al mero reconocimiento de u na cadena dentro de un lenguaje 6 · Análisis Sintáctico · Detecta entradas con árboles mal formados. · Análisis Semántico · Detecta todos los errores restantes 1
19/09/2013 Objetivo del análisis semántico · La semántica del lenguaje forma parte de la especificación del mismo. Normalmente la semántica de un lenguaje se describe de manera informal. · El objetivo del análisis s emántico es comprobar si la semántica del programa que se está compilando cumple las e specificaciones de la semántica del lenguaje fuente. 7 Objetivo del análisis semántico Algunas de estas comprobaciones son: · Para realizar el análisis semántico se utilizan gramáticas de atributos, que básicamente, son gramáticas independientes del contexto en las que los símbolos tienen asignados atributos o valores semánticos. Hay dos tip os de atributos: · sintetizados: corresponden al no terminal de la parte izquierda de una regla. Se calculan a partir de los atributos de los símbolos de la parte derecha de la regl a. · heredados: corresponden a los símbolos de la parte derecha de la regla. Se cons truyen a partir de los atributos de los símbolos de ambas partes de la regla. 8 Por qué necesitamos el análisis semántico 9 ¿Qué hace el análisis semántico? · Verificaciones de varias clases, típicamente: · Que todos los identificadores estén declarados. · Los tipos de las expresiones y la compatibilidad de las asignaciones. · Invocación de métodos compatibles con las declar aciones · etc ¼ · Los requerimientos dependes del lenguaje. 10 · El analizador sintáctico no puede detectar todos los errores. s del lenguaje no son libres de contexto · Ejemplo: declaración de identificadores y su uso. · No puedes describir que alguna palabra particulares aparezca dos veces en ada por un texto en medio. · Una versión abstracta del problema * } declaración uso
· Algunos constructore utilizar una GLC para una cadena separ es: {wcw | w (a | b)
· Se asocia información a las construcciones del lenguaje de programación proporcionan do atributos a los símbolos de la gramática. Ejemplo: · el valor de una expresión, · el ti po de una variable, · su ámbito, · un trozo de código, · el número de argumentos de una func ión, · etc. Los valores de los atributos se calculan mediante reglas semánticas asocia das a las producciones gramaticales. El análisis semántico incluye: 11 · La construcción de la Tabla de Símbolos para llevar un seguimiento del significado d e los identificadores en el programa: · · · · · · · variables, funciones, tipos, parámetros y métodos de paso de parámetros en func Etc. 12 · Realizar la comprobación e inferencia de tipos en expresiones y sentencias. Por ej
emplo: · · · · · que ambos lados de una asignación tengan tipos adecuados, que no se declaren varia bles con el mismo nombre, que los parámetros de llamada a una función tengan tipos a decuados, número de parámetros correcto, Etc. 2
19/09/2013 1.1.-ARBOL DE EXPRESIONES 14 1.1.- Arboles de expresiones. 13 Las expresiones regulares que se pueden representar a través de los símbolos conteni dos en un alfabeto, también se pueden representar a través de árboles, que se denomina n árboles de expresiones. La información contenida en los árboles de expresio-nes tien en las siguientes características. Se almacena en forma de estructura jerárquica, po rque los componentes están en diferentes niveles. La información se almacena en forma Dinámica porque su forma, tamaño y contenido puede n variar durante la ejecución. Los datos son almacenados de forma Organizada porqu e importa la forma en que está dispuesto el contenido. La consulta de los datos se hace de manera rápida y eficiente obteniendo mejores resultados. 15 Propiedades de los árboles Los árboles de expresiones están compuestos por los siguien tes elementos: Token.- es una Unidad mínima de información entendible por un compila dor. Puede ser un ope-rando o un operador. Operandos.- Los operandos pueden ser las hojas de los nodos. Raíz.- La raíz de un árbol puede ser cuaquier operador aritmétic o. 16 Reglas para un árbol La reglas para representar una expresión mediante un árbol son la s siguientes: 17 Árboles de expresión Representan un orden de ejecución 18 + para la expresión siguiente: 1.- Cada hoja está etiquetada con un operando y solo consta de ese operando. 2.- C ada nodo interior ªnº está etiquetado con un solo operador. 3.- Las hojas están represen tadas por los operandos y los nodos por la raíz de cada árbol. (A* B) + C * D + E A * B C + * D E
3
19/09/2013 Otro ejemplo de árbol sintáctico para una expresión Aritmética: (7 + 12) * (-9) -171 19 20 * + 7 12 9 21 Ejemplo: x=(x+y)*(a-b) 22 23 24 4
19/09/2013 25 26 27 28 29 30 5
19/09/2013 31 32 http://www.esdebian.org/wiki/interpretprete-funciones-mediante-arbol-binario-exp resiones 33 34 35 36 6
19/09/2013 37 38 1.2. Acciones Semánticas de un Analizador Sintáctico Dependiendo del tipo de sentencias, semánticas pueden agruparse en: las acciones 40 1.2. Acciones Semánticas de un Analizador Sintáctico 39 · Sentencias de Declaración: Se utilizan para completar la sección de tipos de la Tabl a de Símbolos. · Sentencias ªejecutablesº: Se utilizan para realizar comprobaciones de t ipos entre los operandos implicados. Algunas de estas comprobaciones son: · comprobación de tipos en sentencias de asigna ción · comprobación de tipos en operaciones aritmético-lógicas · comprobación de tipos en las sentencias condicionales · comprobación de la declaración de las variables antes de su uso · comprobación de unicidad de identificadores · comprobación del indexado de vector es Continuación¼ 41 · Funciones y procedimientos: Se utilizan para comprobar el número, orden y tipo de los parámetros actuales en cada llamada a una función o procedimiento. · Identificación de variables: Se utilizan para comprobar si un identificador ha sido declarado a ntes de utilizarlo. · Etiquetas: comprobar si hay etiquetas repetidas y validación. 42 7
19/09/2013 Continuación¼ · Constantes: comprobar que no se utilicen en la parte izquierda de una asignación. · Conversiones y equivalencias de tipo: realizan la verificación de las co nstantes para que éstas sean de un mismo tipo. · Sobrecarga de operadores y funcione s: en las funciones y los procedimientos, se utilizan para detectar y solventar la autenticidad de los datos. 43 Ámbitos · Consiste en empatar las declaraciones de identificadores con su uso · El ámbito de u n identificador es la porción del programa en la cual el identificador es accesibl e. · El mismo identificador se puede referir a diferentes cosas en diferentes part es del programa. · Ámbitos diferentes para el mismo nombre no se sobreponen. · Un iden tificador puede tener ámbitos restringidos. · Es decir solo es visible en áreas partic ulares del programa 44 Ámbitos estáticos vs dinámicos · La mayoría de los lenguajes tienen ámbitos estáticos. · El ámbito sólo depende del texto del programa no de la conducta en tiempo de ejecución . · Java, C, C++, Pascal, Modula, cool, etc. Tienen ámbito estático. 45 Ejemplo de ámbito estático int x; -- variable global o campo estático float convert_speed(float y) { float x; --una x diferente (variable local) x=y*1.6 return x; } (El uso de x se refiere a la definición más cercana ) 46 · Pocos lenguajes tiene ámbitos dinámicos · Lisp, SNOBOL · El ámbito depende de la ejecución del programa Ámbito en lenguajes OO · No todas las clases de identificadores siguen la regla del anidamiento más cercano · Por ejemplo las definiciones de clases · Todas son visibles globalmente 47 Más sobre ámbito · Los nombres de métodos y atributos tienen reglas complejas. · Los nombres de campos son globales dentro de cualquier clase. · Pero los métodos y campos no necesitan est ar definidos en la clase en la cual se están utilizando, pero si en una clase padr e (herencia) · Los métodos se pueden redefinir (sobreescritura) 48 · Declaración de campos en Java · Visibles a todos los métodos en una clase · Y algunas veces a otras clases también · Dependiendo si son públicas o privadas, etc. 8
19/09/2013 Implementación de la regla anidada más cercana · La mayor parte del análisis semántico se puede expresar como un recorrido descendent e recursivo de un árbol o AST. · Procesa un nodo n · Procesa los hijos de n · Finaliza procesando el nodo n 49 1.3.- Comprobaciones de Tipos en Expresiones 50 · En cualquier porción del árbol (contexto en el programa), necesitamos saber que iden tificadores están definidos. 1.3.-Comprobación de tipos en Expresiones · La comprobación de tipos es una forma de a segurar que los identificadores relacionados sean de tipos compatibles. · Dos iden tificadores son compatibles de acuerdo a lo siguiente: · Cuando forman el lado izquierdo y el lado derecho de un operador. · Cuando forman el lado izquierdo y el lado derecho de una proposición de asignación. · Cuando sean pa rámetros reales y formales. 51 Las comprobaciones de consistencia que se efectúan antes de la ejecución del program a fuente, se denominan comprobaciones estáticas. Las comprobaciones que se realiza n durante la ejecución del programa objeto se denominan comprobaciones dinámicas. · La revisión de la sintaxis de un programa fuente es un ejemplo de comprobación estática, · mientras que la comprobación de tipos, es un ejemplo de comprobación que con frecue ncia puede efectuarse en forma estática y que en ocasiones debe realizarse dinámicam ente. 52 Tipos · ¿Qué es un tipo? · La noción varía de lenguaje a lenguaje. 53 Tipos y operaciones · Ciertas Operaciones son legales para cada tipo · No tiene sentido sumar un apuntador a función y un entero en C · Tiene sentido sumar dos enteros · Pero ambos tienen la misma implementación en lenguaje ensamblador! 54 · Consenso · Un conjunto de valores · Un conjunto de operadores sobre los valores · Las clases son una instanciación moderna de la noción de tipo 9
19/09/2013 Sistema de tipos · Un sistema de tipos de un lenguaje especifica las operaciones que son válidas para cada tipo. · La meta de la verificación de tipos es asegurar que las operaciones se utilizan con los tipos correctos. · Hace cumplir la interpretación de los valores. · Algunas veces puede realizar conver siones automáticas cuando el lenguaje permite modos mezclados y promoción de tipos. 55 Traslación dirigida por la sintaxis · La mayoría de los compiladores son de múltiples pasadas. · Recorre el AST (árbol de anális is sintáctico) para el análisis semántico, verificación de tipos. · Recorre este otra vez para optimización. · y generación de código · .. etc. 56 · El sistema de tipos provee una formalización concisa de las reglas de verificación s emántica. Compilación de una pasada · Bajo ciertas circunstancias, es posible construir un compilador completo de una sola pasada. · Es posible con ciertas condiciones del lenguaje · Particularmente cuando se declara antes de que se use. Verificación de tipos 57 · Existen aspectos a considerar en la verificación de tipos de un compilador · Procesa r las declaraciones y mantener una tabla de símbolos. · Almacenar el tipo de cada id entificador en la tabla de símbolos. · Realizar la verificación de tipos y hacer cumpl ir las reglas semánticas en expresiones y otros elementos del lenguaje (e.g. Lista de argumentos, etc.) · Buscar el tipo de los identificadores usados. · Inferir los tipos de constantes · Calcular el tipo de los nodos que denotan expresiones. 58 · Esto requiere que la traslación se realice durante un recorrido del árbol en profund idad. · La forma en que el analizador sintáctico se mueve a través del árbol Verificación de tipos con aseveraciones · En cada regla declaramos la aseveración que se debe cumplir si el programa es válido . · ASSERT(condición) ¨mensaje¨ significa: · La condición se supone debe cumplirse · Si no es verdadera, imprime mensaje. 59 Ejemplo de verificación de tipos (un ejemplo similar esta en la Sec. 6.4.4 de Kenn eth) 60 · Assert (Visual Studio 2012 ) · Prueba una aserción de software en tiempo de compilac ión. Si la expresión constante especificada es false, el compilador muestra el mensa je especificado y la compilación emite un error; si no, la declaración no tiene ningún efecto. static_assert( constant-expression, string-literal ); · Puede usarse una macro en C para este propósito
#define ASSERT(x,y) if (!x) printf(¨line %d: %s\n¨,lineno, (y)) 10
19/09/2013 Verificación de tipos en Bison 61 Verificación de tipos (Cont.) 62 Expresiones de Tipos · El tipo de una construcción de un lenguaje se denotará mediante una ªExpresión de tipoº. · Una expresión de tipo es, o bien un tipo básico o se forma aplic ando un operador llamado constructor de tipos a otras expresiones de tipos. · Los conjuntos de tipos y construcciones dependen del lenguaje que deba comprobarse. básicas 63 · Se utilizará la siguiente definición de expresiones de tipos: 1. Un tipo básico es una expresión de tipo. Entre los tipos básicos se encuentran bolean, char, integer y re al. Un tipo básico especial, la función error_tipo(), señalará un error durante la com-p robación de tipos. 2- Como se puede dar nombre a las expresiones de tipos, el nomb re de un tipo es una expresión de tipo. 64 3.-Un constructor de tipos aplicado a expresiones de tipos es una expresión de tip o. Los constructores incluyen: · · · · · Matrices, Productos, Registros, apuntadores y funciones). 65 b) Productos. Si T1 y T2 son expresiones de tipo, entonces su producto cartesian o T1 x T2 es una expresión de tipo. Se supone que x es asociativa por la izquierda . c) Registros. La diferencia entre un registro y un producto es que los campos de un registro tienen nombres. El constructor de tipos record se aplicará a un con junto ordenado formado con nombres de campos y tipos de campos. Por ejemplo, el fragmento de programa en Pascal: Type fila = record Dirección: integer; Lexema: ar ray [1..15] of char end; var tabla: array [1..10] of fila; 66 a) Matrices. Si T es una expresión de tipo, entonces array (I, T) es una expresión d e tipo que indica el tipo de una matriz con elementos de tipo T y conjunto de índi ces I, I con frecuencia es un rango de enteros. · Por ejemplo, la declaración en Pas cal Var A: array[1..10] of integer; Asocia la expresión de tipo array(1..10, integ er) con A. 11
19/09/2013 Declara que el nombre de tipo fila representa la expresión de tipo. Record (direcc ión x integer ) x (lexema x array (1..15, char)) Y que la variable tabla es una ma triz de registro de este tipo. d) Apuntadores.- Si T es una función de tipo, enton ces pointer (T) es una expresión de tipo que indica el tipo ªapuntador a un objeto d e Tº. · Por ejemplo, en Pascal, la declaración Var pila: fila Declara que la variable pila tiene tipo pointer (fila) 67 e) Funciones.- matemáticamente una función transforma los elementos de un conjunto, el dominio, a elementos de otro conjunto, el rango. Se pueden considerar las fun ciones dentro de los lenguajes de programación como transformaciones de un dominio de tipo D a un rango tipo R. La expresión tipo D R indica el tipo de dicha función. · Por ejemplo, la función predefinida mod de Pascal tiene un dominio de tipo int x int, es decir, un par de enteros, y rango de tipo int. De esta forma, se dice qu e mod tiene el tipo1. · int x int int 68 · Con frecuencia existen, por razones de implantación, limitaciones que en cuanto al tipo que una función puede devolver; por ejemplo, matrices o funciones. · Sin embar go existen lenguajes que permiten que las funciones devuelvan objetos de tipos a rbitrarios, así que se puede definir una función g de tipo (integer integer); (integ er integer) 69 4.- Las expresiones de tipo pueden contener variables cuyos valores son expresio nes de tipos. · Una manera conveniente de representar expresiones de tipo es utili zando un grafo. · Con el enfoque de la traducción dirigida por la sintaxis se puede construir un árbol o un GDA para una expresión de tipo, con nodos interiores para lo s constructores de tipos y hojas para los tipos básicos, nombres de tipos, y varia bles de tipos. 70 · Es decir, g toma como argumento una función que transforma un entero en un entero y g produce como resultado otra función del mismo tipo. Por ejemplo, consideremos la siguiente declaración: Str : array [0..80] of char; I : integer; Estáticamente puede que no se cumpla la condición: 0 <= i <= 80 al utili zar str [i]; es decir, esta comprobación debe efectuarse en forma dinámica. Sin emba rgo, es posible, por ejemplo, comprobar estáticamente si la asignación: str [i] := c h; está permitida, o sea, si ambos lados de la proposición de asignación son de tipos compatibles. Para ello es necesario consultar la tabla de símbolos. 71 · A continuación se presenta un breve ejemplo de cómo introducir las reglas que permit en la comprobación de tipos de expresiones aritméticas. · TipoE, TipoT y TipoF, repres entan el tipo de una expresión, términos, etc.; se emplean subíndices para distinguir entre varias ocurrencias de un mismo símbolo no Terminal. · Se usará el siguiente subc onjunto de la gramática G0 con las reglas correspondientes: 72 12
19/09/2013 E E1 T E2 + T (* TipoE := TipoT; *) (* TipoE1 := ifTipoE2 = integer end TipoT = integer then i nteger else error_tipo; *) (* TipoT := TipoF *) (* TipoT1 := ifTipoT2 = integer end TipoF = integer then integer else error_tipo; *) (* TipoF := buscar_Tipo(x); *) (* TipoF := buscar_Tipo(y); *) (* TipoF := TipoE; *) 73 · El procedimiento buscar Tipo(...) se utiliza para determinar el tipo de un ident ificador por medio de la revisión de la tabla de símbolos. · Por ejemplo, el tipo de u na expresión formada donde se aplica el operador ª+º a una subexpresión y un término, es e ntero, si el tipo de la subexpresión y el término es entero; en caso contrario será un error de tipo. · La formulación de reglas para semánticas (tipo Pascal), que establec en, por ejemplo, que Entero * Real genera un resultado de tipo Real, es obvia y puede verse cómo se propagará un tipo. 74 T T1 F T2 * F F F F x y (E De esta forma, durante el proceso de análisis semántico, se puede determinar donde s e requieren cambios forzados de tipo y qué operadores deben relacionarse (por ejem plo, multiplicación entera o de punto flotante). Se debe señalar que no todos los le nguajes de programación permiten una comprobación estática de tipos como la que se aca ba de exponer, para ello se tiene que implementar en su diseño, para que pueda ser considerada. 75 1.4.- Pila Semántica en un Analizador Sintáctico 76 Pila semántica en un ASem · La pila juega un papel fundamental en el desarrollo de cualquier analizador semánt ico. Dentro de cada elemento de la pila se guardan los valores que pueden tener una expresión. Admon. Tabla de Símbolos · La tabla de símbolos también recibe el nombre de ambiente. · Un ambiente contiene un c onjunto de parámetros que sólo son visibles en ese ambiente. · · La tabla de símbolos se m antiene durante todo el proceso de traducción agregando elementos específicos en cad a paso. 13
19/09/2013 Tabla de Símbolos Tabla de símbolos · Funcionalidades básicas: · Inserta(símbolo) · Existe(nombre) · · Se agrega una primitiva má Tipo (nombre) · ¿El análisis léxico crea la tabla de símbolos? · No · ¿Cómo se agrega la semántica al analizador sintáctico? · Declaración TIPO {tipo=obtengo(yy t());} listavar PYC · listavar var {inserta(símbolo);} | var {inserta(simbolo);} · var ID {simbolo=yytext; símbolo.tipo=tipo; simbolo.amb=ambito;} Tabla de Símbolos Exprlog PI exprlog{A=A;} PD | NOT exprlog {A=A;} | exprlog {A1=A;} OPLOG exprlog { A2=A if(A1==INT && A2==INT) A=INT; else A=ERROR_TIPO; } · int a; · a = (int) 10.1; Tabla de Símbolos 83 · Una tabla de símbolos es una estructura de datos empleada para registrar las decla raciones de identificadores. · Los identificadores se almacenan cuando se declaran · Con atributos · Nombres de clases, métodos, variables, etc Implementación de la tabla de símbolos 84 · La estructura es una pila · O una lista ligada que opera como pila · Operaciones · add_symbol(x) inserta x y la información asociada, tal como el tipo, en la pila. · f ind_symbol(x) busca en la pila, comenzando del tope de la pila.Regresa el primer x encontrado o NULL si no se encontro. · remove_symbol() saca elemento de la pila · Y sub-atributos · public, private, integer, float, static, array, etc · Su localización en la pila si es variable local · La tabla de símbolos se consulta para cualquier uso. · Verificación semántica y generación de código. 14
19/09/2013 Definición de clase Una tabla de símbolos más elaborada · enter_scope() comenzar un nuevo ámbito anidado · find_symbol(x) encuentra el x actua l (o null) · add_symbol(x) agrega un símbolo x a la tabla · check_scope(x) verdadero s i x esta definido en el ámbito actual (verificar declaraciones múltiples) · exit_scope () salir del ámbito · Descartar todos los símbolos del ámbito reciente 85 · Los nombres de clases se pueden usar antes de que sean definidos. · Usualmente no se puede verificar esto para los nombres de clases. · Usando una tabla de símbolos (compilación separada?) · O en una pasada (a menos que se requieran prototipos) 86 Definición de clase · Solución usual · Fase 1: Junta todos los nombres de clases (+ otras cosas) · Fase 2: Realiza la ver ificación 87 Implementación de una Tabla de Símbolos simple 88 · El análisis semántico completo requiere varias pasadas. · Probablemente más de una · La mayoría de compiladores en JAVA busca por archivos de clases previamente compil adas. Análisis semántico estático: se realiza en tiempo de compilation, no de execution. 1. Cómo vamos a especificar (describir) la estructura semántica de un lenguaje? · Mediante gramáticas de atributos. 89 1.5.- Esquemas de Traducción Los programas de aplicación, los videojuegos y otras he rramientas que se ejecutan en las computadoras, generalmente se realizan en leng uajes de alto nivel. Estos programas escritos en lenguajes de alto nivel necesit an ser traducidos a un lenguaje que sea entendible por la computadora, este leng uaje es el lenguaje de bajo nivel. 90 2. Cómo vamos a implementar la estructura semántica de un lenguaje? · A partir de la construcción del árbol de análisis sintáctico, lo recorreremos en un dete rminado orden y calcularemos en cada nodo la información semántica necesaria (el val or de una expresión, el tipo de una variable, su ámbito de declaración, el número de arg umentos de una función, etc). 15
19/09/2013 1.3.- Comprobaciones de Tipos en Expresiones 1.4.- Pila Semántica en un Analizador Sintáctico 91 Sistemas de Tipos. · El diseño de un comprobador de tipos para un lenguaje se basa e n información acerca de las construcciones sintácticas del lenguaje, la noción de tipo s y las reglas para asignar tipos a las construcciones de lenguajes. · Los siguien tes extractos de Pascal y del manual de referencia de C, respectivamente, son ej emplos de la información con la que el diseñador de un compilador podría verse obligad o a comenzar. 92 · ªSi ambos operandos de los operadores aritméticos de suma, sustracción y multiplicación son de tipo entero, entonces el resultado es de tipo entero.º · ªEl resultado del oper ando unario & es un apuntador hacia el objeto al que se refiere el operando. Si el tipo del operando es `Un Arreglo', o el tipo del resultado es `apuntador a' º. En los a nteriores extractos se encuentra implícita la idea de que cada expresión tiene asoci ado un tipo. 93 En los lenguajes Pascal y C, los tipos de datos son básicos o construidos. Los tip os básicos son los tipos atómicos sin estructura interna por lo que concierne al pro gramador. En Pascal, los tipos básicos son bolean, carácter, integer y real. Los tip os de subrango, como 1..10, y los tipos enumerados, como: · (Violeta, azul, verde, amarillo, naranja, rojo) Se pueden considerar como tipos básicos. 94 El lenguaje Pascal admite que un programador construya tipos a partir de tipos bás icos y otros tipos construidos, como por ejemplo, las matrices o arreglos (array ), los registros (record) y los conjuntos (set). Además, los apuntadores y las fun ciones también pueden considerarse como tipos construidos. Estos son algunos ejemp los de tipos de datos construidos que se pueden realizar con los lenguajes de al to nivel. 95 Todos los programas escritos en lenguajes de alto nivel deben ser traducidos a l enguaje de máquina mediante un traductor. La función de un traductor de un lenguaje de programación, es traducir programas escritos en un lenguaje de alto nivel a pro gramas equivalentes, expresados en lenguaje máquina. Después del proceso de traducción , los programas pueden ejecutarse en cualquier computadora a través de un intérprete microprogramado 96 16
19/09/2013 La siguiente figura muestra el funcionamiento de un traductor mediante un compil ador de cuatro pasos con las demás actividades que intervienen durante la compilac ión de un programa hasta llegar a convertir el programa escrito en lenguaje de alt o nivel a un programa escrito en lenguaje ensamblador o lenguaje binario, para q ue posteriormente se convierta en programa objeto: 97 98 Tipos de Traducción de lenguajes. 99 Compilados.- Los lenguajes por lo general como el C, Pascal, java, son lenguajes que se compilan. Esto significa que los programas en estos lenguajes se traduce n ordinariamente al lenguaje máquina de la computadora real que sé esta usando antes que inicie la ejecución, y la simulación está confinada a un con-junto de rutinas de apoyo en tiempos de ejecución que simulan operaciones primitivas en el lenguaje fu ente para las cuales no existe un análogo cercano en el lenguaje máquina. 100 Interpretados.- Este tipo de traducción lee y ejecu-ta instrucción por instrucción. LI PS, Prolog, Basic y Smalltalk, se suelen implementar a través del uso de un interp rete . En esta clase de lenguajes, el traductor no procede código de máquina para la computadora que sé esta utilizando. En su lugar, el traductor produce alguna form a inter-media del programa cuya ejecución es más fácil que la forma del programa origi nal, pero que es distinta del código máquina. Existe otro tipo de traducción que se realiza directa-mente por el procesador, est a traducción se describe a continuación: Ensamblador.-Es un traductor cuyo lenguaje objeto es también alguna variedad de lenguaje máquina para una computadora real pero cuyo lenguaje fuente, un lenguaje ensamblador constituye en gran medida una rep resentación simbólica del código de máquina objeto. Casi todas las instrucciones en el l enguaje fuente se traducen una por una a cada instrucción del lenguaje objeto. 101 Cargador.- es un traductor cuyo lenguaje objeto es un código de máquina real y cuyo lenguaje fuente es casi idéntico; y está compuesto por lo general de programas en le nguaje máquina en forma reubicable junto con tablas de datos que especifican punto s donde el código reubicable se debe codificar para volverlo automáticamente ejecuta ble. Preprocesador o Macroprocesador.- es un tra-ductor cuyo lenguaje fuente es una forma ampliada de un lenguaje de alto nivel cuyo lenguaje objeto es la forma estándar del mismo lenguaje. 102 17
19/09/2013 1.6.- Generación de la Tabla de Símbolos y de Direcciones. Una tabla de símbolos es una estructura de datos que contiene una entrada para cad a identificador encontrado en el programa fuente. Con el objeto de que el compil ador pueda llevar un control de la información sobre el ámbito y el enlace de los no mbres de datos que intervienen en el progra-ma fuente. 1.6.- Generación de la Tabl a de Símbolos y de Direcciones. Los campos de cada entrada en la tabla de sím-bolos corresponden a los atributos de cada i-dentificador. (Tipo, valor, dirección, paráme tros, etc.). 104 103 Durante la compilación de un programa, cada vez que se encuentra un identificador en la ta-bla de símbolos, se puede realizar lo siguiente: · La tabla puede ser consultada para ver si es necesario dar de alta el nuevo iden tificador. En la tabla se puede completar los atributos faltantes de un identifi cador ya existente. Se pueden recuperar los atributo de un iden-tificador ya exi stente en la tabla de símbolos. 105 · Los dos mecanismos para tablas de símbolos presentadas a continuación son listas lin eales y tablas de dispersión. · Cada uno de estos mecanismos se evalúa basán-dose en el tiempo necesario para añadir n entra-das y realizar e consultas. · Una lista lineal es lo más fácil de implantar, pero su rendimiento es pobre cuando e y n se vuelven más grandes. · Las tablas de dispersión proporcionan un mayor rendimiento con esfuerzo algo mayor de programación y gasto de espacio. · Ambos mecanismos pueden adaptarse ráp ida-mente funcionar las reglas del anidamiento más cercano. para 106 · · Un mecanismo de tabla de símbolos debe permitir añadir nuevas entradas y encontrar l as entradas existentes de un analizador léxico eficientemente. · Un compilador debe ser capaz de aumentar dinámicamente la tabla de símbolos durante la compilación. · Si la tabla de símbolos tiene tamaño fijo al escribir el compilador, e ntonces el tamaño debe de ser lo suficientemente grande como para almacenar cualqu ier programa fuente. · Es muy probable que dicho tamaño sea demasiado grande para la mayoría de los programa e inadecuado para algunos. · Para mantener uniformes los re gistros de la tabla de símbolos, es conveniente guardar una parte de la información de un nombre fuera de la entrada de la tabla, almacenando en el registro sólo un a puntador a esta infor-mación, para hacer referencia a él. 107 Administración de la Tabla de Símbolos. · Cada entrada de la tabla de símbolos corresponde a la declaración de un nombre. El f ormato de las entradas no tiene que ser uniforme porque la información de un nombr e depende del uso de dicho nombre. · Cada entrada se puede implantar como un regis tro que conste de una secuencia de palabras consecutivas de memoria. · No toda la información se introduce en la tabla de símbolos. · · Las palabras clave se introducen, al inicio. El analizador léxico busca secuencias de letras y dígitos en la tabla de símbolos para determinar si se ha encontrado una palabra clave o un nombre.
108 18
19/09/2013 Las palabras clave deben estar en la tabla de símbolos antes de que comience el anál isis léxico. 109 · Si el analizador léxico reconoce las palabras clave, entonces no necesitan aparece r en la tabla de símbolos. · Si el lenguaje no convierte en palabras reservadas las palabras clave, entonces es indispensable que las palabras clave se introduzcan en la tabla de símbolos advirtiendo su posible uso como palabras clave. · La entrada misma de la tabla de símbolos puede establecerse cuando se aclara el papel de un nombre, y se llenan los valores de los atributos cuando se dispone de la informa ción. · En algunos casos, el analizador léxico puede iniciar la entrada en cuanto apar ezca un nombre en los datos de entrada. 110 Fig. Una tabla de símbolos separada en dos partes, utilizando una parte como apunt ador a dicha tabla para hacer referencia a los nombres almacenados en ella. Un nombre puede indicar varios objetos distintos, quizás incluso en el mismo bloqu e o procedimiento. Por ejemplo, las declaraciones en C. int x; struct x { float y, z; } ; Utilizan x como entero y como etiqueta de una estructura con dos campo s. En ambos casos, el analizador léxico sólo puede devolver al analizador sintáctico e l nombre solo (o un apuntador al lexema que forma dicho nombre), en lugar de un apuntador a la entrada en la tabla de símbolos. · Se crea el registro en la tabla de símbolos cuando se descubre el papel sintáctico q ue desempeña este nombre. 111 · Para las declaraciones de la expresión, se crearían dos entradas en la tabla de símbol os para x; una con x como entero y otra como estructura. · Los atributos de un nom bre se introducen en respuesta a las declaraciones, que pueden ser implícitas. · Las etiquetas son identificadores seguidos de dos puntos, así que una acción asociada c on el reconocimiento de dicho identifica-dor puede ser introducir este hecho en la tabla de símbolos. · La sintaxis de las declaraciones de los procedimientos espec ifican que algunos identificadores son parámetros formales. 112 1.7.- Manejo de Errores Semánticos 114 Los errores que puede detectar el Analizador Sintáctico son aquellos que no cumple n las reglas de una gramática independiente del contexto. Una de las características de un lenguaje de programación es que no puede enunciarse con las reglas independ ientes del contexto, ya que dependen de él; por ejemplo, la restricción de que los i dentificadores deben declararse previamente antes de ser utilizados. 1.7.- Manejo de Errores Semánticos 113 19
19/09/2013 Por tanto, los principales errores semánticos son los siguientes: a).-Identificado res no definidos; b).-Operadores y operandos incompatibles; Es mucho más difícil int roducir métodos formales para la recuperación de errores semánticos que para la recupe ración de errores sintácticos, ya que con frecuencia la recuperación es ambigua. 115 · No obstante, puede requerirse que, por lo menos, el error semántico sea informado al programador, que se le ignore y que, por tanto, se suprimirá la generación de códig o. · Sin embargo, la mayoría de los errores semánticos pueden ser detectados mediante la revisión de la tabla de símbolos. 116 FUENTES DE INFORMACION 1. Aho, Sethi, Ullman. Compiladores Principios, técnicas y herramientas. Ed. Addis on Wesley. 117 FUENTES DE INFORMACION 118 2. Lemone Karen A. , Fundamentos de Compiladores Cómo traducir al lenguaje de comp utadora. Ed. Compañía Editorial Continental. 3. Kenneth C. Louden. Construcción de com piladores Principios y práctica. Ed. Thomson. 4. Martin John, Lenguajes Formales y Teoría de la Computación, ED. Mc Graw Hill. 5. Hopcroft John E., Introducción a la Te oría de Autómatas, Lenguajes y Computación, ED. Addison Wesley 6. Guerra Crespo. Hecto r. Compiladores. Ed. Tecnológica Didáctica. 7. Ronald Mark. Writing Compilers and In terpreters. Ed. Wiley Computer Publishing. 8. Fischer, LeBlanc. Crafting a compi ler with C. Ed. Cummings Publishing Company, Inc. 9. Salas Parrilla, Jesús. Sistem as Operativos y Compiladores. Ed. McGraw Hill. 10. Beck. Software de Sistemas, Introducción a la programación de Sistemas. Ed. Addi son-Wesley Iberoamericana. 11. Teufel, Schmidt, Teufel. Compiladores Conceptos F undamentales. Ed. Addison-Wesley Iberoamericana. 12. C. Louden, Kenneth. Lenguaj es de programación Principios y práctica. Ed. Thomson. 13. Levine Gutiérrez, Guillermo . Computación y programación moderna Perspectiva integral de la informática. Ed. Pears on Educación. 14. Abel, Peter. Lenguaje ensamblador y programación para PC IBM y com patibles. Ed. Pearson Educación. 15. Mak, Ronald. Writing compilers and interprete rs. Wiley Computer. Ed. Publishing. 16. Pittman, Thomas, Peters, James. The art of compiler design Theory and práctice. Prentice Hall. Dudas???? 119 20