Вы находитесь на странице: 1из 7

Laboratorio de Compiladores

Práctica 1: Compilador LL(1) recursivo

Capítulo 2: Analizador semántico y Traductor a cuartetos

Profesor:
Juan Antonio Román
2002

1
7.-Análisis semántico

En el Análisis semántico se realizarán dos tipos de comprobaciones:


• Comprobación de unicidad de las declaraciones:
o Un identificador sólo se declara una vez
o Un identificador que se usa en el código no ha sido declarado
• Comprobación de tipos:
o En sentencias de asignación
o En expresiones aritméticas
Para poder realizar la comprobación de tipos en las declaraciones se ha de añadir el tipo
en la TDS. Se necesitará una función para ello, por ejemplo: añadetipo(id.e)
Para hacer las comprobaciones semánticas se necesitará preguntar por el tipo del id y
obtener el nombre de un identificador. Por ejemplo: las funciones buscatipo(id.e) y
buscanombre(id.e).
¡ Revisad el esquema del Analizador semántico y traductor a cuartetos de la
introducción!

8.- Generación de cuartetos

Se generará una secuencia de cuartetos que constituirá la entrada para el generador de


código objeto ( que no es materia de esta práctica).
Se necesitará una función que genere cuartetos en las sentencias:
• Asignación
• Expresiones aritméticas
Para las sentencias de selección y flujos de control, para asegurar el flujo correcto, se
necesitarán etiquetas. Así pues cada registro de cuarteto necesitará otro campo para las
etiquetas, que no representará más que direcciones simbólicas de cuartetos.
Para ello se necesitarán las siguientes funciones:
• temporalnuevo( ), que devuelve una variable temporal

¡ no olvidar que estas variables han de ser guardadas en la TDS!

• generacuarteto( operador, argumento1, argumento2, resultado), que genera un


registro guardando los argumentos en los campos correspondientes
• etiquetanueva( ) que devuelve una etiqueta diferente cada vez que es invocada.
• generaetiqueta( “etiqueta”) que guarda la etiqueta contenida en el argumento en
el campo de etiqueta de registro del cuarteto.

9.- Esquema de traducción

Será la especificación del código del traductor. En él quedarán integradas las acciones
tanto para el análisis semántico como la traducción a cuartetos.
Es ahora el momento de utilizar los atributos. En general, se necesitan dos clases de
atributos:
• nombre, para contener el lexema (string) de los identificadores, o de los números
enteros, o el carácter de un operador.

2
• Tipo, para la comprobación de unicidad y de tipos.

Declaraciones

D  id L
L  , id L1 | TI
TI  ent | real

Ejemplo de cadena: a,b ent

¿ Qué traducción ? escribir el tipo en la TDS de los identificadores declarados


¿ Qué información ? el tipo, (en el ejemplo: ent)
¿Quién la proporciona? El símbolo TI
¿ Qué hacer ? sacar el tipo de TI ,llevarlo a cada uno de los identificadores, recorriendo
el árbol sintáctico en profundidad

Usando ATR SINT se podrá añadir el tipo después de visitar L y D subiendo por el
árbol por la derecha, cuando ya se dispone de los atributos sintetizados:
• Para L : id.e (b) y L1t
• Para D : id.e (a) y Lt

D añadetipo ( id.e , L.t )

id Id.e

L L.t y añadetipo( id.e , L1.t )


a

, id id.e

L1 L1.t
b

TI TI.t

ent

3
Pero además de lo anterior hay que incluir el análisis semántico de si el identificador en
cuestión ha sido ya declarado o no ¿Cómo? Simplemente leyendo su tipo en la TDS, si
es diferente de cero es que ha sido ya declarado con anterioridad y ha de emitirse un
error semántico. Sólo si el tipo es cero podrá actualizarse el tipo declarado en la TDS
para el identificador en cuestión.

Sentencias de asignación
Se utilizarán ATR SINT

S  F asigna E

Sean cuales fueren los subárboles que penden de F y de E, cuando se recorra el árbol en
profundidad, al ascender por la derecha estaremos llevando sus ATR SINT.

S Comprobación de tipos (F.t, E.t) ok Generacuarteto


(:=, E.n, , Fn )

F.t
F
No ok
F.n
E.t
E
Error
E.n semántico

¿ Qué traducción ? escribir el cuarteto de una asignación y comprobación semántica


¿ Qué información ? el tipo y el nombre
¿Quién la proporciona? El símbolo F, F.t y F.n
¿ Qué hacer ? obtener los ATR SINT de F (F.t y F.n) y de E (E.t y E.n) recorriendo el
árbol sintáctico en profundidad. A la vuelta de E Comprobar los tipos F.t y E.t y generar
el cuarteto de la asignación con F.n y E.n.

Expresiones aritméticas

E  T E’ ¿Qué traducción? cuartetos y comprob. Semánticas


E’  opsr T E’ | λ ¿ Qué información ? el tipo y el nombre
T  F T’ ¿Quién la proporciona? Nombre y tipo de id y de
T’  opmd F T’ | λ nume
F  id | nume | pa E pc ¿A quienes damos los resultados? Tras recorrer el
árbol en profundidad, usar ATR SINT y HER. Los
cuartetos finales para T’ (temp1), E’(temp2) y E
Observando el árbol podemos sacar las siguientes conclusiones:
• Todas las funciones devuelven los atributos nombre y tipo (ATR SINT)
• Algunas funciones necesitan parámetros (ATR HER) para poder tratar sus
argumentos y finalmente devolver los atributos nombre y tipo (ATR SINT). Estas
son E’( ) y T’( ):
o E’ tendrá que distinguir si el atributo opsr es MAS o MEN, pues el operador
en el cuarteto que se genere será ‘+’ o ‘-‘ respectivamente
4
E En Et

E’t
tmp2 Comp. tipos
E’hn cuarteto
Tn E’ht
T Tt E’
E’1n
T’hn E’1hn E’1t
T’n Tn
Fn T’ht T’t Tt E’1ht
F T’ opsr MAS T E’1
F.t

λ
id id.e λ T’hn
id.t F Fn T’
Ft T’ht
tmp1
cuarteto
T’t
Comp..tipos
a id.e
id id.t
Árbol para el ejemplo
T’1n
a+b*c
T’1t
b
Fn T’1hn
opmd MULT F Ft T’1
T’1ht

id id.e λ
id.t

5
En ambos caso ha de generar el correspondiente temporal, guardarlo en la TDS y
generar el cuarteto correspondiente con los siguientes argumentos:
• Operador (‘+’ si atributo es MAS, ‘-‘ si es MEN)
• Parámetro recibido por E’ padre (nombre) (ATR HER).
• Parámetro recibido por E’ hijo (nombre) (ATR SINT).
• Temporal nuevo Ti.
Desde ese momento el atributo nombre será el Ti, que ha de ser copiado como atributo
nombre (ATR SINT ) de E’ padre y pueda ser devuelto por la función.

En el caso de que el símbolo de preanálisis no sea opsr (caso de alternativa λ ) no hay


error, el ATR HER se convierte en SINT para ser devuelto por la función.
Además se ha de hacer la comprobación de tipos entre:
• Tipo entregado como parámetro a E’ padre (ATR HER)
• Tipo “ “ “ a E’ hijo (ATR SINT)

Lo dicho para E’ es aplicable para T’, pero cambiando opsr ( MAS y MEN como
atributos) por opmd ( MULT y DIV ).

En la función de F ( ) sí hay tratamiento de error si el símbolo de preanálisis no coincide


ni con id , ni nume, ni con ‘(‘.

¡No olvidad la comprobación semántica de si el id analizado ha sido declarado!

Sentencias de flujo de control


Éstas no generan cuartetos en sí mismas, sólo lo harán las asignaciones, comparaciones
y expresiones aritméticas que contengan( que ya han sido tratadas).lo importante es
dirigir el flujo de control creando etiquetas y asignándolas a los cuartetos adecuados.

S  if C then S1 else S2 | do S1 while C


E E=E

if – then – else
Sea el esquema de la figura adjunta: representa la secuencia de cuartetos en el
orden en que serán generados:
Cv C genera saltos a Cv en caso que se cumpla
Cuartetos de C la condición y a Cf en caso contrario.
Cf Cv será asignada al primer cuarteto de los
Cv: Cuartetos de S1
que se generen para S1 y Cf para el primer
cuarteto de los que se generen para S2.
goto Sf
Cuando se termine la generación de S1 se
Cf: Cuartetos de S2 hace necesario un salto incondicional a Sf
(1º cuarteto después de S2) y es preciso
Sf: asignar Sf al cuarteto1º después de s2.
6
La función C ( ) ha de devolver la etiqueta Cf (ATR SINT), pues ha de ser
entregada como parámetro a la función S( ) para que en ella se asigne la etiqueta
Cf al primer cuarteto de S2 . La función C ( ), además de generar el salto
condicional a Cv y el incondicional a Cf, ha de asignar la etiqueta Cv al primer
cuarteto de S1.

Do –while

En el esquema de la figura adjunta puede observarse que en primer lugar ha de


generarse los cuartetos de S1.
Después se pregunta por la condición.
Si ésta se cumple se ha de volver a
Sc: Cuartetos de S1 ejecutar los cuartetos de S1. así pues,
antes de generar los cuartetos de S1 se
ha de crear y asignar una etiqueta a su
Cuartetos de C primer cuarteto, así cuando se cumple la
Cv
condición en C el salto será a Sc

En este caso no se necesitaría Cf y Cv debería ser Sc, pero como la función C se


ha generado para que sirva a la sentencia if-then-else, ésta deberá permanecer y
entonces para generar este do-while se debe hacer la necesaria adaptación:
Crear Sc por supuesto y después de la llamada a la función C (el mismo cuarteto
de la etiqueta Cv:), generar un salto incondicional a Sc. Cf y el salto a Cf en este
caso no servirían pero no molestan.

PUNTO DE ACCIÓN 7 PARA EL ALUMNO


Escribir el EDT completo

PUNTO DE ACCIÓN 8 PARA EL ALUMNO


Modificar las funciones codificadas para el ANASINT para que refleje ese
EDT

¡ Recordad esas funciones han de contemplar parámetros cuando reciban


ATR HER y han de devolver los ATR SINT ¡

PUNTO DE ACCIÓN 9 PARA EL ALUMNO


Prueba y ejecución

Вам также может понравиться