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();
55 LinkedList<Simbolo_no_resuelto> no_resueltos = new LinkedList<Simbolo_no_resuelto>();
57 void ambito_abrir_programa(){
58 if(pilaambitos.vacia() == true){
59 Ambito a = new Ambito("programa","PROGRAMA",null,null);
60 pilaambitos.apilar_ambito(a);
64 void ambito_abrir(AST nombre, String tipo){
65 Ambito act = pilaambitos.ambito_actual();
66 String tipoAct = act.getTipo();
67 if(tipo.equals("MODULO") && tipoAct.equals("PROGRAMA")
68 || tipo.equals("CLASE") && tipoAct.equals("MODULO")
69 || tipo.equals("METODO") && tipoAct.equals("CLASE")){
70 Ambito A = new Ambito(nombre.getText(), tipo, null, act);
71 pilaambitos.apilar_ambito(A);
76 if(pilaambitos.vacia() == false){
78 pilaambitos.desapilar_ambito();
81 void ambito_cerrar_programa(){
82 if(pilaambitos.vacia() == false && pilaambitos.ambito_actual().getTipo().equals("PROGRAMA")){
84 pilaambitos.desapilar_ambito();
88 //XX TODO referencia adelantada
89 void ambito_instalar(){
90 Ambito a = pilaambitos.ambito_actual();
91 t.tablaambitos.apilar_ambito(a);
92 if(a.getTipo().equals("MODULO")){
97 AST crear_declaracion_modulo(AST nombre_modulo, AST definicion_modulo){
98 String m = nombre_modulo.getText();
99 AST M = #(#[MODULO, "modulo"],nombre_modulo, definicion_modulo);
100 Simbolo S = new Simbolo(m, M);
101 pilaambitos.ambito_actual().setDeclaracion(S);
105 AST crear_declaracion_clase (AST nombre_clase, AST cualificador_clase, AST definicion_clase){
106 String c = nombre_clase.getText();
107 AST C = #(#[CLASE,"clase"],nombre_clase, cualificador_clase, definicion_clase);
108 Simbolo S = new Simbolo(c,C);
109 pilaambitos.ambito_actual().setDeclaracion(S);
113 AST crear_declaracion_metodo (AST declaracion_metodo, AST cualificador_metodo){
114 AST MT = #(#[METODO,"metodo"], declaracion_metodo, cualificador_metodo);
115 String mt = MT.getFirstChild().getFirstChild().getText();
116 Simbolo S = new Simbolo(mt,MT);
117 pilaambitos.ambito_actual().setDeclaracion(S);
121 AST crear_declaracion_atributo (AST nombre_atributo, AST tipo_atributo, AST cualificador_atributo){
122 String a = nombre_atributo.getText();
123 AST A = #(#[ATRIBUTO,"atributo"], nombre_atributo, tipo_atributo, cualificador_atributo);
124 Simbolo S = new Simbolo(a, A);
125 pilaambitos.ambito_actual().setDeclaracion(S);
129 AST crear_declaracion_parametro (AST nombre_parametro, AST tipo_parametro){
130 String p = nombre_parametro.getText();
131 AST P = #(#[PARAMETRO,"parametro"], nombre_parametro, tipo_parametro);
132 Simbolo S = new Simbolo(p, P);
133 pilaambitos.ambito_actual().setDeclaracion(S);
139 AST crear_declaracion_variable_local (AST nombre_variable, AST tipo_variable){
140 String v = nombre_variable.getText();
141 AST V = #(#[VARIABLE_LOCAL,"variable_local"], nombre_variable, tipo_variable);
142 Simbolo S = new Simbolo(v, V);
143 pilaambitos.ambito_actual().setDeclaracion(S);
147 AST ambito_tratar_acceso_simple (AST ident){
148 String acc = ident.getText();
152 if ((s=pilaambitos.buscar_simbolo(acc)) != null){
153 dec_acc = s.getDeclaracion(); // AST de la declaracion del acceso simple
154 ACC = #(#[ACCESO_SIMPLE,"acceso_simple"], ident, dec_acc);
155 log.writeNoIndent(" ("+dec_acc.getText()+")\n");
158 //referencia adelantada o error
159 String n = t.accesossinresolver.setAcceso(acc, pilaambitos.ambito_actual(), ((ArbolLineas)ident).getLinea());
160 AST LI = #(#[LIT_ENTERO, "lit_entero"]);
162 ACC = #(#[ACCESO_SIMPLE, "acceso_simple"], ident, LI);
168 AST ambito_tratar_ident_tipo (AST ident){
170 String tipo = ident.getText();
171 men = "ERROR RN: Identificador de tipo "+tipo+" no declarado";
172 Ambito amb = pilaambitos.ambito_actual();
173 while (amb != null && !amb.getTipo().equals("MODULO"))
174 amb = amb.getContenedor();
176 System.out.println("ERROR: El tipo" + tipo + "no es un tipo clase"); // el tipo no es un tipo clase
177 return #(#[ERROR,"error"]);
179 Simbolo simb = amb.getDeclaracion(tipo);
181 //referencia adelantada o error
182 Identificador_Tipo IT = new Identificador_Tipo(tipo);
183 IT.setLinea(((ArbolLineas)ident).getLinea());
184 t.identtiposinresolver.setIdentificador(IT);
190 public AST arbol_crear(AST e1, AST e2){
192 return #(#[CREAR,"crear"],e1, #[ERROR,"error"]);
194 return #(#[CREAR,"crear"],e1, e2);
197 public AST arbol_escribir(AST e){
199 return #(#[ERROR,"error"]);
201 return #(#[ESCRIBIR,"escribir"],e);
204 //comprueba que existe la clase programa y el metodo inicio en esta
205 public void comprobarPrograma(AST modulo){
206 boolean programa=false;
207 AST clase = modulo.getFirstChild().getNextSibling();
208 while (!clase.getText().equals("exportacion")){
209 clase = clase.getNextSibling();
211 clase = clase.getFirstChild();
212 String nombre = clase.getFirstChild().getText();
214 if(nombre.equals("Programa") && !programa){
216 if(clase.getFirstChild().getNextSibling().getText().equals("inst")){
217 System.out.println("ERROR AS: La clase Programa tiene que ser no instanciable");
219 comprobarInicio(clase);
222 clase = clase.getNextSibling();
225 nombre = clase.getFirstChild().getText();
228 System.out.println("ERROR AS: No se ha definido la clase Programa");
232 public void comprobarInicio(AST Prog){
233 boolean inicio = false;
235 AST modulo = Prog.getFirstChild().getNextSibling().getNextSibling();
237 while(modulo.getType() != METODO && modulo != null){
238 modulo = modulo.getNextSibling();
240 if(modulo != null && !modulo.getFirstChild().getFirstChild().getText().equals("inicio")){
241 System.out.println("ERROR AS: Debe haber un metodo inicio en la clase Programa, y debe ser unico");
242 }if(modulo.getNextSibling() != null){
243 System.out.println("ERROR AS: Debe haber un metodo inicio en la clase Programa, y debe ser unico");
251 /////////////////////////////////////////////////////////
252 // DECLARACION DE MODULO
253 /////////////////////////////////////////////////////////
255 declaracion_modulo![String f] returns [Tabla_Global tab=null] :
257 ambito_abrir_programa();
258 log = new logFile(f);
262 ambito_abrir (#n,"MODULO");
263 log.write("MODULO: "+#n.getText()+"\n");
266 d:definicion_modulo EOF
269 #declaracion_modulo=crear_declaracion_modulo(#n,#d);
270 //comprobarPrograma(#declaracion_modulo);
271 ambito_cerrar_programa();
277 nombre_modulo : MODULO! IDENT ;
285 lista_ident: IDENT (COMA! IDENT)*;
288 IMPORTACION^ DOS_PUNTOS! l:lista_ident
292 EXPORTACION^ DOS_PUNTOS!
293 l:lista_declaraciones_clases
297 IMPLEMENTACION^ DOS_PUNTOS!
298 l:lista_declaraciones_clases
301 lista_declaraciones_clases :
306 ///////////////////////////////////////////////////////////
307 // DECLARACION DE CLASE
308 ///////////////////////////////////////////////////////////
310 declaracion_clase ! :
314 ambito_abrir(#n,"CLASE");
315 log.write("CLASE: "+#n.getText()+"\n");
322 #declaracion_clase = crear_declaracion_clase(#n,#c,#d);
326 cualificador_clase! :
327 INST {#cualificador_clase = #(#[INST]);}
328 | {#cualificador_clase = #(#[NO_INST,"no_inst"]);}
331 nombre_clase : CLASE! IDENT ;
335 declaraciones_elemento_clase
339 declaraciones_elemento_clase :
340 (declaracion_elemento_clase)* ;
342 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
343 // DECLARACION DE ELEMENTO CLASE: METODO O ATRIBUTO
344 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
346 declaracion_elemento_clase! :
347 c:cualificador_elemento_clase
348 ((IDENT PARENTESIS_ABIERTO) =>
352 #declaracion_elemento_clase = crear_declaracion_metodo(#a,#c);
355 | t:tipo i:IDENT PUNTO_Y_COMA
357 #declaracion_elemento_clase = crear_declaracion_atributo(#i,#t,#c);
358 log.write("ATRIBUTO: "+#i.getText()+"\n");
362 // Cualificador de visibilidad
363 cualificador_elemento_clase! :
364 OCULTO {#cualificador_elemento_clase = #(#[OCULTO]);}
365 | {#cualificador_elemento_clase = #(#[VISIBLE,"visible"]);}
376 ambito_abrir(#i,"METODO");
377 log.write("METODO: "+#i.getText()+"\n");
380 p:declaracion_parametros
383 {#prototipo_metodo = #(#[PROTOTIPO,"prototipo"],#i,#(#[PARAMETROS,"parametros"],#p),#(#[RESULTADO,"resultado"],#t));}
384 | {#prototipo_metodo = #(#[PROTOTIPO,"prototipo"],#i,#(#[PARAMETROS,"parametros"],#p),#(#[RESULTADO,"resultado"],#[VACIO, "vacio"]));}
388 declaracion_parametros :
389 declaracion_parametro (COMA! declaracion_parametro)*
393 ///////////////////////////////////////////////////////////
394 // DECLARACION DE PARAMETRO
395 ///////////////////////////////////////////////////////////
397 declaracion_parametro!: t:tipo i:IDENT
398 {#declaracion_parametro = crear_declaracion_parametro(#i,#t);}
402 LLAVE_ABIERTA {log.incNivel();}
403 d:declaraciones_variables_locales
405 LLAVE_CERRADA {log.decNivel();}
406 {#definicion_metodo= #(#[DEFINICION,"definicion"],#(#[VARIABLES_LOCALES,"variables_locales"],#d), #b);}
409 declaraciones_variables_locales :
410 (declaracion_variables_locales tipo IDENT) =>
411 declaracion_variables_locales declaraciones_variables_locales
412 |(declaracion_variables_locales) =>
413 declaracion_variables_locales
417 declaracion_variables_locales :
418 t:tipo! lista_nombres_variables_locales[#t] PUNTO_Y_COMA! ;
420 lista_nombres_variables_locales [AST t] :
421 nombre_variable_local[#t] (COMA! nombre_variable_local[#t])* ;
423 /////////////////////////////////////////////////////////////////
424 // DECLARACION DE VARIABLE LOCAL
425 //////////////////////////////////////////////////////////////////
427 nombre_variable_local! [AST t] :
429 { #nombre_variable_local = crear_declaracion_variable_local(#i,#t); }
432 ///////////////////////////////////////////////////////////
434 ///////////////////////////////////////////////////////////
435 instrucciones : (instruccion)* ;
438 i:instruccion_simple PUNTO_Y_COMA
439 {#instruccion=#(#[INSTRUCCION,"instruccion"],#i);}
440 | j:instruccion_compuesta
441 {#instruccion=#(#[INSTRUCCION,"instruccion"],#j);}
445 (expresion ASIGNACION CREAR) => crear
446 | (expresion ASIGNACION) => asignacion
452 instruccion_compuesta :
458 e1:expresion ASIGNACION e2:expresion
459 { #asignacion = #(#[ASIGNACION],#e1,#e2); }
463 retorno! : DEV e:expresion
464 { #retorno = #(#[DEV],#e); }
473 { #llamada_metodo = #(#[LLAMADA,"llamada"],#i,#(#[EXPRESIONES,"expresiones"],#s)); }
476 lista_expresiones : expresion (COMA! expresion)*
480 condicion : SI^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! ENTONCES!
482 (SINO! bloque)? FINSI! ;
485 iteracion : MIENTRAS^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! HACER!
489 bloque!: i:instrucciones
490 {#bloque=#(#[INSTRUCCIONES,"instrucciones"],#i);}
493 /////////////////////////////////////////////////////////////
495 ////////////////////////////////////////////////////////////
498 expresion_nivel_1 (O^ expresion_nivel_1)* ;
501 expresion_nivel_2 (Y^ expresion_nivel_2)* ;
504 (NO^)? expresion_nivel_3 ;
508 ((MAYOR^|MAYOR_IGUAL^|MENOR^|MENOR_IGUAL^|IGUAL^|DISTINTO^)
509 expresion_nivel_4)? ;
512 expresion_nivel_5 ((MAS^|MENOS^) expresion_nivel_5)* ;
515 expresion_nivel_6 ((POR^|DIVISION^) expresion_nivel_6)* ;
518 MENOS i:expresion_nivel_7
519 {#expresion_nivel_6=#(#[MENOSUNARIO,"menosunario"],#i);}
524 PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO!
527 | (acceso PARENTESIS_ABIERTO) => llamada_metodo
528 | (acceso CORCHETE_ABIERTO) => acceso_tabla
536 //////////////////////////////////////////////////////////////
538 //////////////////////////////////////////////////////////////
539 acceso_tabla!: c:acceso CORCHETE_ABIERTO d:lista_expresiones_nv CORCHETE_CERRADO
540 {#acceso_tabla=#(#[ACCESO_TABLA,"acceso_tabla"],#c,#(#[EXPRESIONES,"expresiones"],#d));}
543 //////////////////////////////////////////////////////////////
544 // ACCESOS SIMPLES Y A OBJETOS
545 //////////////////////////////////////////////////////////////
548 (IDENT PUNTO)=> i1:IDENT PUNTO i2:IDENT
550 log.write("ACCESO SIMPLE: "+#i1.getText());
551 #acceso=#(#[ACCESO_OBJETO,"acceso_objeto"], ambito_tratar_acceso_simple(#i1), #i2);
555 log.write("ACCESO SIMPLE: "+#i.getText());
556 #acceso = ambito_tratar_acceso_simple(#i);
560 lista_expresiones_nv :
561 expresion (COMA! expresion)*
564 //////////////////////////////////////////////////////////
566 /////////////////////////////////////////////////////////
568 tipo_predefinido_simple
569 | tipo_predefinido_compuesto
570 | i:IDENT {#tipo = ambito_tratar_ident_tipo(#i);
571 log.write("IDENTIFICADOR TIPO: "+#i.getText()+"\n");
575 tipo_predefinido_simple :
582 tipo_predefinido_compuesto :
586 formacion! : FORMACION l:lista_enteros
587 ( t:tipo_predefinido_simple
588 {#formacion = #(#[FORMACION,"formacion"],#(#[LISTA_ENTEROS,"lista_enteros"],#l),#t);}
590 {#formacion = #(#[FORMACION,"formacion"], #(#[LISTA_ENTEROS,"lista_enteros"],#l), ambito_tratar_ident_tipo(#i));
591 log.write("IDENTIFICADOR TIPO: "+#i.getText()+"\n");
595 lista_enteros : LIT_ENTERO (COMA! LIT_ENTERO)*;
598 escribir!: ESCRIBIR PARENTESIS_ABIERTO e:expresion PARENTESIS_CERRADO
600 #escribir = arbol_escribir(#e);
602 log.write("IDENTIFICADOR TIPO: "+#e.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
603 }catch(NullPointerException n){}
606 //de momento se pasa el arbol completo del tipo, pero creo que con el ident seria
607 //suficiente para el analisis semantico
608 crear!: e1:expresion ASIGNACION CREAR PARENTESIS_ABIERTO i:expresion PARENTESIS_CERRADO
610 #crear = arbol_crear(#e1,#i);
612 log.write("IDENTIFICADOR TIPO: "+#i.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
613 }catch(NullPointerException n){}
617 entero_a_real!: ENTERO_A_REAL PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
618 {## = #(#[ENTERO_A_REAL],#e1);};
620 real_a_entero!: REAL_A_ENTERO PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
621 {## = #(#[REAL_A_ENTERO],#e1);};