Análisis Semántico
Análisis Semántico
Análisis Semántico
sobre los tipos para la fase posterior de generacin de cdigo. En ella se utiliza la estructura jerrquica determinada por la fase de anlisis sintctico para identificar los operadores y operandos de expresiones y proposiciones. Un componente importante del anlisis semntico es la verificacin de tipos. Aqu, el compilador verifica si cada operador tiene operandos permitidos por la especificacin del lenguaje fuente. Por ejemplo, las definiciones de muchos lenguajes de programacin requieren que el compilador indique un error cada vez que se use un nmero real como ndice de una matriz. Sin embargo, la especificacin del lenguaje puede imponer restricciones a los operandos, por ejemplo, cuando un operador aritmtico binario se aplica a un nmero entero y a un nmero real. Revisa que los arreglos tengan definido el tamao correcto.
Deteccin e informacin de errores Cada frase puede encontrar errores. Sin embargo, despus de detectar un error. Cada fase debe tratar de alguna forma ese error, para poder continuar la compilacin, permitiendo la deteccin de ms errores en el programa fuente. Un compilador que se detiene cuando encuentra el primer error, no resulta tan til como debiera. Las fases de anlisis sintctico y semntico por lo general manejan una gran proporcin de los errores detectables por el compilador. La fase lxica puede detectar errores donde los caracteres restantes de la entrada no forman ningn componente lxico del lenguaje. Los errores donde la
cadena de componentes lxicos violan las reglas de estructura (sintaxis) del lenguaje son determinados por la fase del anlisis sintctico. Durante el anlisis semntico el compilador intenta detectar construcciones que tengan la estructura sintctica correcta, pero que no tengan significado para la operacin implicada, por ejemplo, si se intenta sumar dos identificadores. Uno de los cuales es el nombre de una matriz, y el otro, el nombre de un procedimiento.
Las fases de anlisis Conforme avanza la traduccin, la representacin interna del programa fuente que tiene el compilador se modifica. Para ilustrar esas representaciones, considrese la traduccin de la proposicin Posicin := inicial + velocidad * 60 (1)
Anlisis Semntico
El anlisis semntico es posterior al sintctico y mucho ms difcil de formalizar que ste. 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. La salida "terica" de la fase de anlisis semntico sera un rbol semntico. Consiste en un rbol sintctico en el que cada una de sus ramas ha adquirido el significado que debe tener. En el caso de los operadores polimrficos (un nico smbolo con varios significados), el anlisis semntico determina cul es el aplicable. Por ejemplo, consideremos la siguiente sentencia de asignacin: A := B + C En Pascal, el signo + sirve para sumar enteros y reales, concatenar cadenas de caracteres y unir conjuntos. El anlisis semntico debe comprobar que B y C sean de un tipo comn o compatible y que se les pueda aplicar dicho operador. Si B y C son enteros o reales los sumar, si son cadenas las concatenar y si son conjuntos calcular su unin. Ejemplo VAR ch : CHAR; (* Un identificador no se puede utilizar si *) ent: INTEGER; (* previamente no se ha definido. *) ... ch := ent + 1; (* En Pascal no es vlido, en C s. *) Anlisis Lxico: Devuelve la secuencia de tokens: id asig id suma numero ptocoma Anlisis Sintctico: Orden de los tokens vlido Anlisis Semntico: Tipo de variables asignadas incorrecta
Analizador Semntico: Mdulo que se ocupa de analizar si la sentencia tiene algn significado, ya que se pueden encontrar sentencias que son sintcticamente correctas pero que no se pueden ejecutar porque carecen de sentido.
Anlisis semntico
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)
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
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 top-down 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
b int
c int
b int
c 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.
Anlisis Semntico
La habilidad para analizar un programa, razonando acerca de sus propiedades, es una de las tareas ms importantes en el diseo de software y en la manipulacin de programas. El anlisis de flujo de datos, es decir, el proceso de recoger informacin sobre la forma en que el programa usa las variables y las estructuras de datos (sin necesidad de ejecutarlo) juega un papel fundamental en el diseo de programas que, a su vez, transforman programas (como compiladores, intrpretes, sistemas de comprobacin de tipos, etc). Esto queda justificado, por ejemplo, cuando se recapacita sobre la enorme proporcin de cdigo dedicada en la mayora de compiladores modernos a la comprobacin y optimizacin del cdigo generado, puesto que cualquier mejora en el cdigo intermedio contribuye a producir un cdigo mquina correcto (con idntica semntica) y ms rpido. Una aproximacin interesante para el anlisis de los lenguajes de alto nivel consiste en considerar el anlisis del programa como un tipo de pseudo evaluacin, es decir, un proceso que imita la ejecucin del programa. La teora de la Interpretacin Abstracta permite el diseo y verificacin sistemtica de anlisis de flujo de datos, formalizando la relacin entre anlisis y semntica. Diferentes estilos de definicin semntica conducen a diferentes aproximaciones al anlisis de programas. El anlisis semntico es posterior al sintctico y mucho ms difcil de formalizar que ste. 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. La salida terica de la fase de anlisis semntico sera un rbol semntico. Consiste en un rbol sintctico en el que cada una de sus ramas ha adquirido el significado que debe tener. En el caso de los operadores polimrficos (un nico smbolo con varios significados), el anlisis semntico determina cul es el aplicable. Por ejemplo, consideremos la siguiente sentencia de asignacin: A := B + C En Pascal, el signo + sirve para sumar enteros y reales, concatenar cadenas de caracteres y unir conjuntos. El anlisis semntico debe comprobar que B y C sean de un tipo comn o compatible y que se les pueda aplicar dicho operador. Si B y C son enteros o reales los sumar, si son cadenas las concatenar y si son conjuntos calcular su unin.
1. Un vocabulario terminal T: las palabras o smbolos de la lengua definida 2. Un vocabulario no-terminal N: (los smbolos que no pertenecen al anterior y que se utilizan
para especificar la gramtica. Se define V como la unin de estos dos vocabularios: V = (T U N).
b donde a
Una lengua definida por una PSG es el conjunto de cadenas terminales (es decir, secuencias compuestas totalmente por smbolos terminales) que pueden derivarse del smbolo inicial S. La gran mayora de las gramticas formales para la descripcin formal del lenguaje natural que se han propuesto hasta ahora estn basadas en la gramtica de estructura de frase, lo cual determina el hecho de que casi todos los parsers estn basados tambin en ella. Una sencilla PSG para un subconjunto del ingls podra quedar determinado por el siguiente conjunto de reglas:
1. O 2. SN 3. SV 4. DET 5. Npr 6. N 7. V
SN, SV
Npr | DET, N V | V, SN
the | a John
Esta gramtica, por ejemplo, puede ser directamente implementada en un sistema prolog, que contenga un intrprete standard DCG (Definite Clause Grammar) (Pereira & Warren 1980), y podra generar las siguientes oraciones bien formadas segn nuestra gramtica: John cleaned John cleaned the printer John cleaned the document John printed
John printed the printer John printed the document ? the printer cleaned ? the printer cleaned John ? the printer cleaned the document the printer printed ? the printer printed John the printer printed the document ? the document cleaned ? the document cleaned John ? the document cleaned the printer ? the document printed ? the document printed John ? the document printed the printer Esta pequea gramtica es una gramtica independiente del contexto, porque satisface la condicin A x
donde A es un smbolo no-terminal y x es una secuencia de cero o ms smbolos terminales y noterminales. La principal caracterstica de este tipo de gramticas (CF-PSG: Context-Free Phrase Structure Grammar) es que emplea un conjunto finito de reglas para especificar la forma en que las categoras LHS se pueden reescribir en la RHS. Cuando una regla determinada especifica una realizacin determinada, esta realizacin es siempre posible, independientemente del contexto en la que la categora LHS aparece, de ah el nombre.