7 class Anasint extends Parser;
43 Pila_Ambitos pilaambitos = new Pila_Ambitos();
45 void ambito_abrir_programa(){
46 if(pilaambitos.vacia() == true){
47 Ambito a = new Ambito("programa","PROGRAMA",null,null);
48 pilaambitos.apilar_ambito(a);
52 void ambito_abrir(AST nombre, String tipo){
53 Ambito act = pilaambitos.ambito_actual();
54 String tipoAct = act.getTipo();
55 if(tipo.equals("MODULO") && tipoAct.equals("PROGRAMA")
56 || tipo.equals("CLASE") && tipoAct.equals("MODULO")
57 || tipo.equals("METODO") && tipoAct.equals("CLASE")){
58 Ambito A = new Ambito(nombre.getText(), tipo, null, act);
59 pilaambitos.apilar_ambito(A);
64 if(pilaambitos.vacia() == false){
65 pilaambitos.desapilar_ambito();
68 void ambito_cerrar_programa(){
69 if(pilaambitos.vacia() == false && pilaambitos.ambito_actual().getTipo().equals("PROGRAMA"))
70 pilaambitos.desapilar_ambito();
73 AST crear_declaracion_modulo(AST nombre_modulo, AST definicion_modulo){
74 String m = nombre_modulo.getText();
75 AST M = #(#[MODULO, "modulo"],nombre_modulo, definicion_modulo);
76 Simbolo S = new Simbolo(m, M);
77 pilaambitos.ambito_actual().setDeclaracion(S);
81 AST crear_declaracion_clase (AST nombre_clase, AST cualificador_clase, AST definicion_clase){
82 String c = nombre_clase.getText();
83 AST C = #(#[CLASE,"clase"],nombre_clase, cualificador_clase, definicion_clase);
84 Simbolo S = new Simbolo(c,C);
85 pilaambitos.ambito_actual().setDeclaracion(S);
89 AST crear_declaracion_metodo (AST declaracion_metodo, AST cualificador_metodo){
90 AST MT = #(#[METODO,"metodo"], declaracion_metodo, cualificador_metodo);
91 String mt = MT.getFirstChild().getFirstChild().getText();
92 Simbolo S = new Simbolo(mt,MT);
93 pilaambitos.ambito_actual().setDeclaracion(S);
97 AST crear_declaracion_atributo (AST nombre_atributo, AST tipo_atributo, AST cualificador_atributo){
98 String a = nombre_atributo.getText();
99 AST A = #(#[ATRIBUTO,"atributo"], nombre_atributo, tipo_atributo, cualificador_atributo);
100 Simbolo S = new Simbolo(a, A);
101 pilaambitos.ambito_actual().setDeclaracion(S);
105 AST crear_declaracion_parametro (AST nombre_parametro, AST tipo_parametro){
106 String p = nombre_parametro.getText();
107 AST P = #(#[PARAMETRO,"parametro"], nombre_parametro, tipo_parametro);
108 Simbolo S = new Simbolo(p, P);
109 pilaambitos.ambito_actual().setDeclaracion(S);
115 AST crear_declaracion_variable_local (AST nombre_variable, AST tipo_variable){
116 String v = nombre_variable.getText();
117 AST V = #(#[VARIABLE_LOCAL,"variable_local"], nombre_variable, tipo_variable);
118 Simbolo S = new Simbolo(v, V);
119 pilaambitos.ambito_actual().setDeclaracion(S);
123 AST ambito_tratar_acceso_simple (AST ident){
124 String acc = ident.getText();
127 if ((s=pilaambitos.buscar_simbolo(acc)) != null){
128 dec_acc = s.getDeclaracion(); // AST de la declaracion del acceso simple
129 log.writeNoIndent(" ("+dec_acc.getText()+")\n");
132 String men = "ERROR RN: Identificador " +acc+ " no declarado";
133 dec_acc = #(#[ERROR,"error"]);
134 System.out.println(men); // identificador no declarado
135 log.writeNoIndent(" (error)\n");
137 AST ACC = #(#[ACCESO_SIMPLE,"acceso_simple"], ident, dec_acc);
141 AST ambito_tratar_ident_tipo (AST ident){
143 String tipo = ident.getText();
144 men = "ERROR RN: Identificador de tipo "+tipo+" no declarado";
145 Ambito amb = pilaambitos.ambito_actual();
146 while (amb != null && !amb.getTipo().equals("MODULO"))
147 amb = amb.getContenedor();
149 System.out.println(men); // el tipo no es un tipo clase
150 return #(#[ERROR,"error"]);
152 Simbolo simb = amb.getDeclaracion(tipo);
154 System.out.println(men); // el tipo no es un tipo clase
155 return #(#[ERROR,"error"]); //#(#[ERROR,"error"]);
157 AST C = simb.getDeclaracion();
162 public AST arbol_crear(AST e1, AST e2){
164 return #(#[CREAR,"crear"],e1, #[ERROR,"error"]);
166 return #(#[CREAR,"crear"],e1, e2);
169 public AST arbol_escribir(AST e){
171 return #(#[ERROR,"error"]);
173 return #(#[ESCRIBIR,"escribir"],e);
176 //comprueba que existe la clase programa y el metodo inicio en esta
177 public void comprobarPrograma(AST modulo){
178 boolean programa=false;
179 AST clase = modulo.getFirstChild().getNextSibling().getNextSibling().getFirstChild();
180 String nombre = clase.getFirstChild().getText();
182 if(nombre.equals("Programa") && !programa){
184 if(clase.getFirstChild().getNextSibling().getText().equals("inst")){
185 System.out.println("ERROR AS: La clase Programa tiene que ser no instanciable");
187 comprobarInicio(clase);
190 clase = clase.getNextSibling();
193 nombre = clase.getFirstChild().getText();
196 System.out.println("ERROR AS: No se ha definido la clase Programa");
200 public void comprobarInicio(AST Prog){
201 boolean inicio = false;
203 AST modulo = Prog.getFirstChild().getNextSibling().getNextSibling();
205 while(modulo.getType() != METODO && modulo != null){
206 modulo = modulo.getNextSibling();
208 if(modulo != null && !modulo.getFirstChild().getFirstChild().getText().equals("inicio")){
209 System.out.println("ERROR AS: Debe haber un metodo inicio en la clase Programa, y debe ser unico");
210 }if(modulo.getNextSibling() != null){
211 System.out.println("ERROR AS: Debe haber un metodo inicio en la clase Programa, y debe ser unico");
219 /////////////////////////////////////////////////////////
220 // DECLARACION DE MODULO
221 /////////////////////////////////////////////////////////
223 declaracion_modulo![String f] :
225 ambito_abrir_programa();
226 log = new logFile(f);
230 ambito_abrir (#n,"MODULO");
231 log.write("MODULO: "+#n.getText()+"\n");
234 d:definicion_modulo EOF
237 #declaracion_modulo=crear_declaracion_modulo(#n,#d);
238 comprobarPrograma(#declaracion_modulo);
239 ambito_cerrar_programa();
245 nombre_modulo : MODULO! IDENT ;
248 lista_declaraciones_clases;
256 lista_ident: IDENT (COMA! IDENT)*;
259 (IMPORTACION DOS_PUNTOS l:lista_ident)?
260 {#importacion = #(#[IMPORTACION, "importacion"], #l);}
264 EXPORTACION^ DOS_PUNTOS!
265 l:lista_declaraciones_clases
269 IMPLEMENTACION^ DOS_PUNTOS!
270 l:lista_declaraciones_clases
273 lista_declaraciones_clases :
278 ///////////////////////////////////////////////////////////
279 // DECLARACION DE CLASE
280 ///////////////////////////////////////////////////////////
282 declaracion_clase ! :
286 ambito_abrir(#n,"CLASE");
287 log.write("CLASE: "+#n.getText()+"\n");
294 #declaracion_clase = crear_declaracion_clase(#n,#c,#d);
298 cualificador_clase! :
299 INST {#cualificador_clase = #(#[INST]);}
300 | {#cualificador_clase = #(#[NO_INST,"no_inst"]);}
303 nombre_clase : CLASE! IDENT ;
307 declaraciones_elemento_clase
311 declaraciones_elemento_clase :
312 (declaracion_elemento_clase)* ;
314 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
315 // DECLARACION DE ELEMENTO CLASE: METODO O ATRIBUTO
316 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
318 declaracion_elemento_clase! :
319 c:cualificador_elemento_clase
320 ((IDENT PARENTESIS_ABIERTO) =>
324 #declaracion_elemento_clase = crear_declaracion_metodo(#a,#c);
327 | t:tipo i:IDENT PUNTO_Y_COMA
329 #declaracion_elemento_clase = crear_declaracion_atributo(#i,#t,#c);
330 log.write("ATRIBUTO: "+#i.getText()+"\n");
334 // Cualificador de visibilidad
335 cualificador_elemento_clase! :
336 OCULTO {#cualificador_elemento_clase = #(#[OCULTO]);}
337 | {#cualificador_elemento_clase = #(#[VISIBLE,"visible"]);}
348 ambito_abrir(#i,"METODO");
349 log.write("METODO: "+#i.getText()+"\n");
352 p:declaracion_parametros
355 {#prototipo_metodo = #(#[PROTOTIPO,"prototipo"],#i,#(#[PARAMETROS,"parametros"],#p),#(#[RESULTADO,"resultado"],#t));}
356 | {#prototipo_metodo = #(#[PROTOTIPO,"prototipo"],#i,#(#[PARAMETROS,"parametros"],#p),#(#[RESULTADO,"resultado"],#[VACIO, "vacio"]));}
360 declaracion_parametros :
361 declaracion_parametro (COMA! declaracion_parametro)*
365 ///////////////////////////////////////////////////////////
366 // DECLARACION DE PARAMETRO
367 ///////////////////////////////////////////////////////////
369 declaracion_parametro!: t:tipo i:IDENT
370 {#declaracion_parametro = crear_declaracion_parametro(#i,#t);}
374 LLAVE_ABIERTA {log.incNivel();}
375 d:declaraciones_variables_locales
377 LLAVE_CERRADA {log.decNivel();}
378 {#definicion_metodo= #(#[DEFINICION,"definicion"],#(#[VARIABLES_LOCALES,"variables_locales"],#d), #b);}
381 declaraciones_variables_locales :
382 (declaracion_variables_locales tipo IDENT) =>
383 declaracion_variables_locales declaraciones_variables_locales
384 |(declaracion_variables_locales) =>
385 declaracion_variables_locales
389 declaracion_variables_locales :
390 t:tipo! lista_nombres_variables_locales[#t] PUNTO_Y_COMA! ;
392 lista_nombres_variables_locales [AST t] :
393 nombre_variable_local[#t] (COMA! nombre_variable_local[#t])* ;
395 /////////////////////////////////////////////////////////////////
396 // DECLARACION DE VARIABLE LOCAL
397 //////////////////////////////////////////////////////////////////
399 nombre_variable_local! [AST t] :
401 { #nombre_variable_local = crear_declaracion_variable_local(#i,#t); }
404 ///////////////////////////////////////////////////////////
406 ///////////////////////////////////////////////////////////
407 instrucciones : (instruccion)* ;
410 i:instruccion_simple PUNTO_Y_COMA
411 {#instruccion=#(#[INSTRUCCION,"instruccion"],#i);}
412 | j:instruccion_compuesta
413 {#instruccion=#(#[INSTRUCCION,"instruccion"],#j);}
417 (expresion ASIGNACION CREAR) => crear
418 | (expresion ASIGNACION) => asignacion
424 instruccion_compuesta :
430 e1:expresion ASIGNACION e2:expresion
431 { #asignacion = #(#[ASIGNACION],#e1,#e2); }
435 retorno! : DEV e:expresion
436 { #retorno = #(#[DEV],#e); }
445 { #llamada_metodo = #(#[LLAMADA,"llamada"],#i,#(#[EXPRESIONES,"expresiones"],#s)); }
448 lista_expresiones : expresion (COMA! expresion)*
452 condicion : SI^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! ENTONCES!
454 (SINO! bloque)? FINSI! ;
457 iteracion : MIENTRAS^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! HACER!
461 bloque!: i:instrucciones
462 {#bloque=#(#[INSTRUCCIONES,"instrucciones"],#i);}
465 /////////////////////////////////////////////////////////////
467 ////////////////////////////////////////////////////////////
470 expresion_nivel_1 (O^ expresion_nivel_1)* ;
473 expresion_nivel_2 (Y^ expresion_nivel_2)* ;
476 (NO^)? expresion_nivel_3 ;
480 ((MAYOR^|MAYOR_IGUAL^|MENOR^|MENOR_IGUAL^|IGUAL^|DISTINTO^)
481 expresion_nivel_4)? ;
484 expresion_nivel_5 ((MAS^|MENOS^) expresion_nivel_5)* ;
487 expresion_nivel_6 ((POR^|DIVISION^) expresion_nivel_6)* ;
490 MENOS i:expresion_nivel_7
491 {#expresion_nivel_6=#(#[MENOSUNARIO,"menosunario"],#i);}
496 PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO!
499 | (acceso PARENTESIS_ABIERTO) => llamada_metodo
500 | (acceso CORCHETE_ABIERTO) => acceso_tabla
508 //////////////////////////////////////////////////////////////
510 //////////////////////////////////////////////////////////////
511 acceso_tabla!: c:acceso CORCHETE_ABIERTO d:lista_expresiones_nv CORCHETE_CERRADO
512 {#acceso_tabla=#(#[ACCESO_TABLA,"acceso_tabla"],#c,#(#[EXPRESIONES,"expresiones"],#d));}
515 //////////////////////////////////////////////////////////////
516 // ACCESOS SIMPLES Y A OBJETOS
517 //////////////////////////////////////////////////////////////
520 (IDENT PUNTO)=> i1:IDENT PUNTO i2:IDENT
522 log.write("ACCESO SIMPLE: "+#i1.getText());
523 #acceso=#(#[ACCESO_OBJETO,"acceso_objeto"], ambito_tratar_acceso_simple(#i1), #i2);
527 log.write("ACCESO SIMPLE: "+#i.getText());
528 #acceso = ambito_tratar_acceso_simple(#i);
532 lista_expresiones_nv :
533 expresion (COMA! expresion)*
536 //////////////////////////////////////////////////////////
538 /////////////////////////////////////////////////////////
540 tipo_predefinido_simple
541 | tipo_predefinido_compuesto
542 | i:IDENT {#tipo = ambito_tratar_ident_tipo(#i);
543 log.write("IDENTIFICADOR TIPO: "+#i.getText()+"\n");
547 tipo_predefinido_simple :
554 tipo_predefinido_compuesto :
558 formacion! : FORMACION l:lista_enteros
559 ( t:tipo_predefinido_simple
560 {#formacion = #(#[FORMACION,"formacion"],#(#[LISTA_ENTEROS,"lista_enteros"],#l),#t);}
562 {#formacion = #(#[FORMACION,"formacion"], #(#[LISTA_ENTEROS,"lista_enteros"],#l), ambito_tratar_ident_tipo(#i));
563 log.write("IDENTIFICADOR TIPO: "+#i.getText()+"\n");
567 lista_enteros : LIT_ENTERO (COMA! LIT_ENTERO)*;
570 escribir!: ESCRIBIR PARENTESIS_ABIERTO e:expresion PARENTESIS_CERRADO
572 #escribir = arbol_escribir(#e);
574 log.write("IDENTIFICADOR TIPO: "+#e.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
575 }catch(NullPointerException n){}
578 //de momento se pasa el arbol completo del tipo, pero creo que con el ident seria
579 //suficiente para el analisis semantico
580 crear!: e1:expresion ASIGNACION CREAR PARENTESIS_ABIERTO i:expresion PARENTESIS_CERRADO
582 #crear = arbol_crear(#e1,#i);
584 log.write("IDENTIFICADOR TIPO: "+#i.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
585 }catch(NullPointerException n){}
589 entero_a_real!: ENTERO_A_REAL PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
590 {## = #(#[ENTERO_A_REAL],#e1);};
592 real_a_entero!: REAL_A_ENTERO PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
593 {## = #(#[REAL_A_ENTERO],#e1);};