Análisis semántico
Análisis semántico
Análisis semántico
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