Tema 5: Traducción dirigida por la sintaxis Procesamiento de Lenguajes Dept. de Lenguajes y Sistemas Informáticos Universidad de Alicante Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 1 / 35 Ejemplo 1 de traducción E E T T F F F → → → → → → → E + T T T * F F id num pari E pard a+4*b ⇓ suma(a,mul(4,b)) Procesamiento de Lenguajes E E a T a F a id a suma(a,mul(4,b)) + Tema 5: Traducción dirigida por la sintaxis T T 4 F 4 num mul(4,b) * F b id b 4 2 / 35 Ejemplo 1 de traducción (2) G RAMÁTICA DE ATRIBUTOS E E T T F F F → → → → → → → R EGLA E + T T T * F F id num pari E pard ACCIÓN SEMÁNTICA E.trad := ”suma(”||E1 .trad||”, ”||T.trad||”)” E.trad := T.trad T.trad := ”mul(”||T1 .trad||”, ”||F.trad||”)” T.trad := F.trad F.trad := id.lexema F.trad := num.lexema F.trad := E.trad IMPORTANTE: no es posible acceder a atributos de símbolos que no estén en la regla Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 3 / 35 Ejemplo 2 de traducción D T T L L → → → → → T id L float int coma id L D T integer a,b:integer id int int a,b ⇓ a,b:integer Procesamiento de Lenguajes a coma L ,b id b L Tema 5: Traducción dirigida por la sintaxis 4 / 35 Ejemplo 2 de traducción (2) D T T L L G RAMÁTICA DE ATRIBUTOS R EGLA ACCIÓN SEMÁNTICA → T id L D.trad := id.lexema||L.trad||” : ”||T.trad → float T.trad := ”real” → int T.trad := ”integer ” → coma id L L.trad := ”, ”||id.lexema||L1 .trad → L.trad := ”” Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 5 / 35 Implementación del traductor Existen dos posibilidades: 1 El analizador sintáctico construye el árbol (decorado con los atributos de los terminales), y en una segunda pasada se recorre el árbol calculando los atributos que falten hasta completar la traducción (traducción de dos o más pasadas) 2 El analizador sintáctico no construye explícitamente el árbol (aunque hace un recorrido virtual por el árbol), y va calculando todos los atributos a la vez que va recorriendo el árbol (traducción de una sola pasada) Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 6 / 35 Recorrido virtual del árbol realizado por el A.S. E E T T F F F → → → → → → → E + T T T * F F id num pari E pard Procesamiento de Lenguajes E 13 + 5 E 4 T 3 T 8 F 2 F 7 id 1 num T 12 * 9 F 11 id 10 6 Tema 5: Traducción dirigida por la sintaxis 7 / 35 Ejemplo 3 de traducción D T T L L → → → → → T id L float int coma id L D T integer a:integer;b:integer id L integer ;b:integer int coma int a,b ⇓ a:integer;b:integer Procesamiento de Lenguajes a id b L integer Tema 5: Traducción dirigida por la sintaxis 8 / 35 Ejemplo 3 de traducción (2) D T T L L G RAMÁTICA DE ATRIBUTOS R EGLA ACCIÓN SEMÁNTICA L.th := T.trad; → T id L D.trad := id.lexema||” : ”||T.trad||L.trad T.trad := ”real” → float → int T.trad := ”integer ” L1 .th := L.th; → coma id L L.trad := ”; ”||id.lexema||” : ”||L.th||L1 .trad → L.trad := ”” Algunos no terminales tienen más de un atributo Algunos atributos se calculan a partir de atributos de hermanos o padres en el árbol. Estos atributos se llaman atributos heredados (los demás atributos se llaman sintetizados). Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 9 / 35 Grafo de dependencias D T integer a:integer;b:integer id a L integer ;b:integer int coma id b L integer Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 10 / 35 Ejemplo 4 de traducción D T T L L → → → → → D L T real integer L coma id id L int T int a;int b int integer L a,b integer ⇓ int a;int b int a;int b int coma int a id id b a IMPORTANTE: hay herencia de derecha a izquierda en el árbol Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 11 / 35 Ejemplo 4 de traducción (2) D T T L L G RAMÁTICA DE ATRIBUTOS R EGLA ACCIÓN SEMÁNTICA L.th := T.trad; D.trad := L.trad → L T → real T.trad := ”double” → integer T.trad := ”int” → L coma id L1 .th := L.th; L.trad := L1 .trad||”; ”||L.th||””||id.lexema → id L.trad := L.th||””||id.lexema La herencia de derecha (T ) a izquierda (L) implica que cuando se está analizando/traduciendo L todavía no se conoce la traducción de T Por tanto, no es posible traducir a la vez que se analiza, no es posible la traducción en una pasada. El analizador tiene que construir explícitamente el árbol, y cuando termine, en una segunda pasada, podrá generar la traducción. Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 12 / 35 Gramática de atributos por la izquierda D EFINICIÓN : una gramática de atributos se dice que es una gramática de atributos por la izquierda (l-attributed grammar) si solamente hay herencia de padres a hijos o bien de izquierda a derecha en el árbol, pero no de derecha a izquierda Las gramáticas de atributos por la izquierda (GAI) son aquellas que permiten evaluar los atributos a la vez que se hace el análisis sintáctico (en una sola pasada). Cuando la gramática de atributos no cumple las condiciones de las GAI (porque tiene herencia de derecha a izquierda en el árbol), el analizador sintáctico debe construir un árbol decorado con atributos y, en una segunda pasada se evaluarán los atributos que no se hayan podido evaluar en la primera pasada. Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 13 / 35 Tabla de símbolos La tabla de símbolos se utiliza para almacenar los símbolos (identificadores) declarados en el programa fuente, junto con su tipo y posiblemente alguna información más (dirección de memoria, etc). Ejemplo: int a,b; float c,d; Procesamiento de Lenguajes N OMBRE a b c d T IPO ENTERO ENTERO REAL REAL Tema 5: Traducción dirigida por la sintaxis D IRECCIÓN 0 2 4 8 14 / 35 Tabla de símbolos (2) Cuando el compilador procesa las declaraciones, tiene que añadir las variables declaradas a la tabla de símbolos (comprobando que no se declara dos veces el mismo identificador en el mismo ámbito). En el código (instrucciones, expresiones, etc), cuando aparece un identificador el compilador debe buscarlo en la tabla de símbolos, y obtener sus datos: tipo, dirección, etc. Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 15 / 35 Ejemplo 5 de traducción En este ejemplo, el traductor no genera traducción, pero debe almacenar los símbolos en la tabla de símbolos: int a,b,c D T T L L N OMBRE a b c T IPO ENTERO ENTERO ENTERO D IRECCIÓN 0 2 4 D EFINICIÓN DIRIGIDA POR LA SINTAXIS R EGLA ACCIÓN SEMÁNTICA L.th := T.tipo; anadirTS(id.lexema, T.tipo) → T id L → float T.tipo := REAL → int T.tipo := ENTERO → coma id L L1 .th := L.th; anadirTS(id.lexema, L.th) → Cuando una gramática de atributos tiene acciones que no calculan atributos, se denomina Definición dirigida por la sintaxis (DDS) Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 16 / 35 Definiciones dirigidas por la sintaxis (DDS) Las DDS son como las gramáticas de atributos, pero pueden incluir acciones que no calculen atributos, con efectos secundarios (como guardar símbolos en la tabla de símbolos), por lo que todas las gramáticas de atributos son también DDS De igual manera que existen las gramáticas de atributos por la izquierda (GAI), existen también las definiciones dirigidas por la sintaxis con atributos por la izquierda (DDSI), que son las que permiten la traducción en una sola pasada. IMPORTANTE: las DDS solamente especifican las acciones que es necesario realizar en cada regla, pero no el orden en el que hay que ejecutarlas. Las DDS son una herramienta para el diseño de alto nivel del traductor, sin entrar en los detalles de implementación. El orden de ejecución de las acciones es muy importante Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 17 / 35 Restricciones formales de las acciones semánticas Dada una regla A → α, y una acción semántica b := f (c1 , c2 , . . . , cn ), en una gramática de atributos o en una DDS (o en un ETDS), se tiene que cumplir una de las dos siguientes restricciones: 1 b es un atributo sintetizado de A, y c1 , c2 , . . . , cn son constantes o atributos de los símbolos de la producción (de A o de α) 2 b es un atributo heredado de algún no terminal de α, y c1 , c2 , . . . , cn son constantes o atributos de los símbolos de la producción (de A o de α) Si b es un atributo heredado de un no terminal αi , y se cumple que c1 , c2 , . . . , cn son atributos de A o de otros símbolos αj , con j < i, entonces la gramática de atributos o DDS cumple la condición para ser una GAI o DDSI (si se cumple también en las demás acciones semánticas, por supuesto). Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 18 / 35 Ejemplo 5 de traducción (2) int a,b,c N OMBRE a b c T IPO ENTERO ENTERO ENTERO D IRECCIÓN 0 2 4 E SQUEMA DE TRADUCCIÓN DIRIGIDO POR LA SINTAXIS (ETDS) D → T id {anadirTS(id.lexema, T.tipo); L.th := T.tipo}L T → float {T.tipo := REAL} T → int {T.tipo := ENTERO} L → coma id {anadirTS(id.lexema, L.th); L1 .th := L.th}L L → Un esquema de traducción dirigido por la sintaxis (ETDS) es como una DDSI en la que las acciones semánticas se insertan en la parte derecha de la regla, en el momento exacto del análisis en el que se tienen que ejecutar. Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 19 / 35 Esquema de traducción dirigido por la sintaxis (ETDS) Los ETDS son la herramienta para diseñar traductores de una sola pasada Las acciones semánticas se situan (encerradas entre llaves) en el punto de la parte derecha de la regla en que se deben ejecutar. Se tienen que cumplir las siguientes restricciones: 1 2 3 Un atributo heredado de un símbolo αi de la parte derecha de la regla se debe calcular en una acción semántica situada antes de αi Una acción semántica no puede referirse a un atributo sintetizado de un símbolo situado a la derecha de la acción en la regla Un atributo sintetizado de la parte izquierda de la regla A solo se puede calcular después de haber calculado todos los atributos que se usan para calcularlo (preferentemente al final de la regla). Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 20 / 35 Ejemplo 3 de traducción, con ETDS G RAMÁTICA D T T L L D T T L L R EGLA → T id L → float → int → coma id L → → → → → → DE ATRIBUTOS ACCIÓN SEMÁNTICA L.th := T.trad; D.trad := id.lexema||” : ”||T.trad||L.trad T.trad := ”real” T.trad := ”integer ” L1 .th := L.th; L.trad := ”; ”||id.lexema||” : ”||L.th||L1 .trad L.trad := ”” E SQUEMA DE TRADUCCIÓN DIRIGIDO POR LA SINTAXIS T id {L.th := T.trad}L {D.trad := id.lexema||” : ”||T.trad||L.trad} float {T.trad := ”real”} int {T.trad := ”integer ”} coma id {L1 .th := L.th}L {L.trad := ”; ”||id.lexema||” : ”||L.th||L1 .trad} {L.trad := ””} Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 21 / 35 Implementación de ETDS 1 2 Con un analizador ascendente: hay que utilizar marcadores para implementar las acciones en mitad de la parte derecha y los atributos heredados (lo veremos más adelante). Con un analizador descendente recursivo: I I I I Los atributos sintetizados deben ser devueltos por las funciones de los no terminales (cuando hay más de un atributo es mejor devolver un struct o un objeto con todos los atributos de los no terminales) Los atributos heredados son parámetros que se les pasan a las funciones de los no terminales IMPORTANTE: puede ser necesario almacenar el lexema de los tokens antes de llamar a la función empareja. La traducción de la cadena de entrada es devuelta por la función que analiza el símbolo inicial de la gramática. Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 22 / 35 Implementación de ETDS (2) Ejemplo 3 de traducción, implementado con un ASDR: String L(String th) // L -> coma id L { if (token == COMA) { String idlexema,ltrad; String D() // D -> T id L { String ttrad,idlexema,ltrad; | epsilon emparejar(COMA); idlexema = lexema; emparejar(ID); ltrad = L(th); // L1.th := L.th return ";" + idlexema + ":" + th + ltrad; ttrad = T(); idlexema = lexema; empareja(ID); ltrad = L(ttrad); // L.th := T.trad } else if (token == FINFICHERO) return ""; // L -> epsilon { L.trad := "" } else errorSintactico(....); return idlexema + ":" + ttrad + ltrad; } } Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 23 / 35 Traducción de expresiones aritméticas con ETDS a+b-c+d a+b-c sum(res(sum(a,b),c),d) res(sum(a,b),c) La asociatividad por la izquierda de los operadores ’+’ y ’-’ implica utilizar una gramática con recursividad por la izquierda: E E T T Procesamiento de Lenguajes −→ −→ −→ −→ E op T T id ( E ) Tema 5: Traducción dirigida por la sintaxis 24 / 35 Traducción de expresiones aritméticas con ETDS (2) E E E T T → → → → E op T T id ( E ) a+b-c ⇒ res(sum(a,b),c) Procesamiento de Lenguajes E E a T a id a op sum(a,b) op + res(sum(a,b),c) T b id b - T c id c Tema 5: Traducción dirigida por la sintaxis 25 / 35 Traducción de expresiones aritméticas con ETDS (3) El ETDS quedaría de esta manera: E E T T −→ −→ −→ −→ E op T {E.trad := op.trad||”(”||E1 .trad||”, ”||T.trad||”)”} T {E.trad := T.trad} id {T.trad := id.lexema} ( E ) {T.trad := E.trad} Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 26 / 35 Traducción de expresiones aritméticas con ETDS (4) Si queremos realizar la misma traducción con una gramática sin recursividad por la izquierda (porque por ejemplo queremos usar un ASDR), la gramática sería: E E’ E’ T T Procesamiento de Lenguajes −→ −→ −→ −→ −→ T E’ op T E’ id ( E ) Tema 5: Traducción dirigida por la sintaxis 27 / 35 Traducción de expresiones aritméticas con ETDS (5) E E E’ E’ T T → → → → → T a id a T E’ op T E’ id ( E ) a+b-c ⇒ res(sum(a,b),c) res(sum(a,b),c) E’ op + a res(sum(a,b),c) T id b E’ sum(a,b) res(sum(a,b),c) b op - T id Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis c E’ res(sum(a,b),c) res(sum(a,b),c) c 28 / 35 Traducción de expresiones aritméticas con ETDS (6) El ETDS quedaría: E E’ −→ −→ E’ T T −→ −→ −→ T {E’.th := T.trad}E’ {E.trad := E’.trad} op T {E10 .th := op.trad||”(”||E 0 .th||”, ”||T.trad||”)”} E’ {E’.trad := E10 .trad} {E’.trad := E’.th} id {T.trad := id.lexema} ( E ) {T.trad := E.trad} Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 29 / 35 Ejercicio 1 (examen febrero 1998) (1 de 2) Diseña un ETDS para traducir declaraciones de funciones en C a Pascal. El proceso de traducción se puede especificar con los siguientes ejemplos de traducción: int f(void), g(float a,int *b); function f:integer; function g(a:real;var b:integer):integer; void h(int a,float *c), j(void); procedure h(a:integer;var c:real); procedure j; float f(int a); function f(a:integer):real; int f(int a,int b,int c), g(int d), h(int e); function f(a:integer;b:integer;c:integer):integer; function g(d:integer):integer; function h(e:integer):integer; Procesamiento de Lenguajes Tema 5: Traducción dirigida por la sintaxis 30 / 35 Ejercicio 1 (examen febrero 1998) (2 de 2) Debes diseñar el ETDS utilizando como base la siguiente gramática, que genera el lenguaje fuente: S TipoFun TipoFun TipoFun L Lp Lp F A A M M Argu Argu Tipo Tipo Procesamiento de Lenguajes −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ TipoFun L puntoycoma void int float F Lp coma F Lp ident lpar A rpar void Argu M coma Argu M Tipo ident Tipo asterisco ident int float Tema 5: Traducción dirigida por la sintaxis 31 / 35 Ejercicio 2 (examen marzo 1997) (1 de 2) Diseña un ETDS para traducir declaraciones de funciones y procedimientos anidados en Pascal a C. El proceso de traducción se puede especificar con los siguientes ejemplos de traducción: function f:integer; codigo endfunc; int f(); procedure p1; procedure p2; codigo endproc; codigo endproc; void p1(); void p1_p2(); Procesamiento de Lenguajes procedure p1; procedure p2; codigo endproc; function f1:real; codigo endfunc; procedure p3; procedure p4; codigo endproc; codigo endproc; codigo endproc; Tema 5: Traducción dirigida por la sintaxis void p1(); void p1_p2(); float p1_f1(); void p1_p3(); void p1_p3_p4(); 32 / 35 Ejercicio 2 (examen marzo 1997) (2 de 2) Debes diseñar el ETDS utilizando como base la siguiente gramática, que genera el lenguaje fuente: S P P L L T T −→ −→ −→ −→ −→ −→ −→ Procesamiento de Lenguajes P procedure id ; L endproc ; function id : T ; L endfunc ; P L codigo integer real Tema 5: Traducción dirigida por la sintaxis 33 / 35 Ejercicio 3 (1 de 2) Dada la siguiente gramática (que permite declarar clases anidadas y sus métodos para un determinado lenguaje orientado a objetos): S C B B V V P P D D L L T T Procesamiento de Lenguajes −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ −→ C class id { B V } public : P private : P D P T id ( T id L ) C , T id L int float Tema 5: Traducción dirigida por la sintaxis 34 / 35 Ejercicio 3 (2 de 2) Construye un ETDS que traduzca a una notación como la indicada en este ejemplo: class A { public: int f1(int n,float s) private: class B { private: float f2 (float r,float s,float t) class C {} } } Procesamiento de Lenguajes clase A { público: A::f1 (entero x real -> entero) privado: clase A::B { privado: A::B::f2 (real x real x real -> real) clase A::B::C {} } } Tema 5: Traducción dirigida por la sintaxis 35 / 35