3 * Referencia adelantada
4 * se intentan resolver los nombres, los que no se resuelvan se almacenan en al tabla de simbolos
5 * se recorren los no resueltos, y se le asigna el nombre correspondiente
6 * se recorre el ambito modulo, y se instalan las declaraciones en los no resueltos
16 class Anasint extends Parser;
52 Pila_Ambitos pilaambitos = new Pila_Ambitos();
53 Tabla_Global t = new Tabla_Global();
54 Hashtable<String,String> declaraciones = new Hashtable<String,String>();
56 LinkedList<Simbolo_no_resuelto> no_resueltos = new LinkedList<Simbolo_no_resuelto>();
58 void ambito_abrir_programa(){
59 if(pilaambitos.vacia() == true){
60 Ambito a = new Ambito("programa","PROGRAMA",null,null);
61 pilaambitos.apilar_ambito(a);
65 void ambito_abrir(AST nombre, String tipo){
66 Ambito act = pilaambitos.ambito_actual();
67 String tipoAct = act.getTipo();
68 if(tipo.equals("MODULO") && tipoAct.equals("PROGRAMA")
69 || tipo.equals("CLASE") && tipoAct.equals("MODULO")
70 || tipo.equals("METODO") && tipoAct.equals("CLASE")){
71 Ambito A = new Ambito(nombre.getText(), tipo, null, act);
72 pilaambitos.apilar_ambito(A);
77 if(pilaambitos.vacia() == false){
79 pilaambitos.desapilar_ambito();
82 void ambito_cerrar_programa(){
83 if(pilaambitos.vacia() == false && pilaambitos.ambito_actual().getTipo().equals("PROGRAMA")){
85 pilaambitos.desapilar_ambito();
89 //XX TODO referencia adelantada
90 void ambito_instalar(){
91 Ambito a = pilaambitos.ambito_actual();
92 t.tablaambitos.apilar_ambito(a);
93 if(a.getTipo().equals("MODULO")){
98 AST crear_declaracion_modulo(AST nombre_modulo, AST definicion_modulo){
99 String m = nombre_modulo.getText();
100 AST M = #(#[MODULO, "modulo"],nombre_modulo, definicion_modulo);
101 Simbolo S = new Simbolo(m, M);
102 pilaambitos.ambito_actual().setDeclaracion(S);
106 AST crear_declaracion_clase (AST nombre_clase, AST cualificador_clase, AST definicion_clase){
107 String c = nombre_clase.getText();
108 AST C = #(#[CLASE,"clase"],nombre_clase, cualificador_clase, definicion_clase);
109 Simbolo S = new Simbolo(c,C);
110 pilaambitos.ambito_actual().setDeclaracion(S);
114 AST crear_declaracion_metodo (AST declaracion_metodo, AST cualificador_metodo){
115 AST MT = #(#[METODO,"metodo"], declaracion_metodo, cualificador_metodo);
116 String mt = MT.getFirstChild().getFirstChild().getText();
117 Simbolo S = new Simbolo(mt,MT);
118 pilaambitos.ambito_actual().setDeclaracion(S);
122 AST crear_declaracion_atributo (AST nombre_atributo, AST tipo_atributo, AST cualificador_atributo){
123 declaraciones.put(nombre_atributo.getText(), tipo_atributo.getText());
124 String a = nombre_atributo.getText();
125 AST A = #(#[ATRIBUTO,"atributo"], nombre_atributo, tipo_atributo, cualificador_atributo);
126 Simbolo S = new Simbolo(a, A);
127 pilaambitos.ambito_actual().setDeclaracion(S);
131 AST crear_declaracion_parametro (AST nombre_parametro, AST tipo_parametro){
132 String p = nombre_parametro.getText();
133 declaraciones.put(nombre_parametro.getText(), tipo_parametro.getText());
134 AST P = #(#[PARAMETRO,"parametro"], nombre_parametro, tipo_parametro);
135 Simbolo S = new Simbolo(p, P);
136 pilaambitos.ambito_actual().setDeclaracion(S);
142 AST crear_declaracion_variable_local (AST nombre_variable, AST tipo_variable){
143 String v = nombre_variable.getText();
144 declaraciones.put(nombre_variable.getText(), tipo_variable.getText());
145 AST V = #(#[VARIABLE_LOCAL,"variable_local"], nombre_variable, tipo_variable);
146 Simbolo S = new Simbolo(v, V);
147 pilaambitos.ambito_actual().setDeclaracion(S);
151 AST ambito_tratar_acceso_simple (AST ident){
152 String acc = ident.getText();
156 if ((s=pilaambitos.buscar_simbolo(acc)) != null){
157 dec_acc = s.getDeclaracion(); // AST de la declaracion del acceso simple
158 ACC = #(#[ACCESO_SIMPLE,"acceso_simple"], ident, dec_acc);
159 log.writeNoIndent(" ("+dec_acc.getText()+")\n");
162 //referencia adelantada o error
163 String n = t.accesossinresolver.setAcceso(acc, pilaambitos.ambito_actual(), ((ArbolLineas)ident).getLinea());
164 AST LI = #(#[LIT_ENTERO, "lit_entero"]);
166 ACC = #(#[ACCESO_SIMPLE, "acceso_simple"], ident, LI);
172 AST ambito_tratar_ident_tipo (AST ident){
174 String tipo = ident.getText();
175 men = "ERROR RN: Identificador de tipo "+tipo+" no declarado";
176 Ambito amb = pilaambitos.ambito_actual();
177 while (amb != null && !amb.getTipo().equals("MODULO"))
178 amb = amb.getContenedor();
180 System.out.println("ERROR: El tipo" + tipo + "no es un tipo clase"); // el tipo no es un tipo clase
181 return #(#[ERROR,"error"]);
183 Simbolo simb = amb.getDeclaracion(tipo);
185 //referencia adelantada o error
186 Identificador_Tipo IT = new Identificador_Tipo(tipo);
187 IT.setLinea(((ArbolLineas)ident).getLinea());
188 t.identtiposinresolver.setIdentificador(IT);
194 public AST arbol_crear(AST e1, AST e2){
196 return #(#[CREAR,"crear"],e1, #[ERROR,"error"]);
198 return #(#[CREAR,"crear"],e1, e2);
201 public AST arbol_escribir(AST e){
203 return #(#[ERROR,"error"]);
205 return #(#[ESCRIBIR,"escribir"],e);
208 //comprueba que existe la clase programa y el metodo inicio en esta
209 public void comprobarPrograma(AST modulo){
210 boolean programa=false;
211 AST clase = modulo.getFirstChild().getNextSibling();
212 while (!clase.getText().equals("exportacion")){
213 clase = clase.getNextSibling();
215 clase = clase.getFirstChild();
216 String nombre = clase.getFirstChild().getText();
218 if(nombre.equals("Programa") && !programa){
220 if(clase.getFirstChild().getNextSibling().getText().equals("inst")){
221 System.out.println("ERROR AS: La clase Programa tiene que ser no instanciable");
223 comprobarInicio(clase);
226 clase = clase.getNextSibling();
229 nombre = clase.getFirstChild().getText();
232 System.out.println("ERROR AS: No se ha definido la clase Programa");
236 public void comprobarInicio(AST Prog){
237 boolean inicio = false;
239 AST modulo = Prog.getFirstChild().getNextSibling().getNextSibling();
241 while(modulo.getType() != METODO && modulo != null){
242 modulo = modulo.getNextSibling();
244 if(modulo != null && !modulo.getFirstChild().getFirstChild().getText().equals("inicio")){
245 System.out.println("ERROR AS: Debe haber un metodo inicio en la clase Programa, y debe ser unico");
246 }if(modulo.getNextSibling() != null){
247 System.out.println("ERROR AS: Debe haber un metodo inicio en la clase Programa, y debe ser unico");
255 /////////////////////////////////////////////////////////
256 // DECLARACION DE MODULO
257 /////////////////////////////////////////////////////////
259 declaracion_modulo![String f] returns [Auxiliar tab=null] :
261 ambito_abrir_programa();
262 log = new logFile(f);
266 ambito_abrir (#n,"MODULO");
267 log.write("MODULO: "+#n.getText()+"\n");
270 d:definicion_modulo EOF
273 #declaracion_modulo=crear_declaracion_modulo(#n,#d);
274 //comprobarPrograma(#declaracion_modulo);
275 ambito_cerrar_programa();
278 tab = new Auxiliar(t, declaraciones);}
281 nombre_modulo : MODULO! IDENT ;
289 lista_ident: IDENT (COMA! IDENT)*;
292 IMPORTACION^ DOS_PUNTOS! l:lista_ident
296 EXPORTACION^ DOS_PUNTOS!
297 l:lista_declaraciones_clases
301 IMPLEMENTACION^ DOS_PUNTOS!
302 l:lista_declaraciones_clases
305 lista_declaraciones_clases :
310 ///////////////////////////////////////////////////////////
311 // DECLARACION DE CLASE
312 ///////////////////////////////////////////////////////////
314 declaracion_clase ! :
318 ambito_abrir(#n,"CLASE");
319 log.write("CLASE: "+#n.getText()+"\n");
326 #declaracion_clase = crear_declaracion_clase(#n,#c,#d);
330 cualificador_clase! :
331 INST {#cualificador_clase = #(#[INST]);}
332 | {#cualificador_clase = #(#[NO_INST,"no_inst"]);}
335 nombre_clase : CLASE! IDENT ;
339 declaraciones_elemento_clase
343 declaraciones_elemento_clase :
344 (declaracion_elemento_clase)* ;
346 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
347 // DECLARACION DE ELEMENTO CLASE: METODO O ATRIBUTO
348 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
350 declaracion_elemento_clase! :
351 c:cualificador_elemento_clase
352 ((IDENT PARENTESIS_ABIERTO) =>
356 #declaracion_elemento_clase = crear_declaracion_metodo(#a,#c);
359 | t:tipo i:IDENT PUNTO_Y_COMA
361 #declaracion_elemento_clase = crear_declaracion_atributo(#i,#t,#c);
362 log.write("ATRIBUTO: "+#i.getText()+"\n");
366 // Cualificador de visibilidad
367 cualificador_elemento_clase! :
368 OCULTO {#cualificador_elemento_clase = #(#[OCULTO]);}
369 | {#cualificador_elemento_clase = #(#[VISIBLE,"visible"]);}
380 ambito_abrir(#i,"METODO");
381 log.write("METODO: "+#i.getText()+"\n");
384 p:declaracion_parametros
387 {#prototipo_metodo = #(#[PROTOTIPO,"prototipo"],#i,#(#[PARAMETROS,"parametros"],#p),#(#[RESULTADO,"resultado"],#t));}
388 | {#prototipo_metodo = #(#[PROTOTIPO,"prototipo"],#i,#(#[PARAMETROS,"parametros"],#p),#(#[RESULTADO,"resultado"],#[VACIO, "vacio"]));}
392 declaracion_parametros :
393 declaracion_parametro (COMA! declaracion_parametro)*
397 ///////////////////////////////////////////////////////////
398 // DECLARACION DE PARAMETRO
399 ///////////////////////////////////////////////////////////
401 declaracion_parametro!: t:tipo i:IDENT
402 {#declaracion_parametro = crear_declaracion_parametro(#i,#t);}
406 LLAVE_ABIERTA {log.incNivel();}
407 d:declaraciones_variables_locales
409 LLAVE_CERRADA {log.decNivel();}
410 {#definicion_metodo= #(#[DEFINICION,"definicion"],#(#[VARIABLES_LOCALES,"variables_locales"],#d), #b);}
413 declaraciones_variables_locales :
414 (declaracion_variables_locales tipo IDENT) =>
415 declaracion_variables_locales declaraciones_variables_locales
416 |(declaracion_variables_locales) =>
417 declaracion_variables_locales
421 declaracion_variables_locales :
422 t:tipo! lista_nombres_variables_locales[#t] PUNTO_Y_COMA! ;
424 lista_nombres_variables_locales [AST t] :
425 nombre_variable_local[#t] (COMA! nombre_variable_local[#t])* ;
427 /////////////////////////////////////////////////////////////////
428 // DECLARACION DE VARIABLE LOCAL
429 //////////////////////////////////////////////////////////////////
431 nombre_variable_local! [AST t] :
433 { #nombre_variable_local = crear_declaracion_variable_local(#i,#t);}
436 ///////////////////////////////////////////////////////////
438 ///////////////////////////////////////////////////////////
439 instrucciones : (instruccion)* ;
442 i:instruccion_simple PUNTO_Y_COMA
443 {#instruccion=#(#[INSTRUCCION,"instruccion"],#i);}
444 | j:instruccion_compuesta
445 {#instruccion=#(#[INSTRUCCION,"instruccion"],#j);}
449 (expresion ASIGNACION CREAR) => crear
450 | (expresion ASIGNACION) => asignacion
456 instruccion_compuesta :
462 e1:expresion ASIGNACION e2:expresion
463 { #asignacion = #(#[ASIGNACION],#e1,#e2); }
467 retorno! : DEV e:expresion
468 { #retorno = #(#[DEV],#e); }
477 { #llamada_metodo = #(#[LLAMADA,"llamada"],#i,#(#[EXPRESIONES,"expresiones"],#s)); }
480 lista_expresiones : expresion (COMA! expresion)*
484 condicion : SI^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! ENTONCES!
486 (SINO! bloque)? FINSI! ;
489 iteracion : MIENTRAS^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! HACER!
493 bloque!: i:instrucciones
494 {#bloque=#(#[INSTRUCCIONES,"instrucciones"],#i);}
497 /////////////////////////////////////////////////////////////
499 ////////////////////////////////////////////////////////////
502 expresion_nivel_1 (O^ expresion_nivel_1)* ;
505 expresion_nivel_2 (Y^ expresion_nivel_2)* ;
508 (NO^)? expresion_nivel_3 ;
512 ((MAYOR^|MAYOR_IGUAL^|MENOR^|MENOR_IGUAL^|IGUAL^|DISTINTO^)
513 expresion_nivel_4)? ;
516 expresion_nivel_5 ((MAS^|MENOS^) expresion_nivel_5)* ;
519 expresion_nivel_6 ((POR^|DIVISION^) expresion_nivel_6)* ;
522 MENOS i:expresion_nivel_7
523 {#expresion_nivel_6=#(#[MENOSUNARIO,"menosunario"],#i);}
528 PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO!
531 | (acceso PARENTESIS_ABIERTO) => llamada_metodo
532 | (acceso CORCHETE_ABIERTO) => acceso_tabla
540 //////////////////////////////////////////////////////////////
542 //////////////////////////////////////////////////////////////
543 acceso_tabla!: c:acceso CORCHETE_ABIERTO d:lista_expresiones_nv CORCHETE_CERRADO
544 {#acceso_tabla=#(#[ACCESO_TABLA,"acceso_tabla"],#c,#(#[EXPRESIONES,"expresiones"],#d));}
547 //////////////////////////////////////////////////////////////
548 // ACCESOS SIMPLES Y A OBJETOS
549 //////////////////////////////////////////////////////////////
552 (IDENT PUNTO)=> i1:IDENT PUNTO i2:IDENT
554 log.write("ACCESO SIMPLE: "+#i1.getText());
555 #acceso=#(#[ACCESO_OBJETO,"acceso_objeto"], ambito_tratar_acceso_simple(#i1), #i2);
559 log.write("ACCESO SIMPLE: "+#i.getText());
560 #acceso = ambito_tratar_acceso_simple(#i);
564 lista_expresiones_nv :
565 expresion (COMA! expresion)*
568 //////////////////////////////////////////////////////////
570 /////////////////////////////////////////////////////////
572 tipo_predefinido_simple
573 | tipo_predefinido_compuesto
574 | i:IDENT {#tipo = ambito_tratar_ident_tipo(#i);
575 log.write("IDENTIFICADOR TIPO: "+#i.getText()+"\n");
579 tipo_predefinido_simple :
586 tipo_predefinido_compuesto :
590 formacion! : FORMACION l:lista_enteros
591 ( t:tipo_predefinido_simple
592 {#formacion = #(#[FORMACION,"formacion"],#(#[LISTA_ENTEROS,"lista_enteros"],#l),#t);}
594 {#formacion = #(#[FORMACION,"formacion"], #(#[LISTA_ENTEROS,"lista_enteros"],#l), ambito_tratar_ident_tipo(#i));
595 log.write("IDENTIFICADOR TIPO: "+#i.getText()+"\n");
599 lista_enteros : LIT_ENTERO (COMA! LIT_ENTERO)*;
602 escribir!: ESCRIBIR PARENTESIS_ABIERTO e:expresion PARENTESIS_CERRADO
604 #escribir = arbol_escribir(#e);
606 log.write("IDENTIFICADOR TIPO: "+#e.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
607 }catch(NullPointerException n){}
610 //de momento se pasa el arbol completo del tipo, pero creo que con el ident seria
611 //suficiente para el analisis semantico
612 crear!: e1:expresion ASIGNACION CREAR PARENTESIS_ABIERTO i:expresion PARENTESIS_CERRADO
614 #crear = arbol_crear(#e1,#i);
616 log.write("IDENTIFICADOR TIPO: "+#i.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
617 }catch(NullPointerException n){}
621 entero_a_real!: ENTERO_A_REAL PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
622 {## = #(#[ENTERO_A_REAL],#e1);};
624 real_a_entero!: REAL_A_ENTERO PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
625 {## = #(#[REAL_A_ENTERO],#e1);};