PROCESADORES DEL LENGUAJES Septiembre 2015 Lenguaje SEQ-O2. Análisis Sintáctico. class Anasint extends Parser; options{ k=2; buildAST=true; } tokens{ VINCULACION; SELECCION; } programa: PROGRAMA^ declaraciones instrucciones ; declaraciones: DECLARACIONES^ clases relaciones ; clases: (clase)* ; clase : ID^ CA! (atributos)? CC! PyC! ; atributos: (ID COMA)=> ID COMA! atributos | ID ; relaciones : (relacion)* ; relacion : ID (EXT_CONS^ | EXT_NO_CONS^) ID PyC! ; instrucciones: INSTRUCCIONES^ (instruccion)* ; instruccion: (vinculacion|seleccion) PyC! ; vinculacion!: a:ID DP b:ID {#vinculacion = #(#[VINCULACION,"VINCULACION"], #a,#b);} ; seleccion!: a:ID b:resto_seleccion {#seleccion = #(#[SELECCION,"SELECCION"], #a,#b);} ; resto_seleccion : (PT! ID)+ ; Lenguaje SEQ-O2. Análisis Léxico. class Analex extends Lexer; options{ importVocab=Anasint; k=2; } tokens{ PROGRAMA = "PROGRAMA"; DECLARACIONES = "DECLARACIONES"; INSTRUCCIONES = "INSTRUCCIONES"; EXT_CONS = "EXT_CONS"; EXT_NO_CONS = "EXT_NO_CONS"; } protected NL: "\r\n" {newline();} ; protected DIGITO : '0'..'9' ; protected LETRA : 'a'..'z'|'A'..'Z'|'_' ; BTN : (' '|'\t'|NL) {$setType(Token.SKIP);} ; ID : (LETRA)(LETRA|DIGITO)* ; DP:':' ; PT: '.' ; COMA: ',' ; CA : '[' ; CC : ']' ; PyC : ';' ; LINECOMMENTARY : "//" (options {greedy=false;} :.)* NL {$setType(Token.SKIP);}; Lenguaje SEQ-O2. Análisis Semántico. header{ import java.util.*; } class Anasint2 extends TreeParser; options{ importVocab=Anasint; } { Map<String,Set<String>>atributos = new HashMap<String,Set<String>>(); Map<String,String>objetos = new HashMap<String,String>(); //Pre: suponemos que ext_cls y cls son clases declaradas en el programa void extension_conservativa(String ext_cls, String cls){ Set<String>atrs_cls=atributos.get(cls); Set<String>atrs_ext_cls=atributos.get(ext_cls); for(String atr_cls:atrs_cls){ String aux = cls+"."+atr_cls; atrs_ext_cls.add(aux); } atributos.put(ext_cls,atrs_ext_cls); } void extension_no_conservativa(String ext_cls, String cls){ Set<String>atrs_cls=atributos.get(cls); Set<String>atrs_ext_cls=atributos.get(ext_cls); for(String atr_cls:atrs_cls){ if (!atrs_ext_cls.contains(atr_cls)){ String aux = cls+"."+atr_cls; atrs_ext_cls.add(aux); } } atributos.put(ext_cls,atrs_ext_cls); } private boolean esSimple(AST resto_seleccion){ boolean resultado = false; AST elem = resto_seleccion; int cont = 0; while (elem!=null){ cont++; elem = elem.getNextSibling(); } resultado = (cont==1); return resultado; } private String convertir_seleccion(AST resto_seleccion){ String resultado = new String(""); AST elem = resto_seleccion; while (elem!=null){ resultado = resultado + elem.getText(); elem = elem.getNextSibling(); if (elem!=null) resultado+="."; } return resultado; } //Pre: obj es un objeto declarado en el programa void check(String obj, AST resto_seleccion){ String cls = objetos.get(obj); Set<String>atrs=atributos.get(cls); Iterator<String>it = atrs.iterator(); String aux = convertir_seleccion(resto_seleccion); boolean simple = esSimple(resto_seleccion); boolean encontrado = false; if (simple){//selección simple ej. o.b while(!encontrado & it.hasNext()){ String atr = it.next(); if (atr.length()>1){ if (atr.endsWith(aux)) encontrado = true; } else if (atr.equals(aux)) encontrado = true; } } else{ //seleccion absoluta ej. o.B.b while(!encontrado & it.hasNext()){ String atr = it.next(); if (atr.length()>1) if (atr.equals(aux)) encontrado = true; } } if(!encontrado) System.out.println("Seleccion de un atributo inexistente ("+ aux+") en el objeto "+obj+" "+objetos); } } programa: #(PROGRAMA declaraciones instrucciones) ; declaraciones: #(DECLARACIONES clases relaciones) ; clases: (clase)* ; clase {Set<String>atrs=new HashSet<String>();}: #(a:ID (atrs=atributos)?) {atributos.put(a.getText(),atrs);} ; atributos returns [Set<String>r=new HashSet<String>()]: (a:ID {r.add(a.getText());})+ ; relaciones : (relacion {System.out.println(atributos);})* ; relacion : #(EXT_CONS a:ID b:ID) { extension_conservativa(a.getText(),b.getText()); } | #(EXT_NO_CONS c:ID d:ID) { extension_no_conservativa(c.getText(),d.getText()); } ; instrucciones: #(INSTRUCCIONES (instruccion)*) ; instruccion: (vinculacion|seleccion) ; vinculacion: #(VINCULACION a:ID b:ID) {objetos.put(a.getText(),b.getText());} ; seleccion: #(SELECCION a:ID b:resto) {check(a.getText(),b);} ; resto : (ID)+ ; Lenguaje SEQ-CC. Compilación. header{ import java.io.*; import java.util.*; } class Compilador extends TreeParser; options{ importVocab=Anasint; } { FileWriter f; int blanks = 0; Stack<String> etiq_sino = new Stack<String>(); //pila de etiquetas sino Stack<String> etiq_finsi = new Stack<String>(); //pila de etiquetas fin si int cont = 0; //contador de etiquetas void write(String s){ try{ write_blanks(); f.write(s); }catch(IOException e){} } void write_blanks(){ try{ for(int i=0;i<=blanks;i++) f.write(" "); }catch(IOException e){} } // Open the output file void open_file(String programa){ try{ f = new FileWriter(programa+".ens"); }catch(IOException e){} } void close_file(){ try{ f.close(); }catch(IOException e){} } void gen_code_comienzo_programa(){ write("comienzo_programa\n"); blanks+=3; } void gen_code_fin_programa(){ blanks-=3; write("fin_programa\n"); } void gen_code_declarar_variable(String nombre_variable){ write("declarar_variable("+nombre_variable+")\n"); } void gen_code_cargar_variable(String nombre_variable){ write("cargar_variable_a_pila("+nombre_variable+")\n"); } void gen_code_almacenar_variable(String nombre_variable){ write("almacenar_de_pila_a_variable("+nombre_variable+")\n"); } void gen_code_cargar_constante(int constante){ write("cargar_constante_a_pila("+constante+")\n"); } void gen_code_sumar(){ write("sumar\n"); } void gen_code_restar(){ write("restar\n"); } void gen_code_multiplicar(){ write("multiplicar\n"); } void gen_code_dividir(){ write("dividir\n"); } void gen_code_mayor(){ write("mayor\n"); } void gen_code_menor(){ write("menor\n"); } void gen_code_igual(){ write("igual\n"); } void gen_code_negacion(){ write("negacion\n"); } void gen_code_conjuncion(){ write("conjuncion\n"); } void gen_code_disyuncion(){ write("disyuncion\n"); } void gen_code_salto_incondicional(String etiqueta){ write("salto_incondicional("+etiqueta+")\n"); } void gen_code_salto_condicional(String etiqueta){ write("salto_condicional("+etiqueta+")\n"); } void gen_code_etiq(String etiqueta){ write(etiqueta+":\n"); } } programa: {open_file("programa"); gen_code_comienzo_programa();} #(PROGRAMA declaraciones instrucciones) {gen_code_fin_programa();close_file();} ; declaraciones: (declaracion)* ; declaracion : #(ENTERO variables) | #(BOOLEANO variables) ; variables : (v:VAR {gen_code_declarar_variable(v.getText());})+ ; instrucciones: (instruccion)+ ; instruccion : (asignacion | condicional) ; asignacion : #(ASIG v:VAR expr) {gen_code_almacenar_variable(v.getText());} ; condicional : (#(SI expr entonces SINO))=> {cont++; etiq_sino.push("etiq"+cont); cont++; etiq_finsi.push("etiq"+cont);} #(SI expr {gen_code_salto_condicional(etiq_sino.peek());} entonces {gen_code_salto_incondicional(etiq_finsi.peek());gen_code_etiq(etiq_sino.peek());} sino {etiq_sino.pop();gen_code_etiq(etiq_finsi.peek()); etiq_finsi.pop();}) | {cont++; etiq_finsi.push("etiq"+cont);} #(SI expr {gen_code_salto_condicional(etiq_finsi.peek());} entonces {gen_code_salto_incondicional(etiq_finsi.peek());etiq_finsi.pop();}) ; entonces : #(ENTONCES instrucciones) ; sino : #(SINO instrucciones) ; expr : | | | ; #(Y expr1 expr) {gen_code_conjuncion();} #(O expr1 expr) {gen_code_disyuncion();} #(NO expr1) {gen_code_negacion();} expr1 expr1 : | | | | | ; #(MAYOR expr2 expr2) {gen_code_mayor();} #(MAYORIGUAL expr2 expr2) {gen_code_menor(); gen_code_negacion();} #(MENOR expr2 expr2){gen_code_menor();} #(MENORIGUAL expr2 expr2){gen_code_mayor(); gen_code_negacion();} #(IGUAL expr2 expr2){gen_code_igual();} expr2 expr2 : | | | | | | ; #(MAS expr3 expr2) {gen_code_sumar();} (#(MENOS . .))=>#(MENOS expr3 expr2) {gen_code_restar();} #(POR expr3 expr2){gen_code_multiplicar();} #(DIV expr3 expr2) {gen_code_dividir();} expr3 TRUE {gen_code_cargar_constante(1);} FALSE {gen_code_cargar_constante(0);} expr3 : v:VAR {gen_code_cargar_variable(v.getText());} | n:NUM {gen_code_cargar_constante(new Integer(n.getText()));} | #(MENOS {gen_code_cargar_constante(0);} expr2) {gen_code_restar();} ;