1
Traducción dirigida por la sintaxis
2
INDICE
1. Gramáticas con atributos2. Evaluación de los atributos
2.1 Evaluación mediante grafos2.2 Evaluación durante el parsing
2.2.1 Esquemas de traducción2.2.2 Traducción top-down2.2.3 Traducción bottom-up
3
1. Gramáticas con atributos
Cada símbolo de una gramática puede tener asociados uno o más atributos.
Los atributos pueden ser de cualquier tipo de dato, y su significado depende del programador (valor de una constante, valor de una expresión, puntero, etc…)
N A ‘t’ B C
Representación: N.n A.a ‘t’.t B.b C.c
4
Tipos de atributos
1. Sintetizados2. Heredados
SintetizadosN A B CN.s = f ( A.a , B.b , C.c , N.i )
N.i : atributos que N hereda de su padre o sus hermanos
5
Tipos de atributos
Heredados
N A B C
B.i = f (A.a , B.b , C.c , N.n)
6
Especificación de atributos: reglas semánticas
Reglas Reglas semánticas
A B C D A.a = B.b + C.cD.i = B.b – C.c
C E F C.c = E.e * F.f
Reglas + Reglas semánticas =
Definición dirigida por sintaxis
7
Ejemplo 1: definición dirigida por sintaxis
REGLAS REGLAS SEMÁNTICAS
L E ‘\n’ print (E.val)E E1 + T E.val = E1.val + T.valE T E.val = T.valT T1 * F T.val = T1.val * F.valT F T.val = F.valF ( E ) F.val = E.valF cte F.val = cte.val
8
Ejemplo 1: árbol sintáctico ilustrativo
L
\nE
E + T
T
F
c te
3
T F
F
c te
5
cte
4
*
+ *
(v a l= 3 ) (v a l= 5 )
(v a l= 4 )(v a l= 3 )
(v a l= 3 )
(v a l= 3 )
(v a l= 5 )
(v a l= 5 ) (v a l= 4 )
(v a l= 2 0 )
(v a l= 2 3 )
p r in t (2 3 )
9
Ejemplo 2: definición dirigida por sintaxis
REGLAS REGLAS SEMÁNTICAS
D T L L.i = T.typeT int T.type = 0T real T.type = 1L L1 , id L1.i = L.i
save(id.ptr , L.i)
L id save(id.ptr ,L.i)
10
Ejemplo 2: árbol sintáctico ilustrativo
D
i n t
i n t b ca ,
( t y p e = 0 )T L
L , i d
L , i d
,
i d
( i = 0 )
( i = 0 )
( i = 0 )
11
Ejemplo 3: definición dirigida por sintaxis
REGLAS REGLAS SEMÁNTICAS
E E1 + T E.ptr = makenode (+ , E1.ptr , T.ptr)E E1 – T E.ptr = makenode (- , E1.ptr , T.ptr)E T E.ptr = T.ptrT ( E ) T.ptr = E.ptrT id T.ptr = makeleaf (id , id.ptr)T cte T.ptr = makeleaf (cte , cte.valor)
12
Ejemplo 3: árbol sintáctico ilustrativo
E
ba 5-
( p t r )
+
E + T
E - Ti d
c t eT
i d
i dc te 5i d
( p t r )
( p t r )
( p t r )
( p t r )
( p t r )
+
-
a b
13
ÍNDICE
1. Gramáticas con atributos2. Evaluación de los atributos
2.1 Evaluación mediante grafos2.2 Evaluación durante el parsing
2.2.1 Esquemas de traducción2.2.2 Traducción top-down2.2.3 Traducción bottom-up
14
2. EVALUACIÓN DE LOS ATRIBUTOS
Una Definición dirigida por sintaxis especifica el valor de los atributos, pero no especifica la forma de evaluación.
Existen 2 tipos de métodos para la evaluación:
2.1 Evaluación mediante grafos: la evaluación es independiente del reconocimiento sintáctico (parsing).
2.2 Evaluación durante el parsing: la evaluación se produce durante el reconocimiento sintáctico.
15
2.1 Evaluación mediante grafos
METODOLOGÍA
• Durante el proceso de parsing se genera el grafo de dependencias de los atributos.
• Posteriormente, se computan los valores de los atributos respetando el orden parcial impuesto por el grafo de dependencias.
16
Ejemplo
REGLAS REGLAS SEMÁNTICAS
E E1 + E2 E.val = E1.val + E2.valE E1 * E2 E.val = E1.val * E2.valE ( E1 ) E.val = E1.valE - E1 E.val = - E1.valE cte E.val = cte.val
17
Árbol sintáctico y grafo de dependencias
E
E + E
E
-
cte
2
E E-
cte
3
cte
5
*
+ *
2
2
-2
3 5
3 5
15
13
Á rbol sin tácticoG rafo de dependencias
18
Ventajas y desventajas
Ventaja importante
La evaluación mediante grafos es válida para cualquier definición dirigida por sintaxis (que no contenga ciclos)
Desventajas
Hay que construir un grafo que puede ser enorme (ESPACIO y TIEMPO) y la evaluación se realiza después de finalizar el análisis sintáctico (la evaluación durante el parsing es un poco más intuitiva)
19
2.2 Evaluación durante el parsing
Se trata de evaluar los atributos durante el proceso de parsing.
Ventajas
No se precisa de grafo de dependencias, y la evaluación es un poco más intuitiva.
Desventaja principal
No es una metodología válida para todo tipo de definiciones dirigidas por sintaxis.
20
2.2.1 Esquemas de traducción
Un esquema de traducción especifica la forma en que se van a evaluar los atributos durante un proceso de parsing.
Reglas sintácticas
+ } Definición dirigida por sintaxis
Reglas semánticas
21
Esquemas de traducción
Reglas sintácticas
+ } Esquema de traducción
ACCIONES
N A { acción_1 } B C { acción_2 }
22
Diseño del esquema de traducción
Dada una definición dirigida por sintaxis
¿ Cómo diseñamos el esquema de traducción ?
El diseño del esquema de traducción depende del tipo de recorrido que se realiza durante el proceso de parsing. Fundamentalmente tenemos 2 tipos de diseño:
2.2.2 Traducción top-down2.2.3 Traducción bottom-up
23
2.2.3 Esquemas de traducción bottom-up
A. Diseño del esquema de traducción
B. Implementación del esquema de traducción
24
A. Diseño de esquemas de traducción bottom-up
N A B C
Atributos sintetizados
N.s = f ( A.a , B.b , C.c , N.i )
Atributos heredados
B.i = f (A.a , B.b , C.c , N.n)
25
Metodología
1. El cálculo de un atributo sintetizado se realiza al final del no-terminal correspondiente.
2. El cálculo de un atributo heredado se realiza antes del no-terminal correspondiente.
26
Metodología (gráficamente)
S
A B C
D FE(i) (s)(i)
(i)(i)(i)
(i)
(s)
(s)(s)(s)
(s)
(i) (s)
27
Ejemplo 1 (I): definición dirigida por sintaxis
REGLAS REGLAS SEMÁNTICAS
E E1 + E2 E.val = E1.val + E2.valE E1 * E2 E.val = E1.val * E2.valE ( E1 ) E.val = E1.valE - E1 E.val = - E1.valE cte E.val = cte.val
28
Ejemplo 1 (II): esquema de traducción bottom-up
REGLAS y ACCIONES
E E1 + E2 { E.val = E1.val + E2.val } A1E E1 * E2 { E.val = E1.val * E2.val } A2E ( E1 ) { E.val = E1.val } A3E - E1 { E.val = - E1.val } A4E cte { E.val = cte.val } A5
29
Ejemplo 1 (III): árbol sintáctico con las acciones
E
E + E
E
-
cte
2
E E-
cte
3
cte
5
*
+ *
A1
A2A4
A5 A5 A5
30
REGLAS REGLAS SEMÁNTICAS
D T L L.i = T.typeT int T.type = 0T real T.type = 1L L1 , id L1.i = L.i
save(id.ptr , L.i)
L id save(id.ptr ,L.i)
Ejemplo 2 (I): definición dirigida por sintaxis
31
Ejemplo 2 (II): esquema de traducción bottom-up
REGLAS y ACCIONES
D T { L.i = T.type } L A1T int { T.type = 0 } A2T real { T.type = 1 } A3L { L1.i = L.i } L1 , id { save(id.ptr , L.i) } A4,A5L id { save(id.ptr ,L.i) } A6
32
Ejemplo 2 (III): árbol sintáctico con las acciones
D
in t
i n t b ca ,
T L
L , id
L , id
,
id
A 1
A 2 A 5A 4
A 4 A 5
A 6
33
Restricciones
¿ Se puede diseñar un esquema de traducción bottom-up para cualquier definición dirigida por sintaxis ?
REGLAS REGLAS SEMÁNTICAS
N A B C B.i = f (C.s)B D F B.s = g (D.s, F.s, B.i)
No podemos diseñar un esquema de traducción bottom-up para esta definición dirigida por sintaxis.
34
Clasificación de las definiciones dirigidas por sintaxis
S-Attributed
Solamente contienen atributos de tipo sintetizado.
L-AttributedContienen atributos sintetizados y heredados, pero éstos últimos tienen la siguiente restricción:
A X1 X2 … Xj
Xk.i = f (X1.x1, X2.x2, … , Xk-1.xk-1, A.i)
35
Validez del esquema de traducción bottom-up
La metodología mostrada anteriormente para diseñar el esquema de traducción para reconocedores bottom-up
solamente es válida
para definiciones dirigidas por sintaxis que sean L-Attributed (por supuesto, están incluidas las definiciones S-Attributed)
36
B. Implementación de esquemas de traducción bottom-up
Trataremos por separado la implementación para:
B.1 Atributos sintetizados
B.2 Atributos heredados
37
B.1 Implementación para atributos sintetizados
Los atributos sintetizados se evalúan durante las reducciones de las reglas en el proceso de parsing.
Para ello se utiliza una pila auxiliar (homóloga a la pila de parsing) en la que se realizan los cómputos.
38
Ejemplo: esquema de traducción
Reglas + Acciones
E E1 + T { E.val = E1.val + T.val }E T { E.val = T.val }T T1 * F { T.val = T1.val * F.val }T F { T.val = F.val }F ( E ) { F.val = E.val }F num { F.val = num.val }
39
Ejemplo: árbol sintáctico
E
E T
T F
T F
F
3∗ 4+2
+
num*
num
num
40
Ejemplo: secuencia de cómputos
digit 2 F 2 T 2 T 2*
digit 3
T 2*
F 3
T 6 E 6 E 6
+digit 4
E 6
+F 4
E 6+T 4
E 10
(1) (2) (3) (4)
(5) (6) (7) (8)
(9) (10) (11)
41
B.2 Implementación para atributos heredados
N { A1 } P { A2 } Q { A3 }
¿ Cómo sabemos el momento en el que hay que ejecutar las acciones {A1} y {A2} ?
Solamente tenemos la certeza de que esta regla se aplica cuando <PQ> están en la pila y se procede a la operación de reducción.
Ese momento nos permite ejecutar correctamente {A3}. Sin embargo, para {A1} y {A2} es demasiado tarde.
42
Posible solución
N { A1 } P { A2 } Q { A3 }
Sustituir las acciones {A1} y {A2} por símbolos no-terminales “ficticios”
N F1 P F2 Q { A3 }F1 ε { A1 } F2 ε { A2 }
El lenguaje generado por la gramática es el mismo, pero hemos modificado la gramática. Por tanto hay que modificar el cálculo de los atributos.
43
Atributos con la gramática modificada
Sea una regla general como la siguiente:
N { P.i=f(N.i) } P { Q.i=g(N.i,P.i,P.s) } Q { N.s=h(N.i,P.i,P.s,Q.i,Q.s) }
La modificación gramatical conlleva una pequeña modificación en el cálculo de los atributos:
N F1 P F2 Q { N.s=h(N.i,F1.s,P.s,F2.s,Q.s) }
F1 ε { F1.s=f(N.i) } ¿ localización de N.i ?
F2 ε { F2.s=g(N.i,F1.s,P.s) } ¿ localización de N.i, F1.s, P.s ?
44
Acceso a los valores de los atributos heredados
La localización de los atributos heredados debe realizarse en la pila de atributos.
Ejemplo: esquema de traducción
D T { L.i=T.type } LT int { T.type=0 }T real { T.type=1 }L { L1.i=L.i } L1 , id { save(id.ptr, L.i) }L id { save(id.ptr, L.i }
Añadiendo los no-terminales ficticios queda de la forma:
45
Ejemplo: terminales ficticios
D T F1 LF1 ε { F1.s=L.i=T.type } T int { T.type=0 }T real { T.type=1 }L F2 L1 , id { save(id.ptr, L.i) }F2 ε { F2.s=L1.i=L.i } L id { save(id.ptr, L.i }
46
Ejemplo: localización en la pila
D T F1 LF1 ε { F1.s=L.i=T.type=PILA-1 } T int { T.type=0 }T real { T.type=1 }L F2 L1 , id { save(id.ptr, L.i=PILA-1=F2.s) }F2 ε { F2.s=L1.i=L.i=PILA-1 } L id { save(id.ptr, L.i=PILA-1 }
47
Necesidad de los no-terminales ficticios
No siempre son necesarios. Debemos diferenciar 2 casos:
a) Atributos heredados transmitidos por copia
b) Atributos heredados no transmitidos por copia
48
a) Atributos heredados transmitidos por copia
Solamente se necesitan los no-terminales ficticios cuando no podemos predecir donde de encuentran en la pila los atributos heredados.
Ejemplo 1
S a A C C.i=A.sS b A B C C.i=A.sC c C.s=g(C.i)
En este caso no podemos predecir si C.i se encuentra en PILA-1 o bien en PILA-2 cuando se produce la reducción C c. Por tanto debemos añadir no-terminales ficticios:
49
a) Atributos heredados transmitidos por copia
Ejemplo 1 (con no-terminales ficticios)
S a A F1 C
F1 ε { F1.s=C.i=A.s=PILA-1 }
S b A B F2 C
F2 ε { F2.s=C.i=A.s=PILA-2 }
C c { C.s=g(C.i)=g(PILA-1) }
50
a) Atributos heredados transmitidos por copia
Ejemplo 2
S a A C // C.i=A.sS b A C // C.i=A.sC c C.s=g(C.i)=g(PILA-1)
En este caso si podemos predecir que C.i se encuentra en PILA-1 cuando se produce la reducción C c
51
a) Atributos heredados transmitidos por copia
Ejercicio
Dado el siguiente esquema de traducción con un atributo heredadoy transmitido por copia, ¿ se necesitan no-terminales ficticios para su implementación ?
D T { L.i=T.type } LT int { T.type=0 }T real { T.type=1 }L { L1.i=L.i } L1 , id { save(id.ptr, L.i) }L id { save(id.ptr, L.i }
52
b) Atributos heredados no transmitidos por copia
D T { L.i=T.type+1 } L { D.s=L.s }T int { T.type=0 }L { L1.i=L.i+1 } L1 , id { L.s=L1.s}L id { L.s=L.i }
En estos casos es necesario utilizar los no-terminales ficticios. De lo contrario, no podemos disponer de valores heredados y modificados durante su transmisión.
53
b) Atributos heredados no transmitidos por copia
D T F1 L { D.s=L.s }F1 ε { L.i=T.type+1=(PILA-1)+1 }
T int { T.type=0 }
L F2 L1 , id { L.s=L1.s }F2 ε { L1.i=L.i+1=(PILA-1)+1 }
L id { L.s=L.i=PILA-1 }
54
Símbolos ficticios y posibles conflictos
Tenemos 2 situaciones
• Si la gramática es LL(1), añadir no-terminales ficticios no genera ningún conflicto.
• Si la gramática es LR(1) (pero no es LL(1)), añadir no-terminales ficticios podría generar algún conflicto