incluidos todos, que no lo habĂ­a hecho antes
[PL2.git] / Anasint.g
1 header{
2         import java.util.*;
3         import antlr.*;
4         import java.io.*;
5 }
6
7 class Anasint extends Parser;
8
9 options{
10         buildAST=true;
11 }
12
13 tokens{
14         PROGRAMA;
15         VISIBLE;
16         OCULTO;
17         NO_INST;
18         ATRIBUTO;
19         METODO;
20         PROTOTIPO;
21         PARAMETRO;
22         PARAMETROS;
23         EXPRESIONES;
24         RESULTADO;
25         DEFINICION;
26         VACIO;
27     VARIABLE_LOCAL;
28         VARIABLES_LOCALES;
29         INSTRUCCION;
30         INSTRUCCIONES;
31         MENOSUNARIO;
32         LLAMADA;
33         ACCESO_TABLA;
34         ACCESO_OBJETO;
35         ACCESO_SIMPLE;
36         LISTA_ENTEROS;
37         ERROR;
38 }
39
40 {
41         logFile log;
42         int margen = 0;
43         Pila_Ambitos pilaambitos = new Pila_Ambitos();
44         
45         void ambito_abrir_programa(){
46                 if(pilaambitos.vacia() == true){
47                         Ambito a = new Ambito("programa","PROGRAMA",null,null);
48                         pilaambitos.apilar_ambito(a);
49                 }
50         }
51   
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);
60                 }
61         }
62         
63         void ambito_cerrar(){
64                 if(pilaambitos.vacia() == false){
65                         pilaambitos.desapilar_ambito();
66                 }
67         }
68         void ambito_cerrar_programa(){
69                 if(pilaambitos.vacia() == false && pilaambitos.ambito_actual().getTipo().equals("PROGRAMA"))
70                         pilaambitos.desapilar_ambito();
71         }
72         
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);
78                 return M;
79         }
80         
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);
86                 return C;
87         }
88
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);
94                 return MT;
95         }
96         
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);
102         return A;
103         }
104
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);
110                 return P;
111                 
112         }
113         
114         
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);
120                 return V;
121         }
122
123         AST ambito_tratar_acceso_simple (AST ident){
124                 String acc = ident.getText();
125                 AST dec_acc = null;
126                 Simbolo s;
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");
130                 }
131                 else{
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");
136                 }
137                 AST ACC = #(#[ACCESO_SIMPLE,"acceso_simple"], ident, dec_acc);
138                 return ACC;
139         }
140
141         AST ambito_tratar_ident_tipo (AST ident){
142                 String men = "";
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();
148                 if (amb == null){
149                         System.out.println(men); // el tipo no es un tipo clase
150                         return #(#[ERROR,"error"]);
151                 }
152                 Simbolo simb = amb.getDeclaracion(tipo);
153                 if (simb == null){
154                         System.out.println(men); // el tipo no es un tipo clase
155                         return #(#[ERROR,"error"]); //#(#[ERROR,"error"]);
156                 }
157                 AST C = simb.getDeclaracion();
158                 return C;
159         }
160         
161         
162         public AST arbol_crear(AST e1, AST e2){
163                 if(e2 == null){
164                         return #(#[CREAR,"crear"],e1, #[ERROR,"error"]);
165                 }else
166                         return  #(#[CREAR,"crear"],e1, e2);
167         }
168         
169         public AST arbol_escribir(AST e){
170                 if(e == null){
171                         return #(#[ERROR,"error"]);
172                 }else
173                         return  #(#[ESCRIBIR,"escribir"],e);
174         }
175
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();
181                 while(true){
182                         if(nombre.equals("Programa") && !programa){
183                                 programa = true;
184                                 if(clase.getFirstChild().getNextSibling().getText().equals("inst")){
185                                         System.out.println("ERROR AS: La clase Programa tiene que ser no instanciable");
186                                 }
187                                 comprobarInicio(clase);
188                         }
189                         
190                         clase = clase.getNextSibling();
191                         if(clase == null)
192                                 break;
193                         nombre = clase.getFirstChild().getText();
194                 }
195                 if(!programa){
196                         System.out.println("ERROR AS: No se ha definido la clase Programa");
197                 }
198         }
199         
200         public void comprobarInicio(AST Prog){
201                 boolean inicio = false;
202
203                 AST modulo = Prog.getFirstChild().getNextSibling().getNextSibling();
204                 if(modulo != null){
205                         while(modulo.getType() != METODO && modulo != null){
206                                 modulo = modulo.getNextSibling();
207                         }
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");
212                         }
213                 }
214         }
215         
216         
217 }
218         
219 /////////////////////////////////////////////////////////
220 // DECLARACION DE MODULO          
221 /////////////////////////////////////////////////////////
222  
223 declaracion_modulo![String f] :
224    {
225         ambito_abrir_programa();
226         log = new logFile(f);
227    }
228    n:nombre_modulo
229    {
230         ambito_abrir (#n,"MODULO");
231         log.write("MODULO: "+#n.getText()+"\n");
232         log.incNivel();
233    }
234    d:definicion_modulo EOF
235    {
236         ambito_cerrar();
237     #declaracion_modulo=crear_declaracion_modulo(#n,#d);
238     comprobarPrograma(#declaracion_modulo);
239     ambito_cerrar_programa();
240     log.decNivel();
241     log.close();
242     }
243    ;
244  
245 nombre_modulo : MODULO! IDENT ;
246 /*
247 definicion_modulo :
248         lista_declaraciones_clases;
249 */
250 definicion_modulo :
251    importacion
252    (exportacion)+
253    (implementacion)?
254           ;
255
256 lista_ident: IDENT (COMA! IDENT)*;
257
258 importacion! :
259         (IMPORTACION DOS_PUNTOS l:lista_ident)?
260         {#importacion = #(#[IMPORTACION, "importacion"], #l);}
261         ;
262
263 exportacion :
264         EXPORTACION^ DOS_PUNTOS!
265         l:lista_declaraciones_clases
266         ;
267
268 implementacion :
269         IMPLEMENTACION^ DOS_PUNTOS!
270         l:lista_declaraciones_clases
271         ;
272
273 lista_declaraciones_clases :    
274    (declaracion_clase)*
275    ;
276
277              
278 ///////////////////////////////////////////////////////////
279 // DECLARACION DE CLASE          
280 ///////////////////////////////////////////////////////////
281  
282 declaracion_clase ! : 
283    c:cualificador_clase 
284    n:nombre_clase
285    {
286         ambito_abrir(#n,"CLASE");
287         log.write("CLASE: "+#n.getText()+"\n");
288         log.incNivel();
289         }
290    d:definicion_clase 
291    {
292         ambito_cerrar();
293     log.decNivel();
294     #declaracion_clase = crear_declaracion_clase(#n,#c,#d);
295     }
296    ;
297
298 cualificador_clase! :  
299     INST {#cualificador_clase = #(#[INST]);}
300    |     {#cualificador_clase = #(#[NO_INST,"no_inst"]);}
301    ;
302
303 nombre_clase : CLASE! IDENT ;
304
305 definicion_clase : 
306    LLAVE_ABIERTA! 
307       declaraciones_elemento_clase 
308    LLAVE_CERRADA! 
309    ; 
310
311 declaraciones_elemento_clase : 
312      (declaracion_elemento_clase)* ;
313
314 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
315 // DECLARACION DE ELEMENTO CLASE: METODO O ATRIBUTO          
316 /////////////////////////////////////////////////////////////////////////////////////////////////////////////
317
318 declaracion_elemento_clase! : 
319     c:cualificador_elemento_clase 
320     ((IDENT PARENTESIS_ABIERTO) => 
321        a:declaracion_metodo 
322        {
323         ambito_cerrar();
324         #declaracion_elemento_clase = crear_declaracion_metodo(#a,#c);
325        }
326        
327     | t:tipo i:IDENT PUNTO_Y_COMA
328        {
329         #declaracion_elemento_clase = crear_declaracion_atributo(#i,#t,#c);
330         log.write("ATRIBUTO: "+#i.getText()+"\n");
331        })
332     ;
333
334 // Cualificador de visibilidad
335 cualificador_elemento_clase! :  
336    OCULTO {#cualificador_elemento_clase = #(#[OCULTO]);}
337    | {#cualificador_elemento_clase = #(#[VISIBLE,"visible"]);}
338    ;
339
340 declaracion_metodo :
341    prototipo_metodo
342    definicion_metodo
343    ;
344    
345 prototipo_metodo! :   
346    i:IDENT
347    {
348    ambito_abrir(#i,"METODO");
349    log.write("METODO: "+#i.getText()+"\n");
350    }
351    PARENTESIS_ABIERTO 
352    p:declaracion_parametros 
353    PARENTESIS_CERRADO 
354    (DEV t:tipo 
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"]));}
357    )
358    ;
359
360 declaracion_parametros : 
361       declaracion_parametro (COMA! declaracion_parametro)* 
362     |
363     ;
364
365  ///////////////////////////////////////////////////////////
366 // DECLARACION DE PARAMETRO         
367 ///////////////////////////////////////////////////////////   
368  
369 declaracion_parametro!: t:tipo i:IDENT 
370     {#declaracion_parametro = crear_declaracion_parametro(#i,#t);}
371     ;
372
373 definicion_metodo! : 
374    LLAVE_ABIERTA {log.incNivel();}
375       d:declaraciones_variables_locales  
376       b:bloque     
377    LLAVE_CERRADA {log.decNivel();}
378    {#definicion_metodo=   #(#[DEFINICION,"definicion"],#(#[VARIABLES_LOCALES,"variables_locales"],#d), #b);}
379    ;
380
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 
386    | 
387    ;
388    
389 declaracion_variables_locales  : 
390    t:tipo! lista_nombres_variables_locales[#t] PUNTO_Y_COMA! ;
391
392 lista_nombres_variables_locales [AST t] : 
393    nombre_variable_local[#t] (COMA! nombre_variable_local[#t])* ;
394   
395  /////////////////////////////////////////////////////////////////
396 // DECLARACION DE VARIABLE LOCAL         
397 //////////////////////////////////////////////////////////////////   
398  
399 nombre_variable_local! [AST t] : 
400    i:IDENT 
401    { #nombre_variable_local = crear_declaracion_variable_local(#i,#t); }
402    ;
403    
404 ///////////////////////////////////////////////////////////
405 // INSTRUCCIONES 
406 ///////////////////////////////////////////////////////////
407 instrucciones : (instruccion)* ;
408
409 instruccion! : 
410    i:instruccion_simple PUNTO_Y_COMA
411    {#instruccion=#(#[INSTRUCCION,"instruccion"],#i);}
412  | j:instruccion_compuesta 
413    {#instruccion=#(#[INSTRUCCION,"instruccion"],#j);}
414  ;
415
416 instruccion_simple : 
417         (expresion ASIGNACION CREAR) => crear
418   | (expresion ASIGNACION) => asignacion
419   | llamada_metodo
420   | escribir
421   | retorno
422   ;
423
424 instruccion_compuesta : 
425      condicion
426    | iteracion
427    ;
428  
429 asignacion! : 
430    e1:expresion ASIGNACION e2:expresion
431    { #asignacion = #(#[ASIGNACION],#e1,#e2); }
432    ;
433     
434  
435 retorno! : DEV e:expresion 
436    { #retorno = #(#[DEV],#e); }
437    ;   
438
439  
440 llamada_metodo! :  
441    i:acceso 
442    PARENTESIS_ABIERTO 
443            s:lista_expresiones 
444    PARENTESIS_CERRADO 
445    { #llamada_metodo = #(#[LLAMADA,"llamada"],#i,#(#[EXPRESIONES,"expresiones"],#s)); }
446    ;
447
448 lista_expresiones :  expresion (COMA! expresion)*
449                   |
450                   ;
451  
452 condicion : SI^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! ENTONCES! 
453                bloque 
454            (SINO! bloque)? FINSI! ;
455
456  
457 iteracion : MIENTRAS^ PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO! HACER! 
458                bloque 
459             FINMIENTRAS! ;    
460
461 bloque!: i:instrucciones 
462         {#bloque=#(#[INSTRUCCIONES,"instrucciones"],#i);}
463 ;
464
465 /////////////////////////////////////////////////////////////
466 // EXPRESIONES 
467 ////////////////////////////////////////////////////////////
468
469 expresion : 
470    expresion_nivel_1 (O^ expresion_nivel_1)*  ;
471    
472 expresion_nivel_1 : 
473    expresion_nivel_2 (Y^ expresion_nivel_2)* ;
474    
475 expresion_nivel_2 : 
476    (NO^)? expresion_nivel_3 ;   
477
478 expresion_nivel_3 : 
479    expresion_nivel_4 
480   ((MAYOR^|MAYOR_IGUAL^|MENOR^|MENOR_IGUAL^|IGUAL^|DISTINTO^) 
481     expresion_nivel_4)? ;
482
483 expresion_nivel_4 :
484      expresion_nivel_5 ((MAS^|MENOS^) expresion_nivel_5)* ;
485    
486 expresion_nivel_5 :
487       expresion_nivel_6 ((POR^|DIVISION^) expresion_nivel_6)* ;
488
489 expresion_nivel_6 :
490         MENOS i:expresion_nivel_7
491         {#expresion_nivel_6=#(#[MENOSUNARIO,"menosunario"],#i);}
492         | expresion_nivel_7
493         ;
494
495 expresion_nivel_7:
496         PARENTESIS_ABIERTO! expresion PARENTESIS_CERRADO!
497   | entero_a_real
498   | real_a_entero
499   | (acceso PARENTESIS_ABIERTO) => llamada_metodo
500   | (acceso CORCHETE_ABIERTO) => acceso_tabla
501   | acceso
502   | LIT_ENTERO
503   | LIT_REAL
504   | LIT_CAR
505   | CIERTO
506   | FALSO
507   ;    
508 //////////////////////////////////////////////////////////////
509 // ACCESOS A TABLAS
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));}
513 ;
514
515 //////////////////////////////////////////////////////////////
516 // ACCESOS SIMPLES Y A OBJETOS
517 //////////////////////////////////////////////////////////////
518  
519 acceso!: 
520    (IDENT PUNTO)=> i1:IDENT PUNTO i2:IDENT
521            {
522                 log.write("ACCESO SIMPLE: "+#i1.getText());
523                 #acceso=#(#[ACCESO_OBJETO,"acceso_objeto"], ambito_tratar_acceso_simple(#i1), #i2);
524 }
525  | i:IDENT  
526            {
527            log.write("ACCESO SIMPLE: "+#i.getText());
528                 #acceso = ambito_tratar_acceso_simple(#i);
529            }
530  ;
531
532 lista_expresiones_nv :  
533     expresion (COMA! expresion)*
534                   ;
535
536 //////////////////////////////////////////////////////////
537 // TIPOS
538 /////////////////////////////////////////////////////////
539 tipo : 
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");
544  }
545  ;
546
547 tipo_predefinido_simple :
548      ENTERO 
549    | REAL   
550    | LOGICO
551    | CARACTER
552    ;
553
554 tipo_predefinido_compuesto :
555    formacion
556    ;
557  
558 formacion! : FORMACION l:lista_enteros
559          ( t:tipo_predefinido_simple
560             {#formacion = #(#[FORMACION,"formacion"],#(#[LISTA_ENTEROS,"lista_enteros"],#l),#t);}
561             | i:IDENT
562             {#formacion = #(#[FORMACION,"formacion"], #(#[LISTA_ENTEROS,"lista_enteros"],#l), ambito_tratar_ident_tipo(#i));
563                 log.write("IDENTIFICADOR TIPO: "+#i.getText()+"\n");
564 }
565 );
566
567 lista_enteros :  LIT_ENTERO (COMA! LIT_ENTERO)*;
568
569
570 escribir!: ESCRIBIR PARENTESIS_ABIERTO e:expresion PARENTESIS_CERRADO
571 {
572         #escribir = arbol_escribir(#e);
573         try{
574                 log.write("IDENTIFICADOR TIPO: "+#e.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
575         }catch(NullPointerException n){}
576 };
577
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
581 {
582         #crear = arbol_crear(#e1,#i);
583         try{
584                 log.write("IDENTIFICADOR TIPO: "+#i.getFirstChild().getNextSibling().getFirstChild().getText()+"\n");
585         }catch(NullPointerException n){}
586
587 };
588
589 entero_a_real!: ENTERO_A_REAL PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
590 {## = #(#[ENTERO_A_REAL],#e1);};
591
592 real_a_entero!: REAL_A_ENTERO PARENTESIS_ABIERTO e1:expresion PARENTESIS_CERRADO
593 {## = #(#[REAL_A_ENTERO],#e1);};