Interpretación y Compilación - Departamento de Lenguajes y

Anuncio
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
INTERPRETACIÓN Y COMPILACIÓN
OBJETIVO
Problemas para consolidar el diseño y construcción de intérpretes y compiladores.
PROBLEMA 1: CALCPROG
Supongamos un lenguaje llamado CALCPROG para programar secuencias de órdenes. La
orden puede ser: expresión entera, asignación o declaración de función. Las declaraciones de
funciones están restringidas a un parámetro. A continuación se muestra un programa de ejemplo
CALCPROG y su interpretación.
3 + (4 + 1);
// expresión
a = 1 + 1;
// asignación
f(a) = 10 * a;
// declaración de función
f(a);
// expresión
g(x) = 10*f(x) + a; // declaración de función
g(3);
// expresión
f(f(2));
// expresión
f(a+1);
// expresión
Expresión:
Asignación:
Función: f(
Expresión:
Función: g(
Expresión:
Expresión:
Expresión:
(
a
a
(
x
(
(
(
+ 3 ( +
vale 2
) vale
LLAMADA
) vale
LLAMADA
LLAMADA
LLAMADA
4 1 ) ) vale 8
(
f
(
g
f
f
*
a
+
3
(
(
10 a )
) vale 20
( * 10 ( LLAMADA f x ) ) a )
) vale 302
LLAMADA f 2 ) ) vale 200
+ a 1 ) ) vale 30
SE PIDE: Intérprete para programas CALCPROG. La solución se debe construir con un treeparser. Suponer que el análisis léxico-sintáctico se ha resuelto con los lexer y parser propuestos
en la solución del problema 3 del documento LAB-LEX-SINT.
Solución:
header{
import java.io.*;
import java.util.*;
import antlr.*;
}
class Anasint2 extends TreeParser;
1
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
options{
importVocab=Anasint;
}
{
Hashtable tabla_variables = new Hashtable();
Hashtable tabla_parametros = new Hashtable();
Hashtable tabla_funciones = new Hashtable();
ASTFactory af = new ASTFactory();
void sustituir(AST expresion, AST parametro_formal, int
parametro_real){
// Pre: 'expresion' es el AST asociado a una expresion
//
'parametro_formal' es el AST asociado a un parametro formal
//
'parametro_real' parametro real de tipo entero
switch(expresion.getType()){
case MAS:
case MENOS:
case POR:
case DIV:
sustituir(expresion.getFirstChild(), parametro_formal,
parametro_real);
sustituir(expresion.getFirstChild().getNextSibling(),
parametro_formal, parametro_real);
break;
case LLAMADA: sustituir(expresion.getFirstChild().getNextSibling(),
parametro_formal, parametro_real);
break;
case IDENT: if
(expresion.getText().equals(parametro_formal.getText())){
expresion.setType(NUMERO);
expresion.setText(new
Integer(parametro_real).toString());
}
break;
default: break;
}
}
// Post: toda ocurrencia de 'parametro_formal' en 'expresion' se
sustituye por 'valor'.
int evaluarVariable(AST variable){
// Pre: 'variable' es una variable en formato AST.
if (tabla_variables.containsKey(variable.getText()))
try{
return
this.expresion((AST)tabla_variables.get(variable.getText()));
}catch(RecognitionException e)
{System.out.println("error sintáctico"+e.getMessage());
return 0;}
else
return 0;
// Post: se devuleve el valor de 'variable' almacenado en
'tabla_variables'. Si la
//
variable no se almecenó, se devuelve 0.
}
2
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
int evaluarFuncion(AST def_funcion, AST parametro_formal, int
parametro_real){
// Pre: 'def_funcion' es la expresion correspondiente a la definicion de
una funcion.
//
'parametro_formal' es el parametro formal de la función.
//
'parametro_real' es el parametro real de tipo entero.
try{
switch(def_funcion.getType()){
case MAS:
return evaluarFuncion(def_funcion.getFirstChild(),
parametro_formal, parametro_real)
+
evaluarFuncion(def_funcion.getFirstChild().getNextSibling(),
parametro_formal, parametro_real);
case MENOS:
return evaluarFuncion(def_funcion.getFirstChild(),
parametro_formal, parametro_real)
evaluarFuncion(def_funcion.getFirstChild().getNextSibling(),
parametro_formal, parametro_real);
case POR:
return evaluarFuncion(def_funcion.getFirstChild(),
parametro_formal, parametro_real)
*
evaluarFuncion(def_funcion.getFirstChild().getNextSibling(),
parametro_formal, parametro_real);
case DIV:
return evaluarFuncion(def_funcion.getFirstChild(),
parametro_formal, parametro_real)
/
evaluarFuncion(def_funcion.getFirstChild().getNextSibling(),
parametro_formal, parametro_real);
case LLAMADA: if
(tabla_funciones.containsKey(def_funcion.getFirstChild().getText())){
AST aux1 =
af.dupTree((AST)tabla_funciones.get(def_funcion.getFirstChild().getText()));
AST aux2 =
af.dupTree((AST)tabla_parametros.get(def_funcion.getFirstChild().getText()));
sustituir(aux1,aux2,parametro_real);
return this.expresion(aux1);
}
else return 0;
case IDENT: if
(def_funcion.getText().equals(parametro_formal.getText()))
return parametro_real;
else
return this.expresion(def_funcion);
case NUMERO: return this.expresion(def_funcion);
default: return 0;
}
}catch(RecognitionException e)
{System.out.println("error sintáctico"+e.getMessage()); return
0;}
}
3
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
// Post: Se devuelve la evaluación de 'def_funcion' previa sustitucion de
toda ocurrencia del 'parametro_formal'
//
por 'parametro_real'.
void actualizarVariables(AST variable, AST expresion){
// Pre: 'variable' es el AST de una variable y 'valor' es el AST de una
expresion.
tabla_variables.put(variable.getText(),af.dupTree(expresion));
// Post: 'tabla_variables' se actualiza con la entrada (variable,
expresion).
}
void actualizarFunciones(AST nombre_funcion, AST parametro_formal, AST
expresion){
// Pre: 'nombre_funcion' es el AST correspondiente al nombre de la
funcion.
//
'parametro_formal' es el AST correspondiente al parametro formal
de la función.
//
'expresion' es la expresión que define la función.
tabla_funciones.put(nombre_funcion.getText(),af.dupTree(expresion));
tabla_parametros.put(nombre_funcion.getText(),af.dupTree(parametro_formal));
// Post: 'tabla_funciones' se actualiza con la entrada (nombre_funcion,
expresion).
//
'tabla_parametros' se actualiza con la entrada (nombre_funcion,
parametro_formal).
}
}
ordenes: #(ORDENES (orden)+)
;
orden {int r;}: def_funcion
| asignacion
| r = e:expresion {System.out.println("Expresión:
"+e.toStringTree()+" vale "+r);}
;
def_funcion {int r;}: #(DEF_FUNCION a:IDENT b:IDENT r=c:expresion)
{ actualizarFunciones(a,b,c);
System.out.println("Función:
"+a.getText()+"("+b.toStringTree()+" )"+" vale "+c.toStringTree());}
;
asignacion {int r;}: #(ASIG a:IDENT r=b:expresion)
{ actualizarVariables(a,b);
System.out.println("Asignación: "+a.getText()+"
vale "+r);}
;
expresion returns [int valor=0;] {int r,s;}:
#(MAS r=expresion s=expresion){valor = r + s;}
| #(MENOS r=expresion s=expresion){valor = r - s;}
| #(POR r=expresion s=expresion){valor = r * s;}
| #(DIV r=expresion s=expresion){valor = r / s;}
| #(LLAMADA f:IDENT r=expresion)
{valor = evaluarFuncion((AST)tabla_funciones.get(f.getText()),
4
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
(AST)tabla_parametros.get(f.getText()),
r);}
| i:IDENT { valor = evaluarVariable(i);}
| j:NUMERO { valor = new Integer(j.getText()).intValue();}
;
exception catch [ArithmeticException e]{ valor = 0; }
5
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
PROBLEMA 2: LENGUAJE LEXCHANGE
Supongamos un lenguaje llamado LEXCHANGE para programar transferencias de datos entre
dos bases de datos relacionales. Un programa típico en LEXCHANGE incluye: (a) esquema de
datos fuente, (b) datos fuente, (c) esquema de datos destino y un conjunto de restricciones
especificando la transferencia de datos entre la fuente y el destino. Todos los datos son de tipo
cadena de caracteres. Las restricciones son implicaciones lógicas con antecedente formado por
un átomo definido sobre una relación del esquema fuente y un consecuente formado por un
átomo definido sobre una relación del esquema destino (ver programa de ejemplo). Hay dos
clases de variables en una restricción, las que sólo aparecen en el consecuente y las demás. Las
primeras se suponen cuantificadas existencialmente y las segundas universalmente.
Ejemplo. Programa LEXCHANGE.
ESQUEMA FUENTE
estudiante(NOMBRE, NACIMIENTO, DNI)
empleado(NOMBRE, DNI, TELEFONO)
DATOS FUENTE
estudiante(Axel,1980,12122345)
estudiante(Lorenzo,1982,10345321)
estudiante(Antonio,1979,87654456)
empleado(Axel,12122345,616234345)
empleado(Manuel,50545318,617876654)
ESQUEMA DESTINO
persona(NOMBRE, NACIMIENTO, DNI, TELEFONO)
RESTRICCIONES
VAR x,y,z,u;
estudiante(x,y,z) implica persona(x,y,z,u)
VAR x,y,z,u;
empleado(x,y,z) implica persona(x,u,y,z)
La ejecución del anterior programa transfiere los siguientes datos a la base de datos destino.
persona(Axel,1980,12122345,X1)
persona(Lorenzo,1982, 10345321,X2)
persona(Antonio,1979, 87654456,X3)
persona(Axel,X4,12122345, 616234345)
persona(Manuel,X5,50545318,617876654)
Cada dato Xi representa la instanciación de una variable cuantificada existencialmente en una
restricción.
SE PIDE: Intérprete de programas LEXCHANGE. Se debe construir la solución con un treeparser. Suponer que el análisis léxico-sintáctico se ha resuelto con los lexer y parser propuestos
6
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
en la solución del problema 2 del documento LAB-LEX-SINT y el análisis semántico se ha
resuelto con el parser propuesto en la solución del problema 2 del documento LAB-SEM.
class Anasint extends Parser;
options{
buildAST = true; // Construcción de asa
}
tokens{
ENTRADA;
ESQUEMAFUENTE;
ESQUEMADESTINO;
DATOSFUENTE;
RESTRICCION;
}
//REGLAS
entrada :
esquema_fuente datos_fuente esquema_destino restricciones EOF!
{#entrada = #(#[ENTRADA, "ENTRADA"], ##);}
;
esquema_fuente : ESQUEMA! FUENTE! (signatura)+
{#esquema_fuente = #(#[ESQUEMAFUENTE, "ESQUEMA FUENTE"], ##);}
;
signatura: IDENT^ PA! atributos PC!
;
atributos:(IDENT COMA) => IDENT COMA! atributos
| IDENT
;
datos_fuente: DATOS! FUENTE! (a:atomo)+
{#datos_fuente = #(#[DATOSFUENTE, "DATOS FUENTE"], ##);}
;
esquema_destino: ESQUEMA! DESTINO! (signatura)+
{#esquema_destino = #(#[ESQUEMADESTINO, "ESQUEMA DESTINO"], ##);}
;
restricciones: RESTRICCIONES^ (restriccion)+
;
restriccion: variables implicacion
{#restriccion = #(#[RESTRICCION, "RESTRICCION"], ##);}
;
variables: VAR^ vars PyC!
;
vars: (IDENT COMA) => IDENT COMA! vars
| IDENT
;
implicacion: atomo IMPLICA^ atomo
;
atomo: IDENT^ PA! terminos PC! ;
terminos: (termino COMA)=> termino COMA! terminos
7
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
| termino
;
termino: IDENT
| NUMERO
;
Solución:
header{
import java.util.*;
import java.io.*;
import antlr.*;
}
class Anasint2 extends TreeParser;
options
{
importVocab = Anasint;
}
{
FileWriter f;
int cont=1;
void abrirFichero(){
try{f = new FileWriter("salida.txt");}
catch(IOException e){System.out.println(e.toString());}
}
void cerrarFichero(){
try{f.close();}
catch(IOException e){System.out.println(e.toString());}
}
void escribirFicheroSalida(AST consecuente,
Hashtable<String,String> sustituciones){
//Pre: sustituciones representa las sustituciones llevadas a cabo en el
//
antecedente de la restricción.
try{
f.write(consecuente.getText());
f.write("(");
AST argumento = consecuente.getFirstChild();
while (argumento!=null){
boolean enc = false;
if (sustituciones.containsKey(argumento.getText()))
f.write(sustituciones.get(argumento.getText()));
else{
f.write("X"+cont);
cont++;
}
argumento = argumento.getNextSibling();
if (argumento!=null)
f.write(",");
}
f.write(")\n");
}catch(IOException e){System.out.println(e.toString());}
}
//Post: se escribe en salida.txt la instanciación de consecuente según
8
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
//las sustituticiones contenidas en sustituciones.
Hashtable<String,String> matchingAntecedenteAtomo(AST antecedente,
AST atomo){
//Pre: antecedente y atomo definido sobre el mismo predicado
Hashtable<String,String> resultado =
new Hashtable<String,String>();
AST termino = atomo.getFirstChild();
AST variable = antecedente.getFirstChild();
while (variable!=null){
resultado.put(variable.getText(),termino.getText());
System.out.println(variable.getText()+"
"+atomo.getText());
variable = variable.getNextSibling();
termino = termino.getNextSibling();
}
return resultado;
//Post: cada variable de antecedente se le asocia el término
//correspondiente de atomo
}
void matchingRestriccionDatosFuentes(AST implicacion, AST datos){
//Pre: dada una implicación y el conjunto de datos fuente
System.out.println(implicacion.toStringList());
System.out.println(datos.toStringList());
Hashtable<String,String> aux;
AST atomoFuente = datos.getFirstChild();
while (atomoFuente!=null){
if
((atomoFuente.getText()).equals((implicacion.getFirstChild()).getText())){
aux = matchingAntecedenteAtomo(implicacion.getFirstChild(),
atomoFuente);
System.out.println(aux.toString());
escribirFicheroSalida(implicacion.getFirstChild().getNextSibling(),aux);
aux.clear();
}
atomoFuente = atomoFuente.getNextSibling();
}
//Post: genera el fichero salida.txt aplicado la restricción a cada
// átomo en datos.
//Las variables existenciales generan en el fichero de salida
//variables Xi.
}
}
entrada :{abrirFichero();}
#(ENTRADA esquema_fuente a:datos_fuente esquema_destino
restricciones[a])
{cerrarFichero();}
;
esquema_fuente: #(ESQUEMAFUENTE (signatura)+)
;
datos_fuente: #(DATOSFUENTE (atomo)*)
;
esquema_destino: #(ESQUEMADESTINO (signatura)+)
;
restricciones[AST datosFuentes]: #(RESTRICCIONES
(restriccion[datosFuentes])+)
9
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
;
restriccion[AST datosFuentes]: #(RESTRICCION variables a:implicacion)
{matchingRestriccionDatosFuentes(a, datosFuentes);}
;
signatura: #(IDENT (IDENT)*)
;
variables: #(VAR (IDENT)*)
;
implicacion: #(IMPLICA atomo atomo)
;
atomo: #(IDENT (termino)*)
;
termino: IDENT
| NUMERO
;
10
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
11
PROBLEMA 3: EL LENGUAJE OWL
OWL es un lenguaje diseñado para expresar ontologías en la web. Una ontología es un conjunto
de declaraciones que describen un dominio de interés. En este ejercicio se consideran 4 tipos de
declaraciones:
Asertos de clase: formalizan la pertenencia de un individuo a una clase de individuos.
Ejemplo:
ClassAssertion(Person Mary)
ClassAssertion(Woman Mary)
// Mary es una persona
// Mary es una mujer
Asertos de propiedad: formalizan una determinada relación entre dos individuos.
Ejemplo:
ObjectPropertyAssertion(hasWife John Mary)
esposa de John
// Mary es la
Jerarquía de clase: formalizan una relación de inclusión entre dos clases de individuos.
Ejemplo: SubClassOf(Mother Woman)
//Toda madre es una mujer
Definición de clase: formaliza la definición de una clase primitiva.
Ejemplo:
EquivalentClasses(Person
equivale a ser humano
Human)
//persona
(clase
primitiva)
Aparte de las clases primitivas tales como Woman o Person, OWL dispone de operadores
adicionales para formalizar el concepto clase de individuo:
Clase de individuo expresada mediante operador lógico de intersección, unión y
complemento:
Ejemplo:
ObjectIntersectionOf(Woman Mother) // individuos que son
mujeres y madres
ObjectUnionOf(Father Mother GrandFather) // individuos que son
padres, madres o abuelos
ObjectComplementOf(Father) // individuos que no son padres
Clase expresadas mediante restricción sobre propiedad:
Ejemplo: ObjectSomeValuesFrom(hasChild Happy)
hijo feliz
ObjectAllValuesFrom(hasChild Happy)
sus hijos felices
// individuos con algún
// individuos con todos
Ejemplo de ontología OWL:
ClassAssertion(Person Mary) // Mary es una persona
SubClassOf(Woman Person) //Toda mujer es una persona
SubClassOf(Mother Woman)
//Toda madre es una mujer
ClassAssertion(Person John) // John es una persona
SubClass(HappyMother
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
ObjectIntersectionOf(Mother ObjectAllValuesFrom(hasChild
Happy)))
// Madre feliz es una madre con todos sus hijos felices
Dado el siguiente parser ANTLR para OWL,
class Anasint extends Parser;
options{
buildAST=true;
}
tokens{
ONTOLOGY;
}
ontologia : (declaracion)* EOF!
{ #ontologia = #(#[ONTOLOGY,"Ontology"], ##);}
;
declaracion : aserto_clase
| aserto_propiedad
| subclase
| definicion
;
aserto_clase : CLASS_ASSERTION^ PA! clase_primitiva individuo PC!
;
aserto_propiedad : OBJECT_PROPERTY_ASSERTION^ PA! propiedad individuo
individuo PC!
;
subclase : SUB_CLASS_OF^ PA! clase clase PC!
;
definicion : EQUIVALENT_CLASSES^ PA! clase_primitiva clase PC!
;
individuo : IDENT
;
propiedad : IDENT
;
clase : clase_primitiva
| restriccion_existencial
| restriccion_universal
| union
| interseccion
| complementario
;
clase_primitiva : IDENT
;
restriccion_existencial : OBJECT_SOME_VALUES_FROM^ PA! propiedad clase PC!
;
restriccion_universal : OBJECT_ALL_VALUES_FROM^ PA! propiedad clase PC!
;
union : OBJECT_UNION_OF^ PA! clase (clase)+ PC!
;
interseccion : OBJECT_INTERSECTION_OF^ PA! clase (clase)+ PC!
;
complementario : OBJECT_COMPLEMENT_OF^ PA! clase PC!
12
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
SE PIDE:
(1) Construir un TreeParser ANTLR que reconozca los árboles de sintaxis abstracta
generados por el Parser ANTLR dado (2 puntos).
(2) Anotar el TreeParser del apartado (1) para que compile en formulas lógicas una
ontología OWL (3 puntos).
La compilación de una ontología OWL se define como la compilación de cada una de
sus declaraciones. La compilación de una declaración se define formalmente de la
siguiente manera.
(a) ClassAssertion(C I) se compila a la formula lógica C(I)
(b) ObjectPropertyAssertion(P I1 I2) se compila a la formula lógica P(I1,I2)
(c) SubClassOf(C1 C2) se compila a la formula lógica forall x (F(C1,x) implies F(C2,x)).
EquivalentClasses(C1 C2) se compila a la formula lógica forall x (F(C1,x) equiv
F(C2,x)).
Siendo
F(C,x) = C(x) si C una clase primitiva.
F(ObjectSomeValuesFrom(P C), x)= exists y (P(x,y) and F(C,y)) siendo y una
variable nueva.
F(ObjectAllValuesFrom(P C), x)= forall y (P(x,y) implies F(C,y)) siendo y una
variable nueva.
F(ObjectUnionOf(C1,…,Cn), x)= F(C1, x) or … or F(Cn, x).
F(ObjectIntersectionOf(C1,…,Cn), x)= F(C1, x) and … and F(Cn, x).
F(ObjectComplementOf(C), x)= not F(C, x).
Ejemplo de traducción:
(ontología)
ClassAssertion(Person Mary)
SubClassOf(Woman Person)
SubClassOf(Mother Woman)
ClassAssertion(Person John)
EquivalentClasses(HappyMother
ObjectIntersectionOf(Mother ObjectAllValuesFrom(hasChild Happy)))
(fórmulas lógicas)
Person(Mary)
forall x0 (Woman(x0) implies Person(x0))
forall x0 (Mother(x0) implies Woman(x0))
13
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
Person(John)
forall x0 (HappyMother(x0) equiv Mother(x0) and
Happy(x1)))
forall x1 (hasChild(x0,x1) implies
Solución:
(1)
class Anasint2 extends TreeParser;
options{
importVocab=Anasint;
}
ontologia : #(ONTOLOGY (declaracion)*)
;
declaracion :
|
|
|
;
aserto_clase
aserto_propiedad
subclase
definicion
aserto_clase : #(CLASS_ASSERTION individuo clase)
;
aserto_propiedad : #(OBJECT_PROPERTY_ASSERTION propiedad individuo
individuo)
;
subclase : #(SUB_CLASS_OF clase clase)
;
definicion : #(EQUIVALENT_CLASSES clase_primitiva clase)
;
individuo : IDENT
;
propiedad : IDENT
;
clase : clase_primitiva
| restriccion_existencial
| restriccion_universal
| union
| interseccion
| complementario
;
clase_primitiva : IDENT
;
restriccion_existencial : #(OBJECT_SOME_VALUES_FROM propiedad clase)
;
restriccion_universal : #(OBJECT_ALL_VALUES_FROM propiedad clase)
;
union : #(OBJECT_UNION_OF clase (clase)+)
;
interseccion : #(OBJECT_INTERSECTION_OF clase (clase)+)
;
complementario : #(OBJECT_COMPLEMENT_OF clase)
;
14
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
(2)
header{
import java.util.*;
import java.io.*;
import antlr.*;
}
class Anasint4 extends TreeParser;
options{
importVocab=Anasint;
}
{
FileWriter f; }
ontologia {String r;}:
{try{f = new FileWriter("output");}catch(IOException e) {}}
#(ONTOLOGY ( r=declaracion {try{f.write(r);}catch(IOException
e) {}})*)
{try{f.close();} catch(IOException e) {}}
;
declaracion returns [String r = null] :
r=aserto_clase
| r=aserto_propiedad
| r=subclase[0]
| r=definicion[0]
;
aserto_clase returns [String r = null] :
#(CLASS_ASSERTION c:IDENT i:IDENT) { r=new
String(c.getText()+"("+i.getText()+")\n");}
;
aserto_propiedad returns [String r = null] :
#(OBJECT_PROPERTY_ASSERTION p:IDENT i1:IDENT i2:IDENT)
{ r=new
String(p.getText()+"("+i1.getText()+","+i2.getText()+")\n");}
;
subclase [int cont] returns [String r = null] {String c1, c2;}:
#(SUB_CLASS_OF c1=clase[cont] c2=clase[cont])
{r=new String("forall x"+cont+"("+c1+" implies "+ c2+")\n");}
;
definicion [int cont] returns [String r = null] {String c1, c2;}:
#(EQUIVALENT_CLASSES c1=clase_primitiva[cont] c2=clase[cont])
{r=new String("forall x"+cont+"("+c1+" equiv "+ c2+")\n");}
;
individuo returns [String r = null]: a:IDENT {r = new
String(a.getText());}
;
propiedad returns [String r = null]: a:IDENT {r = new
String(a.getText());}
;
clase [int cont] returns [String r = null]: r=clase_primitiva[cont]
| r=restriccion_existencial[cont]
| r=restriccion_universal[cont]
| r=union[cont]
| r=interseccion[cont]
| r=complementario[cont]
;
15
Departamento de Lenguajes y Sistemas Informáticos
Procesadores de Lenguajes
clase_primitiva[int cont] returns [String r = null]: a:IDENT {r = new
String(a.getText()+"(x"+cont+")");}
;
restriccion_existencial[int cont] returns [String r = null] {String p,
c;}:
#(OBJECT_SOME_VALUES_FROM p=propiedad c=clase[cont+1])
{r=new String("exists x"+(cont+1)+"("+p+"("+"x"+cont+",
x"+(cont+1)+") and "+c+")");}
;
restriccion_universal [int cont] returns [String r = null] {String p,
c;}:
#(OBJECT_ALL_VALUES_FROM p=propiedad c=clase[cont+1])
{r=new String("forall x"+(cont+1)+"("+p+"("+"x"+cont+",
x"+(cont+1)+") implies "+c+")");}
;
union [int cont] returns [String r = null] {String c1, c2, c3, aux;}:
#(OBJECT_UNION_OF c1=clase[cont]
{c2 = new String();}
(c2=clase[cont] {c2 = " or "+c2;} )+)
{r=new String("("+c1+c2+")");}
;
interseccion [int cont] returns [String r = null] {String c1, c2, c3,
aux;}:
#(OBJECT_INTERSECTION_OF c1=clase[cont]
{c2 = new String();}
(c2=clase[cont] {c2 = " and "+c2;} )+)
{r=new String("("+c1+c2+")");}
;
complementario [int cont] returns [String r = null] :
#(OBJECT_COMPLEMENT_OF r=clase[cont]) {r=new String("not"+r);}
;
16
Descargar