Anda di halaman 1dari 14

Analizador Semntico

Para poder entender mejor acerca de este tema definiremos lo que es la semntica; la semntica se refiere a los aspectos del significado, sentido o interpretacin del significado de un determinado elemento, smbolo, palabra, expresin o representacin formal. El anlisis semntico se trata de determinar el tipo de los resultados intermedios, comprobar que los argumentos que tiene un operador pertenecen al conjunto de los operadores posibles, y si son compatibles entre s, etc. En definitiva, comprobar que el significado de lo que se va leyendo es vlido. El anlisis semntico se realiza posteriormente al sintctico y mucho ms difcil de formalizar que ste. La salida terica de la fase de anlisis semntico sera un rbol semntico.

Un rbol semntico es una estructura jerrquica en la cual se registran las operaciones que implica u operan dentro del programa fuente. En cada una de las ramas del rbol semntico se registra el valor o significado que este debe tener, y el anlisis semntico se encarga de terminar cual de los valores registrados en las ramas es aplicable.

Ejemplo: Suponiendo que tenemos esta lnea de cdigo en C: Res=valor1+valor2; En C el smbolo (+) implica una suma de valores o una unin de las cadenas El anlisis semntico se va a encargar que tanto el valor1 como el valor2 tengan datos que son compatibles en comn y que adems se les pueda aplicar dicho operador.

VERIFICACION DE TIPOS DE EXPRESION


Sistema de Tipos: Conjunto de reglas que permiten asociar tipos a las construcciones del lenguaje y vericar su correccin. Determinan el conjunto de expresiones de tipo admisibles en el lenguaje. Expresiones de tipo: Tipos asociados a las construcciones del lenguaje. Una expresin de tipo es o bien un tipo bsico, o es el resultado de aplicar un constructor de tipo a otra expresin de tipo de acuerdo a unas reglas de construccin (dadas por el lenguaje). Tipos bsicos y constructores de tipo dependen del lenguaje.

Expresiones de tipo pueden tener asociados nombres. Tipos Bsicos: char, boolean, real, integer Tipos especiales: error: Indica que no se puede asociar una expresin de tipo correcta. void: Indica que una construccin del lenguaje es correcta, pero no tiene ningn tipo asociado. Util en comprobacin de sentencias.

Constructores de tipo: Permiten formar tipos complejos a partir de otros ms simples. MATRICES: Siendo T una expresin de tipo , array(I, T ) es el tipo de una matriz con elementos de tipo T e ndices del tipo I. T tipo de los elementos del array. l tipo de los ndices (generalmente un rango). Ejemplo: C: int A[10]; array(0.,9, integer)

PRODUCTOS: Si T1 y T2 son expresin de tipo, T1 T2 es una expresin de tipo. ( se supone asociativo por la izq.). REGISTROS: Similar a productos, pero con nombre asociados a los campos. Si u1, u2, . . . , un son los campos de tipos T1, T2, . . . , Tn, la expresin de tipo asociada al registro es: record(u1 : T1 u2 : T2 . . . un : Tn) Ejemplo: struct { record char nombre[10]; nombre: array [0..9] of character; float altura; altura:real;

} end; record(nombre : array(0.,9, char) altura : real) PUNTEROS: Si T es una expr. de tipo, pointer(T ) representa al tipo de dato que tiene como valores el conjunto de posiciones de memoria que pueden almacenar datos del tipo T . Ejemplo: char p; pointer(char) p: character FUNCIONES: Siendo D la expresin de tipo de los argumentos de la funcin y T el tipo del valor devuelto, la expresin de tipo de la funcin ser:D T. Para funciones con mltiples argumentos se usaran productos. Ejemplo: float f(char a,b); pointer(real) function f(a,b:character):real Otros constructores: conjuntos, pilas, colas, cheros, etc,... NOTA: Dentro de las expresiones de tipo podrn incluirse variables Representa un componente que puede tener cualquier expresin De tipo asociada o del cual se desconoce su tipo. Util para manejar funciones polimiorcas. (char char)

CONVERSION DE TIPOS
Conversin IMPLICITA (coerciones) realizada por el compilador Conversin EXPLICITA realizada por el programador SOBRECARGA DE OPERADORES y FUNCIONES POLIMORFICAS

Smbolos del lenguaje que tienen asociados distintos tipos y operaciones en funcin del contexto. Suma de enteros Ejemplo: Operador+: Suma de reales Concatenacin de cadenas
En el proceso de desarrollo de software, los enfoques top-down y bottomup juegan un papel clave.

ACCIONES AGREGADAS A UN ANALIZADOR SEMANTICO TOPDOWN


La solucin de cualquier problema puede darse en varias formas o niveles de abstraccin. Se comienza dando un enunciado ms general o abstracto de la solucin. Se refina esta solucin elaborando los detalles que antes se han ignorado, de lo que resulta una solucin nueva que es menos abstracta. Este proceso contina, hasta que se logra un nivel de detalle apropiado. Esta es la esencia del diseo top-down. Idea del diseo descendente o diseo top-down: Para solucionar un problema complejo vamos a dividirlo en problemas ms simples. La solucin a dichos problemas sern los SUBPROGRAMAS Estructura bsica de un programa en C.

PROGRAMA Secuencia corta de sentencias, la mayora de las cuales son llamadas a subprogramas. Cada subprograma puede ser utilizado tantas veces como queramos dentro del programa principal REUTILIZACIN DEL CDIGO Evita escribir repetidamente las mismas lneas de cdigo Un programa en C, es un conjunto de suprogramas, siendo la funcin main el subprograma principal. Es la primera funcin que se ejecuta Es la encargada de llamar al resto de los subprogramas.

El programa es construido de abajo a arriba, creando 1 subprogramas que resuelvan los mdulos de detalle son usados por otros subprogramas ms generales, hasta llegar a la creacin del programa original.

PILA SEMANTICA BUTTOM-UP


Se compone de un conjunto de rutinas independientes, llamadas por los analizadores morfolgico y sintctico. El anlisis semntico utiliza como entrada el rbol sintctico detectado por el anlisis sintctico para comprobar restricciones de tipo y otras limitaciones semnticas y preparar la generacin de cdigo. En compiladores de un solo paso, las llamadas a las rutinas semnticas se realizan directamente desde el analizador sintctico y son dichas rutinas las que llaman al generador de cdigo. El instrumento ms utilizado para conseguirlo es la gramtica de atributos. En compiladores de dos o ms pasos, el anlisis semntico se realiza independientemente de la generacin de cdigo, pasndose informacin a travs de un archivo intermedio, que normalmente contiene informacin sobre el rbol sintctico en forma linealizada (para facilitar su manejo y hacer posible su almacenamiento en memoria auxiliar).

En cualquier caso, las rutinas semnticas suelen hacer uso de una pila (la pila semntica) que contiene la informacin semntica asociada a los operandos (y a veces a los operadores) en forma de registros semnticos. Propagacin de atributos Sea la expresin int a,b,c; a/(b+c^2) El rbol sintctico es: / --------| | a + --------| | b ^ --------| | c 2 De la instruccin declarativa, la tabla de smbolos y el analizador morfolgico obtenemos los atributos de los operandos: / --------| | a + int --------| | b ^ int --------| | c 2 int int Propagando los atributos obtenemos: / int --------| |

a + int int --------| | b ^ int int --------| | c 2 int int Si la expresin hubiera sido a/(b+c^-2) El rbol sintctico sera el mismo, sustituyendo 2 por -2. Sin embargo, la propagacin de atributos sera diferente: / real --------| | a + real int --------| | b ^ real int --------| | c -2 int int En algn caso podra llegar a producirse error (p.e. si / representara slo la divisin entera). Si la expresin hubiera sido int a,b,c,d; a/(b+c^d) El rbol sintctico sera el mismo, sustituyendo 2 por d. Sin embargo, la propagacin de atributos sera incompleta: / {int,real} --------| | a + {int,real} int ---------

| | b ^ {int,real} int --------| | c d int int El analizador semntico podra reducir los tipos inseguros al tipo mximo (real) o utilizar un tipo interno nuevo (ej. arit={int,real}, una unin). Lo anterior es un ejemplo de propagacin bottom-up. La propagacin topdown tambin es posible: lo que se transmite son las restricciones y los tipos de las hojas sirven de comprobacin. Por ejemplo, si la divisin slo puede ser entera, transmitimos hacia abajo la restriccin de que sus operandos slo pueden ser enteros. Al llegar a d, esa restriccin se convierte en que d debe ser positiva. Si no lo es, error. La implantacin de todos los casos posibles de operacin con tipos mixtos podra ser excesivamente cara. En su lugar, se parte de operaciones relativamente simples (ej. int+int, real+real) y no se implementan las restantes (ej. int+real, real+int), aadiendo en su lugar operaciones mondicas de cambio de tipo (ej. int->real). Esta decisin puede introducir ambigedades. Por ejemplo, sea el programa real a; int b,c; a:=b+c El rbol sintctico es: := --------| | a + real --------| | b c int int Existen dos conversiones posibles: := real := real

--------| | a + real real --------| | b c int int

--------| | a + int real --------| | b c int int

El problema es que no tenemos garanta de que los dos procedimientos sean equivalentes. El segundo puede dar overflow, el primero prdida de precisin. La definicin del lenguaje debe especificar estos casos. Las transformaciones posibles se pueden representar mediante un grafo cuyos nodos son los tipos de datos y cada arco indica una transformacin. Dado un operando de tipo A que se desea convertir al tipo B, se trata de encontrar una cadena de arcos que pase de A a B en el grafo anterior. Podra haber varios grafos, cada uno de los cuales se aplicar en diferentes condiciones, por ejemplo, uno para las asignaciones, otro para las expresiones, etc.

ADMINISTRACION DE TABLA DE SIMBOLOS


Un compilador necesita guardar y usar la informacin de los objetos que se va encontrando en el texto fuente, como variables, etiquetas, declaraciones de tipos, etc Esta informacin se almacena en una estructura de datos interna conocida como tabla de smbolos.

La tabla de smbolos es una estructura de datos que nos permite realizar operaciones de insercin, bsqueda y eliminacin de informacin en varias construcciones del lenguaje fuente, la cual es analizada por el compilador originndose un cdigo objeto.

Mediante la tabla de smbolos un compilador (la mayora de lo dicho sera aplicable tambin a un intrprete) puede, dependiendo de la fase en que se encuentre, determinar: Si un identificador es una variable, conociendo su tipo o la direccin relativa que se le ha asignado. Si una variable o un procedimiento ha sido declarado antes de utilizarse la primera vez. Si un identificador es una palabra reservada y por tanto no debe permitir su redefinicin. Los identificadores que son visibles dependiendo de su mbito y el bloque que se est procesando en cada momento.

MANEJO DE ERRORES SEMANTICOS


Algunos problemas se presentan durante la fase de gestin de memoria al pasar argumentos o al crear la pila semntica. Muchos errores se generan durante la etapa del enlazador, al tratar de obtener cdigo existente de algunas funciones/mtodos ya implementadas en bibliotecas/APIs Tipos de errores que suelen ocurrir (dependiendo de la fase): Lxicos: No concuerda con ninguna ER. Ejemplo: escribir mal una palabra clave Sintcticos: La estructura que se ha seguido no es correcta. Ejemplo: expresin con parntesis no emparejados Semnticos: La estructura est bien pero hay errores de significado Ejemplo: operador y operandos incompatibles. Lgicos: Los comete el programador Ejemplo: una llamada infinitamente recursiva Algunos errores se pueden detectar en compilacin otros solo en ejecucin. El tratamiento de errores es una parte importante que se suele descuidar Tratamiento de errores semnticos Sea la gramtica:

Primer paso: Asignacin de tipo

Segundo paso: Comprobacin de tipo en expresiones

Tercer paso: Comprobacin de tipo en sentencia

Otras comprobaciones o tratamiento de errores semnticos Dentro de las comprobaciones estticas (en el momento de la compilacin), tenemos la deteccin e informacin de errores como: Comprobaciones de tipos: operadores aplicados a operandos incompatibles, asignacin de tipos incompatibles, llamadas a funciones con tipos no adecuados, etc. Comprobaciones de flujo de control: las sentencias que hacen que el flujo de control abandone una construccin debe tener alg un lugar a donde transmitir el control. Por ejemplo: Unbreak debe estar dentro de una proposicin while, for o switch en C. Comprobaciones de unicidad: situaciones en las que solo se puede definir un objeto una vez exactamente. Por ejemplo: Un identificador, las etiquetas case dentro de un switch. Solo nos hemos centrado en las comprobaciones de tipo. Las otras son en cierto modo rutinarias y se pueden realizar fcilmente insertando acciones intercaladas en el cdigo para realizarlas, por eje. Cuando se introduce un identificador en la Tabla de Smbolos.

Anda mungkin juga menyukai