Análisis semántico

Embed Size (px)

Citation preview

Anlisis semntico La fase de anlisis semntico revisa el programa fuente para tratar de encontrar errores semnticos y rene la informacin 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)

La figura 4 muestra la representacin de esa proposicin despus de cada frase.

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 semnticoSe 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 atributosSea la expresinint 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 sidoa/(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 sidoint 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 programareal a; int b,c; a:=b+c

El rbol sintctico es::= --------| | a + real --------| | b c int int

Existen dos conversiones posibles::= real --------| | a + real real --------| | := real --------| | a + int real --------| |

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 SemnticoLa 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.

El anlisis sintctico y el anlisis semnticoDe todos los niveles de anlisis expuestos, la sintaxis ha sido durante mucho tiempo y an sigue siendo el nivel al que la lingstica le ha prestado mayor atencin. Est casi exclusiva atencin se justifica por dos razones principales en cuanto al tratamiento automtico del lenguaje natural (Rich & Knight 1994): 1. El procesamiento semntico funciona sobre los constituyentes de la oracin. Si no existe un paso de anlisis sintctico, el sistema semntico debe identificar sus propios constituyentes. Por otro lado, si se realiza un anlisis sintctico, se restringe enormemente el nmero de constituyentes a considerar por el semntico, mucho ms complejo y menos fiable. El anlisis sintctico es mucho menos costoso computacionalmente hablando que el anlisis semntico (que requiere inferencias importantes). Por tanto, la existencia de un anlisis sintctico conlleva un considerable ahorro de recursos y una disminucin de la complejidad del sistema. 2. Aunque frecuentemente se puede extraer el significado de una oracin sin usar hechos gramaticales, no siempre es posible hacerlo. Por esto es evidente que la disponibilidad de un buen parser es determinante para conseguir buenos resultados en los niveles superiores de anlisis. Aunque el objetivo del presente trabajo no es ste, nos detendremos a analizar el funcionamiento de los parsers tpicos porque es importante para entender las necesidades de informacin que este tipo de aplicaciones requiere, as como los beneficios que tales aplicaciones pueden obtener de una correcta y exhaustiva estructuracin de la informacin lingstica. La sintaxis contempla dos modos diferentes, pero no por ello opuestos, de anlisis. El primero es el anlisis de constituyentes o anlisis de estructura de frase: la estructuracin de las oraciones en sus partes constituyentes y la categorizacin de estas partes como nominales, verbales, adjetivales, etc. El segundo es el anlisis de las relaciones o funciones gramaticales: la asignacin de relacionales gramaticales tales como Sujeto, Objeto, etc. Desde el punto de vista del parser, una gramtica es un conjunto de reglas que describen cmo los distintos constituyentes se pueden combinar. Las combinaciones permitidas por la gramtica son consideradas gramaticales, mientras que el resto son agramaticales. Formalmente, una lengua es un conjunto de oraciones; cada oracin es una cadena de uno o ms smbolos pertenecientes al vocabulario de la lengua. Desde esta perspectiva, una gramtica no es ms que una especificacin formal y finita de este conjunto de oraciones (Grishman 1986). Esta especificacin puede ser llevada a cabo por enumeracin si el conjunto de oraciones es finito. Si el conjunto de oraciones es infinito o el nmero de posibles oraciones es demasiado elevado, resulta imposible o poco econmico describirlas por enumeracin. La otra manera es idear un mecanismo, es decir una gramtica, capaz de decidir, mediante la aplicacin de un determinado nmero de reglas, si determinada oracin es o no es gramatical. Tal tipo de gramtica suele ser una gramtica de estructura de frase o gramtica sintagmtica (PSG: Phrase Structure Grammar) (Hopcroft & Ullmann 1979). Las gramticas de estructura de frase han sido y son ampliamente utilizadas en las aplicaciones de anlisis del lenguaje natural, ya que se caracterizan por aportar una especificacin formal de una lengua, lo cual las hace susceptibles de ser implementadas mediante algoritmos computacionales. Esta implementacin, es decir, el conjunto de reglas, junto con el algoritmo que ha de desarrollarlas, es lo que se denomina parser. Una PSG tiene cuatro componentes (Grishman 1986:25):

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 utilizanpara especificar la gramtica. Se define V como la unin de estos dos vocabularios: V = (T U N).

3. Un conjunto de reglas o producciones P, donde cada regla es de la forma: aes una secuencia de uno o ms smbolos de V (es decir, a cero o ms smbolos de V (a V*).

b donde a

V+) y b es una secuencia de

4. El smbolo inicial S, miembro de N.La operacin bsica de una PSG es la de reescritura, es decir, la conversin de una secuencia de smbolos LHS (Left Hand Side) en otra diferente (RHS: Right Hand Side). Por ejemplo, si a b es una regla, esto significa que podemos reescribir cualquier smbolo que contenga la subcadena a, reemplazando a por b. Por ejemplo: nav nbv donde el smbolo " " denota esta operacin de reescritura.

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

printer cleaned, printed

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.