Traductores EDT con ANTLR

19
Traductores EDT con ANTLR

description

Traductores EDT con ANTLR. La gramática. t ::= f t1 t1 ::= OPMULT f t1 | OPDIV f t1 | λ f ::= | ( e ) | NUMERO. a ::= e ; a | λ e ::= t e1 e1 ::= OPSUMA t e1 | OPRESTA t e1 | λ. Las acciones semánticas. En negrita se muestran las acciones semánticas para cada producción. - PowerPoint PPT Presentation

Transcript of Traductores EDT con ANTLR

Page 1: Traductores EDT con ANTLR

Traductores EDT con ANTLR

Page 2: Traductores EDT con ANTLR

La gramática

• a ::= e ; a

| λ

• e ::= t e1

• e1 ::= OPSUMA t e1

| OPRESTA t e1

| λ

•t ::= f t1

•t1 ::= OPMULT f t1| OPDIV f t1| λ

•f ::= | ( e )| NUMERO

Page 3: Traductores EDT con ANTLR

Las acciones semánticas

• a : exp=e SEMICOLON { System.out.println("\n\nReconocida expresión aritmética. Valor final: " + $exp.res); } a

| ;

En negrita se muestran las acciones semánticas para cada producción.

Para esta primera producción, el resultado de la operación matemática llegará a exp, el atributo de e, y este valor se mostrará por pantalla.

Page 4: Traductores EDT con ANTLR

Las acciones semánticas

El no terminal e va a devolver (subir hacia arriba) el resultado de la operación. Este resultado le vendrá dado del otro no terminal e1. Por este motivo la acción semántica iguala $eres.res (resultado de e1) a $res (valor que devuelve e). Pero para que e1 pueda realizar la parte izquierda de la operación, necesita el resultado de la parte derecha, y este vendrá dado por t. Se puede ver que e1 recibe como atributo heredado $tt.res.

• e returns [int res]: tt=t eres=e1[$tt.res] {$res = $eres.res;};

En el resto de producciones se puede ver el mismo método para operar. Se calcula la parte derecha de la operación, ésta se pasa como atributo heredado a la parte izquierda, y esta parte izquierda realizará otra operación con un nuevo operando. Cuando se llegue a un caso en el que no haya más partes izquierdas (más operandos), habrá que subir el resultado hacia arriba.

Page 5: Traductores EDT con ANTLR

Las acciones semánticas

En las dos primeras producciones se realizan la suma o la resta. El valor recibido en tt (como atributo heredado) se suma/resta al siguiente operando y este resultado se le pasa a e1.

• e1[int tt] returns [int res]: OPSUMA t2=t {int aux = $tt + $t2.res;} eres=e1[aux] {$res = $eres.res;}| OPRESTA t2=t {int aux = $tt - $t2.res;} eres=e1[aux] {$res = $eres.res;}| {$res = $tt;};

En esta última producción ya no hay más operandos y simplemente se devuelve el valor hacia arriba.

Page 6: Traductores EDT con ANTLR

Las acciones semánticas

Esta producción es parecida a la de e. Primero se coge el valor de f, valor que vendrá sintetizado desde abajo. Este número se le pasa a la parte izquierda de la operación. Se consigue pasándolo como atributo heredado de t1 (t1[$num1.res]).

• t returns [int res]:

num1=f tres=t1[$num1.res]

{$res = $tres.res;};

Cuando t1 tenga el resultado, lo subirá hacia arriba asignándoselo a $res, que es el atributo que t subirá.

Page 7: Traductores EDT con ANTLR

Las acciones semánticas

En estas producciones se realizan las multiplicaciones y divisiones. Como antes el resultado de las operaciones anteriores vendrá dado, en este caso en n1. Con este valor y el siguiente operando (n2) se realizará la operación correspondiente. El valor de n2 viene sintetizado de abajo. Cuando se a operado, se pasa el valor a la parte izquierda.

• t1[int n1] returns [int res]:OPMULT n2=f {int aux = $n1 * $n2.res;} tres = t1[aux] {$res = $tres.res;}| OPDIV n2=f {int aux = $n1 / $n2.res;} tres=t1[aux] {$res = $tres.res;}| {$res = $n1;} ;

Cuando no hay más operandos, se sube el valor hacia arriba. Esto lo hace la última producción.

Page 8: Traductores EDT con ANTLR

Las acciones semánticas

Finalmente se llega a la producción f que es la que lee los operandos de la cadena de entrada, o la que recibe el resultado de una operación que estaba entre paréntesis.

• f returns [int res = 0]:

| '(' exp=e ')' {$res = $exp.res;}

| num=NUMERO {$res = Integer.parseInt($num.text);} ;

En el primer caso, este valor de la cadena de entrada se pasa a entero y se transmite hacia arriba a través de $res. En el segundo caso simplemente se pasa el valor de la expresión hacia arriba.

Page 9: Traductores EDT con ANTLR

Ejemplo

• (1+5*5)-8/2;

• Este ejemplo tiene una operación de cada tipo: suma, resta, multiplicación, división y paréntesis. El árbol sintáctico resultante es el siguiente:

Page 10: Traductores EDT con ANTLR

Ejemplo: Árbol sintáctico

A continuación se va a mostrar el comportamiento de las acciones semánticas para resolver este ejemplo.

Page 11: Traductores EDT con ANTLR

Ejemplo: Árbol sintáctico

Se van aplicando producciones hasta que llegamos a la producción:

• f returns [int res = 0]:| num=NUMERO {$res = Integer.parseInt($num.text);} ;

Entonces se coge el número de la cadena de entrada.

Page 12: Traductores EDT con ANTLR

Ejemplo: Árbol sintácticoComo el siguiente carácter de la cadena es un “+”, t1 deriva en λ.

• t1[int n1] returns [int res]: | {$res = $n1;} ;

T1 ha recibido el valor de f, a través de n1. Cuando t1 calcula las operaciones inferiores (en este caso ninguna) sube el valor hacia arriba con $res.

Page 13: Traductores EDT con ANTLR

Ejemplo: Árbol sintáctico

El resultado de t se pasa heredado a e1:

• e returns [int res]:

tt=t eres = e1[$tt.res]

Después se coge el siguiente número y se pasa de f a t1.

Page 14: Traductores EDT con ANTLR

Ejemplo: Árbol sintácticoEn esta producción se realiza una multiplicación. Se realiza antes que la suma porque tiene mayor precedencia. El resultado se pasa hacia abajo como atributo heredado.

• t1[int n1] returns [int res]:OPMULT n2=f {int aux = $n1 * $n2.res;} tres=t1[aux] {$res = $tres.res;}

Page 15: Traductores EDT con ANTLR

Ejemplo: Árbol sintácticoComo no hay más operandos t1 sube el valor que ha recibido de f hacia arriba. Lo mismo hace su antecedente t1:

• t1[int n1] returns [int res]:| {$res = $n1;} ;

En este momento es cuando se realiza la suma:

• e1[int tt] returns [int res]: OPSUMA t2=t {int aux = $tt + $t2.res;} eres=e1[aux] {$res = $eres.res;}

Page 16: Traductores EDT con ANTLR

Ejemplo: Árbol sintácticoe1 recibe el resultado de t, pero como no hay más operaciones en el paréntesis, sube el resultado hacia arriba:

• e1[int tt] returns [int res]:| {$res = $tt;};

Page 17: Traductores EDT con ANTLR

Ejemplo: Árbol sintáctico

El proceso se va repitiendo todo el rato. Cada vez que llega un número en la cadena de entrada, este se sube hasta f. Una vez aquí se pasa como atributo heredado para que la siguiente producción haga su trabajo.

Page 18: Traductores EDT con ANTLR

Ejemplo: Árbol sintácticoComo se ve en la imagen, el número se sube hasta f y se opera. El resultado se pasa como atributo heredado a t1:

• t1[int n1] returns [int res]:| OPDIV n2=f {int aux = $n1 / $n2.res;} tres=t1[aux] {$res = $tres.res;}

Como no hay más operaciones que realizar el resultado se va subiendo hacia arriba con atributos sintetizados.

Page 19: Traductores EDT con ANTLR

Ejemplo: Árbol sintácticoFinalmente se realiza la última operación. Este resultado, como en todos los casos anteriores se pasa como atributo heredado hacia el hermano. Este que ya no tiene más cálculos que hacer devuelve el resultado hacia arriba. Este resultado sube hasta llegar al final y se muestra por pantalla:

• a: exp=e SEMICOLON { System.out.println("\n\nReconocida expresión aritmética. Valor final: " + $exp.res);} a

“Reconocida expresión aritmética. Valor final: 22”