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 LinkedList<Simbolo_no_resuelto> no_resueltos = new LinkedList<Simbolo_no_resuelto>();
55 void ambito_abrir_programa(){
56 if(pilaambitos.vacia() == true){
57 Ambito a = new Ambito("programa","PROGRAMA",null,null);
58 pilaambitos.apilar_ambito(a);
62 void ambito_abrir(AST nombre, String tipo){
63 Ambito act = pilaambitos.ambito_actual();
64 String tipoAct = act.getTipo();
65 if(tipo.equals("MODULO") && tipoAct.equals("PROGRAMA")
66 || tipo.equals("CLASE") && tipoAct.equals("MODULO")
67 || tipo.equals("METODO") && tipoAct.equals("CLASE")){
68 Ambito A = new Ambito(nombre.getText(), tipo, null, act);
69 pilaambitos.apilar_ambito(A);
74 if(pilaambitos.vacia() == false){
75 pilaambitos.desapilar_ambito();
78 void ambito_cerrar_programa(){
79 if(pilaambitos.vacia() == false && pilaambitos.ambito_actual().getTipo().equals("PROGRAMA"))
80 pilaambitos.desapilar_ambito();
81 //TODO referencia adelantada
82 Simbolo_no_resuelto snr;
83 while(no_resueltos.size() > 0){
84 snr = no_resueltos.remove(0);
85 System.out.println(snr.getNombre() + " - " + snr.getAmbito().getNombre());
89 AST crear_declaracion_modulo(AST nombre_modulo, AST definicion_modulo){
90 String m = nombre_modulo.getText();
91 AST M = #(#[MODULO, "modulo"],nombre_modulo, definicion_modulo);
92 Simbolo S = new Simbolo(m, M);
93 pilaambitos.ambito_actual().setDeclaracion(S);
97 AST crear_declaracion_clase (AST nombre_clase, AST cualificador_clase, AST definicion_clase){
98 String c = nombre_clase.getText();
99 AST C = #(#[CLASE,"clase"],nombre_clase, cualificador_clase, definicion_clase);
100 Simbolo S = new Simbolo(c,C);
101 pilaambitos.ambito_actual().setDeclaracion(S);
105 AST crear_declaracion_metodo (AST declaracion_metodo, AST cualificador_metodo){
106 AST MT = #(#[METODO,"metodo"], declaracion_metodo, cualificador_metodo);
107 String mt = MT.getFirstChild().getFirstChild().getText();
108 Simbolo S = new Simbolo(mt,MT);
109 pilaambitos.ambito_actual().setDeclaracion(S);
113 AST crear_declaracion_atributo (AST nombre_atributo, AST tipo_atributo, AST cualificador_atributo){
114 String a = nombre_atributo.getText();
115 AST A = #(#[ATRIBUTO,"atributo"], nombre_atributo, tipo_atributo, cualificador_atributo);
116 Simbolo S = new Simbolo(a, A);
117 pilaambitos.ambito_actual().setDeclaracion(S);
121 AST crear_declaracion_parametro (AST nombre_parametro, AST tipo_parametro){
122 String p = nombre_parametro.getText();
123 AST P = #(#[PARAMETRO,"parametro"], nombre_parametro, tipo_parametro);
124 Simbolo S = new Simbolo(p, P);
125 pilaambitos.ambito_actual().setDeclaracion(S);
131 AST crear_declaracion_variable_local (AST nombre_variable, AST tipo_variable){
132 String v = nombre_variable.getText();
133 AST V = #(#[VARIABLE_LOCAL,"variable_local"], nombre_variable, tipo_variable);
134 Simbolo S = new Simbolo(v, V);
135 pilaambitos.ambito_actual().setDeclaracion(S);
139 AST ambito_tratar_acceso_simple (AST ident){
140 String acc = ident.getText();
143 if ((s=pilaambitos.buscar_simbolo(acc)) != null){
144 dec_acc = s.getDeclaracion(); // AST de la declaracion del acceso simple
145 log.writeNoIndent(" ("+dec_acc.getText()+")\n");
148 String men = "ERROR RN: Identificador " +acc+ " no declarado";
149 dec_acc = #(#[ERROR,"error"]);
150 System.out.println(men); // identificador no declarado
151 log.writeNoIndent(" (error)\n");
153 AST ACC = #(#[ACCESO_SIMPLE,"acceso_simple"], ident, dec_acc);
157 AST ambito_tratar_ident_tipo (AST ident){
159 String tipo = ident.getText();
160 men = "ERROR RN: Identificador de tipo "+tipo+" no declarado";
161 Ambito amb = pilaambitos.ambito_actual();
162 while (amb != null && !amb.getTipo().equals("MODULO"))
163 amb = amb.getContenedor();
165 System.out.println(men); // el tipo no es un tipo clase
166 return #(#[ERROR,"error"]);
168 Simbolo simb = amb.getDeclaracion(tipo);
170 System.out.println(men); // el tipo no es un tipo clase
171 //TODO referencia adelanatada
172 no_resueltos.add(new Simbolo_no_resuelto(tipo, pilaambitos.ambito_actual()));
173 return #(#[ERROR,"error"]); //#(#[ERROR,"error"]);
175 AST C = simb.getDeclaracion();
181 public AST arbol_crear(AST e1, AST e2){
183 return #(#[CREAR,"crear"],e1, #[ERROR,"error"]);
185 return #(#[CREAR,"crear"],e1, e2);
188 public AST arbol_escribir(AST e){
190 return #(#[ERROR,"error"]);
192 return #(#[ESCRIBIR,"escribir"],e);
195 //comprueba que existe la clase programa y el metodo inicio en esta
196 public void comprobarPrograma(AST modulo){
197 boolean programa=false;
198 AST clase = modulo.getFirstChild().getNextSibling();
199 while (!clase.getText().equals("exportacion")){
200 clase = clase.getNextSibling();
202 clase = clase.getFirstChild();
203 String nombre = clase.getFirstChild().getText();
205 if(nombre.equals("Programa") && !programa){
207 if(clase.getFirstChild().getNextSibling().getText().equals("inst")){
208 System.out.println("ERROR AS: La clase Programa tiene que ser no instanciable");
210 comprobarInicio(clase);
213 clase = clase.getNextSibling();
216 nombre = clase.getFirstChild().getText();
219 System.out.println("ERROR AS: No se ha definido la clase Programa");
223 public void comprobarInicio(AST Prog){
224 boolean inicio = false;
226 AST modulo = Prog.getFirstChild().getNextSibling().getNextSibling();
228 while(modulo.getType() != METODO && modulo != null){
229 modulo = modulo.getNextSibling();
231 if(modulo != null && !modulo.getFirstChild().getFirstChild().getText().equals("inicio")){
232 System.out.println("ERROR AS: Debe haber un metodo inicio en la clase Programa, y debe ser unico");
233 }if(modulo.getNextSibling() != null){
234 System.out.println("ERROR AS: Debe haber un metodo inicio en la clase Programa, y debe ser unico");
242 /////////////////////////////////////////////////////////
243 // DECLARACION DE MODULO
244 /////////////////////////////////////////////////////////
246 declaracion_modulo![String f] :
248 ambito_abrir_programa();
249 log = new logFile(f);
253 ambito_abrir (#n,"MODULO");
254 log.write("MODULO: "+#n.getText()+"\n");
257 d:definicion_modulo EOF
260 #declaracion_modulo=crear_declaracion_modulo(#n,#d);
261 comprobarPrograma(#declaracion_modulo);
262 ambito_cerrar_programa();
268 nombre_modulo : MODULO! IDENT ;
276 lista_ident: IDENT (COMA! IDENT)*;
279 IMPORTACION^ DOS_PUNTOS! l:lista_ident
283 EXPORTACION^ DOS_PUNTOS!
284 l:lista_declaraciones_clases
288 IMPLEMENTACION^ DOS_PUNTOS!
289 l:lista_declaraciones_clases
292 lista_declaraciones_clases :
297 ///////////////////////////////////////////////////////////
298 // DECLARACION DE CLASE
299 ///////////////////////////////////////////////////////////
301 declaracion_clase ! :
305 ambito_abrir(#n,"CLASE");
306 log.write("CLASE: "+#n.getText()+"\n");
313 #declaracion_clase = crear_declaracion_clase(#n,#c,#d);
317 cualificador_clase! :
318 INST {#cualificador_clase = #(#[INST]);}
319 | {#cualificador_clase = #(#[NO_INST,"no_inst"]);}
322 nombre_clase : CLASE! IDENT ;
326 declaraciones_elemento_clase
330 declaraciones_elemento_clase :
331 (declaracion_elemento_clase)* ;
333 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
334 // DECLARACION DE ELEMENTO CLASE: METODO O ATRIBUTO
335 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
337 declaracion_elemento_clase! :
338 c:cualificador_elemento_clase
339 ((IDENT PARENTESIS_ABIERTO) =>
343 #declaracion_elemento_clase = crear_declaracion_metodo(#a,#c);
346 | t:tipo i:IDENT PUNTO_Y_COMA
348 #declaracion_elemento_clase = crear_declaracion_atributo(#i,#t,#c);
349 log.write("ATRIBUTO: "+#i.getText()+"\n");
353 // Cualificador de visibilidad
354 cualificador_elemento_clase! :
355 OCULTO {#cualificador_elemento_clase = #(#[OCULTO]);}
356 | {#cualificador_elemento_clase = #(#[VISIBLE,"visible"]);}
367 ambito_abrir(#i,"METODO");
368 log.write("METODO: "+#i.getText()+"\n");
371 p:declaracion_parametros
374 {#prototipo_metodo = #(#[PROTOTIPO,"prototipo"],#i,#(#[PARAMETROS,"parametros"],#p),#(#[RESULTADO,"resultado"],#t));}
375 | {#prototipo_metodo = #(#[PROTOTIPO,"prototipo"],#i,#(#[PARAMETROS,"parametros"],#p),#(#[RESULTADO,"resultado"],#[VACIO, "vacio"]));}
379 declaracion_parametros :
380 declaracion_parametro (COMA! declaracion_parametro)*
384 ///////////////////////////////////////////////////////////
385 // DECLARACION DE PARAMETRO
386 ///////////////////////////////////////////////////////////
388 declaracion_parametro!: t:tipo i:IDENT
389 {#declaracion_parametro = crear_declaracion_parametro(#i,#t);}
393 LLAVE_ABIERTA {log.incNivel();}
394 d:declaraciones_variables_locales
396 LLAVE_CERRADA {log.decNivel();}
397 {#definicion_metodo= #(#[DEFINICION,"definicion"],#(#[VARIABLES_LOCALES,"variables_locales"],#d), #b);}
400 declaraciones_variables_locales :
401 (declaracion_variables_locales tipo IDENT) =>
402 declaracion_variables_locales declaraciones_variables_locales
403 |(declaracion_variables_locales) =>
404 declaracion_variables_locales
408 declaracion_variables_locales :
409 t:tipo! lista_nombres_variables_locales[#t] PUNTO_Y_COMA! ;
411 lista_nombres_variables_locales [AST t] :
412 nombre_variable_local[#t] (COMA! nombre_variable_local[#t])* ;
414 /////////////////////////////////////////////////////////////////
415 // DECLARACION DE VARIABLE LOCAL
416 //////////////////////////////////////////////////////////////////
418 nombre_variable_local! [AST t] :
420 { #nombre_variable_local = crear_declaracion_variable_local(#i,#t); }
423 ///////////////////////////////////////////////////////////
425 ///////////////////////////////////////////////////////////
426 instrucciones : (instruccion)* ;
429 i:instruccion_simple PUNTO_Y_COMA
430 {#instruccion=#(#[INSTRUCCION,"instruccion"],#i);}
431 | j:instruccion_compuesta
432 {#instruccion=#(#[INSTRUCCION,"instruccion"],#j);}
436 (expresion ASIGNACION CREAR) => crear
437 | (expresion ASIGNACION) => asignacion
443 instruccion_compuesta :
449 e1:expresion ASIGNACION e2:expresion
450 { #asignacion = #(#[ASIGNACION],#e1,#e2); }
454 retorno! : DEV e:expresion
455 { #retorno = #(#[DEV],#e); }
464 { #llamada_metodo = #(#[LLAMADA,"llamada"],#i,#(#[EXPRESIONES,"expresiones"],#s)); }
467 lista_expresiones : expresion (COMA! expresion)*
471 condicion : SI^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! ENTONCES!
473 (SINO! bloque)? FINSI! ;
476 iteracion : MIENTRAS^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! HACER!
480 bloque!: i:instrucciones
481 {#bloque=#(#[INSTRUCCIONES,"instrucciones"],#i);}
484 /////////////////////////////////////////////////////////////
486 ////////////////////////////////////////////////////////////
489 expresion_nivel_1 (O^ expresion_nivel_1)* ;
492 expresion_nivel_2 (Y^ expresion_nivel_2)* ;
495 (NO^)? expresion_nivel_3 ;
499 ((MAYOR^|MAYOR_IGUAL^|MENOR^|MENOR_IGUAL^|IGUAL^|DISTINTO^)
500 expresion_nivel_4)? ;
503 expresion_nivel_5 ((MAS^|MENOS^) expresion_nivel_5)* ;
506 expresion_nivel_6 ((POR^|DIVISION^) expresion_nivel_6)* ;
509 MENOS i:expresion_nivel_7
510 {#expresion_nivel_6=#(#[MENOSUNARIO,"menosunario"],#i);}
515 PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO!
518 | (acceso PARENTESIS_ABIERTO) => llamada_metodo
519 | (acceso CORCHETE_ABIERTO) => acceso_tabla
527 //////////////////////////////////////////////////////////////
529 //////////////////////////////////////////////////////////////
530 acceso_tabla!: c:acceso CORCHETE_ABIERTO d:lista_expresiones_nv CORCHETE_CERRADO
531 {#acceso_tabla=#(#[ACCESO_TABLA,"acceso_tabla"],#c,#(#[EXPRESIONES,"expresiones"],#d));}
534 //////////////////////////////////////////////////////////////
535 // ACCESOS SIMPLES Y A OBJETOS
536 //////////////////////////////////////////////////////////////
539 (IDENT PUNTO)=> i1:IDENT PUNTO i2:IDENT
541 log.write("ACCESO SIMPLE: "+#i1.getText());
542 #acceso=#(#[ACCESO_OBJETO,"acceso_objeto"], ambito_tratar_acceso_simple(#i1), #i2);
546 log.write("ACCESO SIMPLE: "+#i.getText());
547 #acceso = ambito_tratar_acceso_simple(#i);
551 lista_expresiones_nv :
552 expresion (COMA! expresion)*
555 //////////////////////////////////////////////////////////
557 /////////////////////////////////////////////////////////
559 tipo_predefinido_simple
560 | tipo_predefinido_compuesto
561 | i:IDENT {#tipo = ambito_tratar_ident_tipo(#i);
562 log.write("IDENTIFICADOR TIPO: "+#i.getText()+"\n");
566 tipo_predefinido_simple :
573 tipo_predefinido_compuesto :
577 formacion! : FORMACION l:lista_enteros
578 ( t:tipo_predefinido_simple
579 {#formacion = #(#[FORMACION,"formacion"],#(#[LISTA_ENTEROS,"lista_enteros"],#l),#t);}
581 {#formacion = #(#[FORMACION,"formacion"], #(#[LISTA_ENTEROS,"lista_enteros"],#l), ambito_tratar_ident_tipo(#i));
582 log.write("IDENTIFICADOR TIPO: "+#i.getText()+"\n");
586 lista_enteros : LIT_ENTERO (COMA! LIT_ENTERO)*;
589 escribir!: ESCRIBIR PARENTESIS_ABIERTO e:expresion PARENTESIS_CERRADO
591 #escribir = arbol_escribir(#e);
593 log.write("IDENTIFICADOR TIPO: "+#e.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
594 }catch(NullPointerException n){}
597 //de momento se pasa el arbol completo del tipo, pero creo que con el ident seria
598 //suficiente para el analisis semantico
599 crear!: e1:expresion ASIGNACION CREAR PARENTESIS_ABIERTO i:expresion PARENTESIS_CERRADO
601 #crear = arbol_crear(#e1,#i);
603 log.write("IDENTIFICADOR TIPO: "+#i.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
604 }catch(NullPointerException n){}
608 entero_a_real!: ENTERO_A_REAL PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
609 {## = #(#[ENTERO_A_REAL],#e1);};
611 real_a_entero!: REAL_A_ENTERO PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
612 {## = #(#[REAL_A_ENTERO],#e1);};