17.04.2015 Views

Análisis semántico

Análisis semántico

Análisis semántico

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Análisis</strong> <strong>semántico</strong><br />

Tabla de símbolos, chequeo de tipos y<br />

representaciones internas<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.1


¿<strong>Análisis</strong>? ... ¿<strong>semántico</strong>?<br />

La semántica corresponde al significado asociado a las<br />

estructuras formales (sintaxis) del lenguaje.<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.2


¿<strong>Análisis</strong>? ... ¿<strong>semántico</strong>?<br />

La semántica corresponde al significado asociado a las<br />

estructuras formales (sintaxis) del lenguaje.<br />

Como las gramáticas (E)BNF —además normalmente<br />

limitadas a LR o LL— no pueden describir todos los<br />

elementos sintácticos del lenguaje, se hace preciso algún<br />

análisis adicional...<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.2


¿<strong>Análisis</strong>? ... ¿<strong>semántico</strong>?<br />

La semántica corresponde al significado asociado a las<br />

estructuras formales (sintaxis) del lenguaje.<br />

Como las gramáticas (E)BNF —además normalmente<br />

limitadas a LR o LL— no pueden describir todos los<br />

elementos sintácticos del lenguaje, se hace preciso algún<br />

análisis adicional...<br />

Así, se denomina tradicionalmente “análisis <strong>semántico</strong>”<br />

a todo aquello que forma parte del frontal [front-end]<br />

más allá de lo que la gramática utilizada nos permite:<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.2


¿<strong>Análisis</strong>? ... ¿<strong>semántico</strong>?<br />

La semántica corresponde al significado asociado a las<br />

estructuras formales (sintaxis) del lenguaje.<br />

Como las gramáticas (E)BNF —además normalmente<br />

limitadas a LR o LL— no pueden describir todos los<br />

elementos sintácticos del lenguaje, se hace preciso algún<br />

análisis adicional...<br />

Así, se denomina tradicionalmente “análisis <strong>semántico</strong>”<br />

a todo aquello que forma parte del frontal [front-end]<br />

más allá de lo que la gramática utilizada nos permite:<br />

Tabla de símbolos<br />

Chequeos de tipos (y otros)<br />

Generación de representación interna<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.2


Ejemplo de extensión<br />

del análisis sintáctico<br />

La tabla de símbolos permite que el analizador léxico<br />

devuelva un token distinto según la categoría del<br />

identificador en ese contexto. Con esta técnica:<br />

En el fondo, estamos introduciendo “dependencia<br />

del contexto” sobre una gramática independiente del<br />

contexto.<br />

Por tanto, aumentamos la potencia del<br />

análisis sintáctico<br />

Podemos resolver algunos conflictos y así evitar<br />

modificar la gramática o el lenguaje<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.3


Tabla(s) de símbolos<br />

Va conteniendo un registro por cada identificador<br />

definido/declarado por el programador, añadiéndose<br />

información asociada:<br />

Ristra del identificador (¿mayúsculas y minúsculas?)<br />

Categoría: variable, constante, tipo, campo,<br />

procedimiento, función, parámetro, clase, etiqueta,<br />

módulo, macro, etc.<br />

A qué ámbito pertenece (profundidad)<br />

Otra información según categoría: tamaño;<br />

ubicación; valor; enlaces a tipo, parámetros o<br />

campos; si incompletamente definido; etc.<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.4


Estructura de la tabla de símbolos<br />

Su estructura lógica viene determinada por:<br />

El tipo de ámbito (estático o dinámico)<br />

Los mecanismos de ámbito del lenguaje:<br />

procedimientos, bloques, herencia, módulos,<br />

espacios de nombres, registros, with, ...<br />

Si se da más de una pasada.<br />

Compilación separada: ficheros con tablas<br />

Su implementación física más eficiente suele ser la<br />

de una tabla hash, asociada a pila de ámbitos activos.<br />

Truco: mover (insertar, al menos) el elemento actual a la<br />

cabeza de la lista<br />

Las ristras (identificadores, constantes) pueden ir en<br />

lista(s) aparte. <strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.5


Ejemplo con open hashing<br />

↓ int s(double, int);<br />

↓ char c;<br />

↓ int main() {<br />

↓ typedef double real;<br />

↓ while (c==0) {<br />

↓ real x = 0.1;<br />

↓ int c = 1;<br />

↓ c = s(x, c);<br />

↓ }<br />

↓ }<br />

↓ int s(double c, int d) {<br />

↓ return c+d;<br />

↓ }<br />

s<br />

?<br />

?<br />

c<br />

main<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.6


Ejemplo con open hashing<br />

↓ int s(double, int);<br />

↓ char c;<br />

↓ int main() {<br />

↓ typedef double real;<br />

↓ while (c==0) {<br />

↓ real x = 0.1;<br />

↓ int c = 1;<br />

↓ c = s(x, c);<br />

↓ }<br />

↓ }<br />

↓ int s(double c, int d) {<br />

↓ return c+d;<br />

↓ }<br />

s<br />

?<br />

?<br />

c<br />

main<br />

real<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.6


Ejemplo con open hashing<br />

↓ int s(double, int);<br />

↓ char c;<br />

↓ int main() {<br />

↓ typedef double real;<br />

↓ while (c==0) {<br />

↓ real x = 0.1;<br />

↓ int c = 1;<br />

↓ c = s(x, c);<br />

↓ }<br />

↓ }<br />

↓ int s(double c, int d) {<br />

↓ return c+d;<br />

↓ }<br />

s<br />

?<br />

?<br />

c<br />

main<br />

real<br />

x<br />

c<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.6


Ejemplo con open hashing<br />

↓ int s(double, int);<br />

↓ char c;<br />

↓ int main() {<br />

↓ typedef double real;<br />

↓ while (c==0) {<br />

↓ real x = 0.1;<br />

↓ int c = 1;<br />

↓ c = s(x, c);<br />

↓ }<br />

↓ }<br />

↓ int s(double c, int d) {<br />

↓ return c+d;<br />

↓ }<br />

s<br />

?<br />

?<br />

c<br />

main<br />

real<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.6


Ejemplo con open hashing<br />

↓ int s(double, int);<br />

↓ char c;<br />

↓ int main() {<br />

↓ typedef double real;<br />

↓ while (c==0) {<br />

↓ real x = 0.1;<br />

↓ int c = 1;<br />

↓ c = s(x, c);<br />

↓ }<br />

↓ }<br />

↓ int s(double c, int d) {<br />

↓ return c+d;<br />

↓ }<br />

s<br />

?<br />

?<br />

c<br />

main<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.6


Ejemplo con open hashing<br />

↓ int s(double, int);<br />

↓ char c;<br />

↓ int main() {<br />

↓ typedef double real;<br />

↓ while (c==0) {<br />

↓ real x = 0.1;<br />

↓ int c = 1;<br />

↓ c = s(x, c);<br />

↓ }<br />

↓ }<br />

↓ int s(double c, int d) {<br />

↓ return c+d;<br />

↓ }<br />

s<br />

c<br />

d<br />

c<br />

main<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.6


Una función hash<br />

Si llamamos c i a los códigos de los caracteres y n la<br />

longitud de la ristra:<br />

h 0 = 0<br />

h i = k(h i−1 mod 2 20 ) + c i<br />

H = h n mod T<br />

Para una tabla de tamaño T = 1008 pueden usarse<br />

valores de k 1 = 613 (preferentemente) o k 2 = 4 (más<br />

rápido pero peor distribución).<br />

Si open hashing:<br />

H j = (h (k 1)<br />

n + jh (k 2)<br />

n ) mod T, j = 0, 1, · · ·<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.7


Chequeos de tipos (y otros)<br />

Un compilador debe realizar una serie de chequeos<br />

estáticos, como chequeos de tipos:<br />

Consistencia: unicidad, existencia, no-ciclicidad, ...<br />

Equivalencia y compatibilidad de tipos<br />

Conversión explícita [cast] o forzada [coercion]<br />

Inferencia de tipos (en valores)<br />

Sobrecarga de funciones y operadores<br />

Funciones polimórficas,<br />

u otros (p.e., consistencia de instrucciones de control).<br />

En otros casos, debe generar código para realizar chequeos<br />

dinámicos (p.e., valor dentro de rango).<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.8


Definiciones de tipos<br />

También llamadas “expresiones de tipos”, en las que el<br />

programador desarrolla los componentes de la estructura.<br />

Cuestiones:<br />

Puede ser conveniente construir un árbol/grafo:<br />

En caso de equivalencia estructural<br />

Para comprobación de no-ciclicidad:<br />

type a=b; b=a;<br />

(Descomponer en) tipos anónimos<br />

Las definiciones incompletas (declaraciones) son necesarias<br />

para definiciones recursivas: entrada en tabla provisionalmente<br />

“vacía” para tipo base.<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.9


El árbol sintáctico abstracto (1/2)<br />

En inglés (abstract) syntax tree, AST, para distinguirlo del árbol del<br />

análisis según la gramática [parse tree].<br />

if(a


El árbol sintáctico abstracto (2/2)<br />

Representación compacta correspondiente a una<br />

gramática sin limitaciones de método de análisis,<br />

caracterizada por que los nodos interiores son<br />

operadores, en sentido amplio.<br />

Útil para ser “anotado” o “decorado” con atributos<br />

en recorridos ulteriores, y a partir de ahí:<br />

Realizar chequeos<br />

Generar código (intermedio)<br />

Con frecuencia se puede simular su recorrido (sin construirlo)<br />

durante el análisis sintáctico.<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.11


Representaciones internas (1/2)<br />

Intermedias entre frontal [front-end] y dorsal [back-end],<br />

permiten desacoplar los diseños de unos y otros.<br />

Orientadas a:<br />

Su optimización (instrucciones claras y simples)<br />

Generar código de distintas máquinas objeto<br />

El diseño debe permitir su fácil generación por el analizador<br />

semático.<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.12


Representaciones internas (2/2)<br />

Podemos clasificarlas por su nivel de abstracción<br />

(distancia a la máquina objeto real):<br />

Alto: próxima al árbol abstracto, con<br />

correspondencia con las estructuras del lenguaje<br />

Medio: instrucciones de máquina virtual (a veces<br />

realmente implementada: P-code, bytecode), tales<br />

como tuplas de tres direcciones<br />

Bajo: máquina próxima al ensamblador, con un<br />

amplio número de registros<br />

Algunos compiladores pasan por varias representaciones<br />

de distintos niveles de abstracción.<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.13


Cuádruplas<br />

Operaciones con hasta tres direcciones, que pueden ser<br />

variables del programa o temporales:<br />

x := y op z<br />

Ó x := op z ó x := z<br />

x := y[z] ó x[y] := z<br />

if x op y goto L ó goto L<br />

param x 1 , ..., param x n , call p(n)<br />

Podemos entenderlas como una linealización de un cierto<br />

tipo de árbol abstracto.<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.14


Ejemplo de cuádruplas<br />

for i in a..b do<br />

...<br />

endfor;<br />

...<br />

:= i a<br />

:= t8 b<br />

if >goto i t8 L5<br />

L4: ...<br />

if = goto i t8 L5<br />

:= + i i 1<br />

goto L4<br />

L5: ...<br />

<strong>Análisis</strong> semático v1.2 c○2005 José Fortes– p.15

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!