Acceso a clase
[PL2.git] / AnaSem.g
1 header{ \r
2         \r
3         import java.util.*; \r
4 \r
5 }\r
6 \r
7 class AnaSem extends TreeParser;\r
8 options{\r
9         buildAST=true;\r
10         importVocab=Analex;\r
11         importVocab=Anasint;\r
12 }\r
13\r
14   int cont_dev; // variable contador del numero de instrucciones DEV en un metodo\r
15         \r
16         \r
17         Atr_Expr AS_Literal(AST lit){\r
18                 Atr_Expr result = new Atr_Expr();\r
19                 AST tipo;\r
20                 if(lit == null) return null;\r
21                 switch(lit.getType()){\r
22                 case LIT_ENTERO: \r
23                         tipo = #(#[ENTERO,"entero"]);\r
24                         break;\r
25                 case LIT_REAL:\r
26                         tipo = #(#[REAL,"real"]);\r
27                         break;\r
28                 case LIT_CAR: \r
29                         tipo = #(#[CARACTER,"caracter"]);\r
30                         break;\r
31                 case CIERTO:\r
32                 case FALSO:\r
33                         tipo = #(#[LOGICO,"logico"]);\r
34                         break;\r
35                 default:\r
36                         return null;\r
37                 }\r
38                 result.setTipo(tipo);\r
39                 result.setLVal(false);\r
40                 result.setRVal(true);\r
41                 return result;\r
42         }\r
43         \r
44         Atr_Expr AS_Acceso_Simple(AST dec){\r
45                 Atr_Expr result = new Atr_Expr();\r
46                 AST tipo = null;\r
47                 if (dec == null) return null;\r
48                 switch(dec.getType()){\r
49                 case MODULO:\r
50                         System.out.println("ERROR CT: el tipo es modulo");\r
51                         return null;\r
52                 case CLASE: //acceso a clase no instanciable\r
53                         tipo = dec;\r
54                         result.setLVal(false);\r
55                         result.setRVal(false);\r
56                         break;\r
57                 case ATRIBUTO://acceso a un atributo de la propia clase\r
58                         tipo = dec.getFirstChild().getNextSibling();\r
59                         result.setLVal(true);\r
60                         result.setRVal(true);\r
61                         break;\r
62                 case METODO: //acceso a un metodo de la propia clase\r
63                         tipo = dec.getFirstChild();\r
64                         result.setLVal(false);\r
65                         result.setRVal(false);\r
66                         break;\r
67                 case PARAMETRO:\r
68                         tipo = dec.getFirstChild().getNextSibling();\r
69                         result.setLVal(false);\r
70                         result.setRVal(true);\r
71                         break;\r
72                 case VARIABLE_LOCAL:\r
73                         tipo = dec.getFirstChild().getNextSibling();\r
74                         result.setLVal(true);\r
75                         result.setRVal(true);\r
76                         break;\r
77                 case ERROR:\r
78                         return null;\r
79                 }\r
80                 result.setTipo(tipo);\r
81                 return result;\r
82         }\r
83         \r
84         Atr_Expr AS_Acceso_Objeto(Atr_Expr atr_raiz, AST raiz, AST atrib){\r
85                 Atr_Expr result = new Atr_Expr();\r
86                 AST tipo, tipo_raiz, aux;\r
87                 if(atr_raiz == null || raiz == null || atrib ==null) return null;\r
88                 //comprobar que el tipo de la raiz sea clase\r
89                 tipo_raiz = atr_raiz.getTipo();\r
90                 if(tipo_raiz.getType() != CLASE){\r
91                         System.out.println("ERROR CT: "+raiz.getFirstChild().getText()+" no es una clase");\r
92                         return null;\r
93                 }\r
94                 //si la raiz es una clase instanciable\r
95                 if(raiz.getFirstChild().getNextSibling().getType() == CLASE){\r
96                         if(tipo_raiz.getFirstChild().getNextSibling().getType() != NO_INST){\r
97                                 System.out.println("ERROR CT: "+raiz.getFirstChild().getText()+" es una clase instanciable");\r
98                                 return null;\r
99                         }\r
100                 }\r
101                 //si la raiz es un objeto\r
102                 else{\r
103                         if(tipo_raiz.getFirstChild().getNextSibling().getType() != INST){\r
104                                 System.out.println("ERROR CT: "+raiz.getFirstChild().getText()+" es un objeto de clase no instanciable");\r
105                                 return null;\r
106                         }\r
107                 }\r
108                 //comprobar que "atrib" sea un atributo o metodo de la clase y ademas sea visible\r
109                 aux = tipo_raiz.getFirstChild().getNextSibling().getNextSibling();\r
110                 while(aux!= null){\r
111                         if(aux.getType() == METODO){\r
112                                 if(aux.getFirstChild().getFirstChild().equals(atrib))\r
113                                         break;\r
114                         }else{ //atributo\r
115                                 if(aux.getFirstChild().equals(atrib))\r
116                                         break;\r
117                         }\r
118                         aux = aux.getNextSibling();\r
119                 }\r
120                 if(aux == null){\r
121                         System.out.println("ERROR CT: el atributo "+atrib.getText()+" no pertenece a la clase "+raiz.getFirstChild().getText());\r
122                         return null;\r
123                 }\r
124                 if(aux.getFirstChild().getNextSibling().getNextSibling().getType() != VISIBLE){\r
125                         System.out.println("ERROR CT: el atributo "+atrib.getText()+" no es visible");\r
126                         return null;\r
127                 }\r
128                 \r
129                 //tipo de la expresion\r
130                 if(aux.getType() == METODO){\r
131                         tipo = aux.getFirstChild();\r
132                         result.setLVal(false);\r
133                         result.setRVal(false);\r
134                 }else{ //atributo\r
135                         tipo = aux.getFirstChild().getNextSibling();\r
136                         result.setLVal(true);\r
137                         result.setRVal(true);\r
138                 }\r
139                 result.setTipo(tipo);\r
140                 return result;\r
141         \r
142         }\r
143         \r
144         //hay que pasarle la raiz para saber el nombre de la raiz cuando no es un metodo\r
145         Atr_Expr AS_Llamada(Atr_Expr atr_raiz, LinkedList expresiones){\r
146                 ListIterator it = expresiones.listIterator();\r
147                 Atr_Expr result = new Atr_Expr();\r
148                 AST pars, par_f, tipo;\r
149                 Atr_Expr par_r;\r
150                 \r
151                 //comprobar que atr_raiz no se a null\r
152                 if(atr_raiz == null || expresiones == null){\r
153                         return null;\r
154                 }\r
155                 //comprobar que la raiz sea de tipo prototipo\r
156                 if(atr_raiz.getTipo().getType() != PROTOTIPO){\r
157                         System.out.println("ERROR CT: "+atr_raiz.getTipo().getText()+" no es un metodo.");\r
158                         return null;\r
159                 }\r
160                 //comprobar que los parametros reales coinciden con los formales\r
161                 pars = atr_raiz.getTipo().getFirstChild().getNextSibling();\r
162                 par_f = pars.getFirstChild();\r
163                 while (it.hasNext() && (par_f != null)){\r
164                         par_r = (Atr_Expr)it.next();\r
165                         if(! par_f.getFirstChild().getNextSibling().equalsTree(par_r.getTipo())){\r
166                                 System.out.println("ERROR CT: El numero de parametros en el metodo \""+atr_raiz.getTipo().getFirstChild().getText()+"\" es incorrecto.");\r
167                                 return null;\r
168                         }\r
169                         par_f = par_f.getNextSibling();\r
170                 }\r
171                 if(it.hasNext() && (par_f == null)){\r
172                         System.out.println("ERROR CT: El numero de parametros en el metodo \""+atr_raiz.getTipo().getFirstChild().getText()+"\" es incorrecto.");\r
173                         return null;\r
174                 }\r
175                 if(!it.hasNext() && (par_f != null)){\r
176                         System.out.println("ERROR CT: El numero de parametros en el metodo \""+atr_raiz.getTipo().getFirstChild().getText()+"\" es incorrecto.");\r
177                         return null;\r
178                 }\r
179                 //el tipo de la expresion es el rango del metodo\r
180                 tipo = atr_raiz.getTipo().getFirstChild().getNextSibling().getNextSibling().getFirstChild();\r
181                 result.setLVal(false);\r
182                 result.setRVal(true);\r
183                 result.setTipo(tipo);\r
184                 return result;\r
185         }\r
186         \r
187         Atr_Expr AS_Acceso_Tabla(Atr_Expr atr_raiz, LinkedList expresiones){\r
188                 if(atr_raiz == null || expresiones == null) return null;\r
189                 ListIterator it = expresiones.listIterator();\r
190                 Atr_Expr result = new Atr_Expr();\r
191                 Atr_Expr aux;\r
192                 AST tipo;\r
193                 int tam = 0;\r
194                 //comprobar que el tipo de la raizes una formacion\r
195                 //TODO\r
196                 if(atr_raiz.getTipo().getType() != FORMACION){\r
197                         System.out.println("ERROR CT: intentando acceder a \""+atr_raiz.getTipo().getText()+"\" como formacion");\r
198                         return null;\r
199                 }\r
200                 //comprobar que el numero de expresiones coincida con el numero  de dimensiones\r
201                 while(it.hasNext()){\r
202                         tam++;\r
203                         aux = (Atr_Expr) it.next();\r
204                         if(aux == null) return null;\r
205                         if(aux.getTipo().getType() != ENTERO){\r
206                                 System.out.println("ERROR CT: no coinciden el numero de expresiones en el acceso a formacion");\r
207                                 return null;\r
208                         }\r
209                 }\r
210                 if(tam != atr_raiz.getTipo().getFirstChild().getNumberOfChildren()){\r
211                         System.out.println("ERROR CT: no coinciden el numero de expresiones en el acceso a formacion");\r
212                         return null;\r
213                 }\r
214                 tipo = atr_raiz.getTipo().getFirstChild().getNextSibling();\r
215                 result.setTipo(tipo);\r
216                 result.setLVal(atr_raiz.getLVal());\r
217                 result.setRVal(atr_raiz.getRVal());\r
218                 return result;\r
219         }\r
220         \r
221         \r
222         \r
223         //AS DE EXPRESIONES\r
224   \r
225   //Expresiones binarias aritmeticas\r
226   Atr_Expr AS_Exp_Bin_Arit(Atr_Expr e1, Atr_Expr e2){\r
227         Atr_Expr result = new Atr_Expr();\r
228         String men="";\r
229         if(e1 == null || e2 == null) return null;\r
230         \r
231         //Comprobamos que e1 y e2 sean consultables\r
232         if(!e1.getLVal() || !e2.getRVal()){\r
233                 if (!e2.getRVal()) men="ERROR LR: la expresion no puede aparecer a la derecha de una expresion binaria" ;\r
234                 if (!e1.getLVal()) men="ERROR LR: la expresion no puede aparecer a la izquierda de una expresion binaria" ;\r
235                 System.out.println(men);\r
236                 return null;\r
237         }\r
238         \r
239         //Comprobamos que e1 y e2 sean numericas y compatibles\r
240         if((e1.getTipo().getType()!=ENTERO) && (e1.getTipo().getType()!=REAL) ||\r
241         (e2.getTipo().getType()!=ENTERO) && (e2.getTipo().getType()!=REAL)){\r
242                 System.out.println("ERROR CT: no son expresiones numericas ("+e1.getTipo().getText()+" y "+e2.getTipo().getText()+")");\r
243                 return null;\r
244         }\r
245         if(!e1.getTipo().equals(e2.getTipo())){\r
246                 System.out.println("ERROR CT: Los tipos no son compatibles ("+e1.getTipo().getText()+" y "+e2.getTipo().getText()+")");\r
247                 return null;\r
248         }\r
249         \r
250         //Calculamos el tipo\r
251         result.setTipo(e1.getTipo());\r
252         result.setLVal(false);\r
253         result.setRVal(true);\r
254         \r
255         return result;\r
256   }\r
257   \r
258   \r
259   //Expresiones binarias logicas\r
260   Atr_Expr AS_Exp_Bin_Log(Atr_Expr e1, Atr_Expr e2){\r
261         Atr_Expr result = new Atr_Expr();\r
262         String men = "";\r
263         \r
264         if(e1 == null || e2 == null) return null;\r
265         //Comprobar que las expresiones son consultables\r
266         if(!e1.getLVal() || !e2.getRVal()){\r
267                 if (!e2.getRVal()) men ="ERROR LR: la expresion no puede aparecer a la derecha de la expresion" ;\r
268                 if (!e1.getLVal()) men ="ERROR LR: la expresion "+e1.getTipo().getFirstChild().getText()+" no puede aparecer a la izquierda de la expresion" ;\r
269                 System.out.println(men);\r
270                 return null;\r
271         }\r
272         \r
273         //Comprobamos que sean de tipo logico\r
274         if((e1.getTipo().getType()!=LOGICO) || (e2.getTipo().getType()!=LOGICO)){\r
275                 if (e1.getTipo().getType()!=LOGICO)\r
276                         men = "ERROR CT: la expresion "+e1.getTipo().getFirstChild().getText()+"no es de tipo logico";\r
277                 if (e2.getTipo().getType()!=LOGICO)\r
278                         men = "ERROR CT: la expresion "+e2.getTipo().getFirstChild().getText()+"no es de tipo logico";\r
279                 System.out.println(men);\r
280                 return null;\r
281         }\r
282         \r
283         //Calculamos el tipo\r
284         result.setTipo(e1.getTipo());\r
285         result.setLVal(false);\r
286         result.setRVal(true);\r
287         \r
288         return result;\r
289   }\r
290   \r
291   //Expresiones binarias relacionales\r
292   Atr_Expr AS_Exp_Bin_Rel(Atr_Expr e1, Atr_Expr e2, AST operador){\r
293         Atr_Expr result = new Atr_Expr();\r
294         AST tipo;\r
295         String men = "";\r
296         \r
297         if(e1 == null || e2 == null || operador == null) return null;\r
298         //Comprobamos que las expresiones son consultables\r
299         if(!e1.getLVal() || !e2.getRVal()){\r
300                 if (!e2.getRVal()) men ="ERROR LR: la expresion no se puede consultar en la expresion binaria" ;\r
301                 if (!e1.getLVal()) men ="ERROR LR: la expresion "+e1.getTipo().getFirstChild().getText()+" no puede aparecer a la izquierda en la expresion";\r
302                 System.out.println(men);\r
303                 return null;\r
304         }\r
305         \r
306         //No dejamos que se utilicen formaciones y comprobamos la compatibilidad de las expresiones\r
307         if(e1.getTipo().getType()==FORMACION){\r
308                 System.out.println("ERROR CT: no puede tener formaciones en expresiones relacionales");\r
309                 return null;\r
310         }\r
311         men = "ERROR CT: Los tipos no son compatibles ("+e1.getTipo().getText()+" y "+e2.getTipo().getText()+")";\r
312         if(!e1.getTipo().equals(e2.getTipo())){\r
313                 System.out.println(men);\r
314                 return null;\r
315         }\r
316 \r
317         if((e1.getTipo().getType() == CLASE) && (!e1.getTipo().getFirstChild().equals(e2.getTipo().getFirstChild()))){ //Comparamos las clases por nombre\r
318                 System.out.println(men);\r
319                 return null;\r
320         }\r
321         \r
322         //Miramos los grupos de operadores\r
323         if((operador.getType()!=IGUAL && operador.getType()!=DISTINTO) && (e1.getTipo().getType()==CLASE || e1.getTipo().getType()==LOGICO)){\r
324                 System.out.println("ERROR CT: el operador \""+operador.getText()+"\" no esta permitido para los tipos usados ("+e1.getTipo().getText()+" y "+e2.getTipo().getText()+")");\r
325                 return null;\r
326         }\r
327         \r
328         //Establecemos el tipo\r
329         tipo = #(#[LOGICO,"logico"]);\r
330         result.setTipo(tipo);\r
331         result.setLVal(false);\r
332         result.setRVal(true);\r
333         \r
334         return result;\r
335   }\r
336   \r
337   //Expresiones unarias aritmeticas == MENOS UNARIO\r
338   Atr_Expr AS_Exp_Una_Arit(Atr_Expr e){\r
339         Atr_Expr result = new Atr_Expr();\r
340         String men="";\r
341         \r
342         if(e == null) return null;\r
343         //e tiene que ser consultable\r
344         if(!e.getRVal()){\r
345                 men ="ERROR LR: la expresion no es consultable" ;\r
346                 System.out.println(men);\r
347                 return null;\r
348         }\r
349         \r
350         //comprobar que e es de tipo numerico\r
351         if( e.getTipo().getType()!=ENTERO && e.getTipo().getType()!=REAL){\r
352                 System.out.println("ERROR CT: el menos unario solo puede ser utilizado en expresiones numericas");\r
353                 return null;\r
354         }\r
355         \r
356         //Establecemos el tipo\r
357         result.setTipo(e.getTipo());\r
358         result.setLVal(false);\r
359         result.setRVal(true);\r
360         \r
361         return result;\r
362   }\r
363   \r
364   //Expresiones unarias logicas == NEGACION\r
365   //Identica a la anterior\r
366   Atr_Expr AS_Exp_Una_Log(Atr_Expr e){\r
367         Atr_Expr result = new Atr_Expr();\r
368         \r
369         if(e == null) return null;\r
370         //e tiene que ser consultable\r
371         if(!e.getRVal()){\r
372                 System.out.println("ERROR LR: la expresion no es consultable" );\r
373                 return null;\r
374         }\r
375         \r
376         //comprobar que e es de tipo numerico\r
377         if( e.getTipo().getType()!=LOGICO){\r
378                 System.out.println("ERROR CT: la negacion solo se puede utilizar con expresiones logicas");\r
379                 return null;\r
380         }\r
381         \r
382         //Establecemos el tipo\r
383         result.setTipo(e.getTipo());\r
384         result.setLVal(false);\r
385         result.setRVal(true);\r
386         \r
387         return result;\r
388   }\r
389   \r
390   //Instrucciones\r
391   //Asignacion\r
392   void AS_Asignacion(Atr_Expr e1, Atr_Expr e2, AST e3, AST e4){\r
393         //comprobar si alguno es null\r
394         String men = "";\r
395         if(e1==null || e2 == null) return;\r
396                 \r
397         //Comprobamos la consultabilidad de las expresiones\r
398         if(!e1.getLVal() || !e2.getRVal()){\r
399                 if (!e2.getRVal())\r
400                         men ="ERROR LR: la expresion "+e4.getFirstChild().getText()+" no puede aparecer a la derecha de una asignacion." ;\r
401                 if (!e1.getLVal()) men ="ERROR LR: el "+e3.getFirstChild().getNextSibling().getText()+" "+e3.getFirstChild().getText()+" no puede aparecer a la izquierda de una asignacion." ;\r
402                 System.out.println(men);\r
403                 return;\r
404         }\r
405         \r
406         //No dejamos asignar formaciones y comprobamos la compatibilidad de tipos\r
407         if(e1.getTipo().getType()==FORMACION){\r
408                 System.out.println("ERROR CT: no dejamos asignar formaciones");\r
409         }\r
410         men = "ERROR CT: Los tipos no son compatibles ("+e1.getTipo().getText()+" y "+e2.getTipo().getText()+")";\r
411         if(!e1.getTipo().equals(e2.getTipo())){\r
412                 System.out.println(men);\r
413         }\r
414         if((e1.getTipo().getType() == CLASE) && (!e1.getTipo().getFirstChild().equals(e2.getTipo().getFirstChild()))){ //Comparamos las clases por nombre\r
415                 System.out.println(men);\r
416         }\r
417   }\r
418   \r
419   //Condiciones\r
420   void AS_Condicional(Atr_Expr e){\r
421         String men = "";\r
422         if (e == null) return;\r
423         if(!e.getRVal()){\r
424                 men ="ERROR LR: la expresion no es consultable" ;\r
425                 System.out.println(men);\r
426                 return;\r
427         }\r
428         \r
429         //Comprobamos que es de tipo logico\r
430         if(e.getTipo().getType()!=LOGICO){\r
431                 System.out.println("ERROR CT: no es un tipo logico");\r
432         }\r
433   }\r
434   \r
435   //Instruccion de devolucion\r
436   int AS_Devolucion(AST tipo_dev, Atr_Expr e, int cont){\r
437         String men = "";\r
438 //  String men = "ERROR CT: Los tipos no son compatibles (entero y real)"\r
439         if(tipo_dev == null || e == null) return cont+1;\r
440         //Comprobamos que el metodo sea funcional\r
441 \r
442         if(cont == -1){\r
443                 System.out.println("ERROR CT: el metodo no es funcional");\r
444                 return -1;\r
445         }\r
446 \r
447         //Comprobar que la expresion e es consultable\r
448         if(!e.getRVal()){\r
449                 System.out.println("ERROR CT: la expresion no es consultable, no se puede devolver");\r
450         }\r
451         \r
452         men = "ERROR CT: Los tipos no son compatibles ("+e.getTipo().getText()+" y "+tipo_dev.getText()+")";\r
453         //Comprobamos que el tipo de la expresion es compatible con el tipo que se devuelve\r
454         if(!e.getTipo().equals(tipo_dev)){\r
455                 System.out.println(men);\r
456         }\r
457         if(tipo_dev.getType()==CLASE && (!tipo_dev.getFirstChild().equals(e.getTipo().getFirstChild()))){\r
458                 System.out.println(men);\r
459         }\r
460         \r
461         if(tipo_dev.getType()==FORMACION && (!tipo_dev.equals(e.getTipo()))){\r
462                 System.out.println(men);\r
463         }\r
464         \r
465         return cont + 1;\r
466   }\r
467   \r
468   \r
469   Atr_Expr AS_Crear(Atr_Expr as, AST clase){\r
470                 if (as == null || clase == null){\r
471                         System.out.println("ERROR CT: no se puede crear");\r
472                          return null;\r
473                 }\r
474                 //comprobar que el tipo de la variable es el mismo que el del interior de crear\r
475                 Atr_Expr result = new Atr_Expr();\r
476                 AST tipo = as.getTipo();\r
477                 if(tipo.getType() != CLASE){\r
478                         System.out.println("ERROR CT: no es una clase");\r
479                         return null;\r
480                 }\r
481                 if(!(tipo.getFirstChild().getNextSibling().getType() == INST)){\r
482                         System.out.println("ERROR CT: la clase no es instanciable");\r
483                         return null;\r
484                 }\r
485                 AST tipo_var = tipo.getFirstChild();\r
486                 AST interior = clase;\r
487                 if(!tipo_var.getText().equals(interior.getText())){\r
488                         if(interior.getType() == ACCESO_SIMPLE)\r
489                                 System.out.println("ERROR CT: Los tipos no son compatibles ("+tipo_var.getText()+" y "+interior.getFirstChild().getText()+")");\r
490                         else\r
491                                 System.out.println("ERROR CT: Los tipos no son compatibles ("+tipo_var.getText()+" y "+interior.getText()+")");\r
492                         return null;\r
493                 }\r
494 \r
495                 result.setLVal(false);\r
496                 result.setRVal(false);\r
497                 //el tipo es el de la variable\r
498                 result.setTipo(tipo);\r
499                 \r
500                 return result;\r
501         }       \r
502         \r
503         //AS Escribir\r
504         void AS_Escribir(Atr_Expr e, AST exp){\r
505                 if (e == null){\r
506                         if(exp.getType() == ACCESO_SIMPLE)\r
507                                 System.out.println("ERROR CT: no se puede escribir "+ exp.getFirstChild().getText());\r
508                         else\r
509                                 System.out.println("ERROR CT: no se puede escribir "+ exp.getText());\r
510                         return;\r
511                 }\r
512                 //Comprobamos que la expresion se pueda consultar\r
513                 if(!e.getRVal()){\r
514                         System.out.println("ERROR CT: la expresion no es consultable, no se puede escribir");\r
515                 }\r
516         }\r
517 \r
518   \r
519   //AS Entero A Real\r
520   Atr_Expr AS_Entero_A_Real(Atr_Expr e1){\r
521         Atr_Expr result = new Atr_Expr();\r
522         if (e1 == null) return null;\r
523         AST tipo = e1.getTipo();\r
524         if(tipo.getType() != ENTERO){\r
525                 System.out.println("ERROR CT: El tipo del parametro del operador enteroareal es incorrecto.");\r
526                 return null;\r
527           }\r
528         result.setTipo(#(#[REAL,"real"]));\r
529         result.setLVal(false);\r
530         result.setRVal(true);\r
531         return result;\r
532   }\r
533   Atr_Expr AS_Real_A_Entero(Atr_Expr e1){\r
534         Atr_Expr result = new Atr_Expr();\r
535         \r
536         if (e1 == null) return null;\r
537         AST tipo = e1.getTipo();\r
538         if(tipo.getType() != REAL){\r
539                 System.out.println("ERROR CT: El tipo del parametro del operador realaentero es incorrecto.");\r
540                 return null;\r
541         }\r
542         result.setTipo(#(#[ENTERO,"entero"]));\r
543         result.setLVal(false);\r
544         result.setRVal(true);\r
545         return result;\r
546   }\r
547   \r
548   \r
549 }\r
550 \r
551 // ========= FIN DE DECLARACION DE FUNCIONES\r
552 \r
553 declaracion_modulo: #(MODULO nombre_modulo definicion_modulo);\r
554 \r
555 nombre_modulo : IDENT ;\r
556 \r
557 definicion_modulo:\r
558         (importacion)?\r
559         (exportacion)+\r
560         (implementacion)?\r
561 ;\r
562 \r
563 importacion : #(IMPORTACION lista_ident);\r
564 lista_ident: (IDENT)+;\r
565 \r
566 exportacion : #(EXPORTACION lista_declaraciones_clases);\r
567 \r
568 implementacion : #(IMPLEMENTACION lista_declaraciones_clases);\r
569 \r
570 \r
571 lista_declaraciones_clases: (declaracion_clase)*\r
572 ;\r
573 \r
574 declaracion_clase : #(CLASE nombre_clase cualificador_clase definicion_clase)\r
575 ;\r
576 \r
577 cualificador_clase : INST | NO_INST ;\r
578 \r
579 nombre_clase : IDENT ;\r
580 \r
581 definicion_clase : declaraciones_elementos_clase\r
582 ;\r
583 \r
584 declaraciones_elementos_clase : (declaracion_elemento_clase)* ;\r
585 \r
586 declaracion_elemento_clase :\r
587 #(METODO declaracion_metodo cualificador_elemento_clase)\r
588 | #(ATRIBUTO IDENT tipo cualificador_elemento_clase)\r
589 ;\r
590 \r
591 cualificador_elemento_clase: OCULTO | VISIBLE ;\r
592 \r
593 declaracion_metodo {AST tipodev;} : tipodev =prototipo_metodo definicion_metodo[tipodev]\r
594 { if (cont_dev == 0){\r
595         System.out.println("ERROR: Metodo funcional que no devuelve nada");\r
596         System.exit(-1);\r
597   }\r
598 } ;\r
599 \r
600 prototipo_metodo returns [AST tipodev=null]: #(PROTOTIPO IDENT #(PARAMETROS\r
601 declaracion_parametros)\r
602 #(RESULTADO\r
603 ( t: tipo {cont_dev = 0; // inicializa el contador de instrucciones DEV\r
604 tipodev = t; }\r
605 | v: VACIO {cont_dev = -1; // marca a -1 para indicar que es un procedimiento\r
606 tipodev = v; }\r
607 )))\r
608 ;\r
609 \r
610 declaracion_parametros : (declaracion_parametro)* ;\r
611 \r
612 declaracion_parametro : #(PARAMETRO IDENT tipo) ;\r
613 \r
614 definicion_metodo [AST tipodev]: #(DEFINICION #(VARIABLES_LOCALES declaracion_variables_locales) #(INSTRUCCIONES instrucciones[tipodev]))\r
615 ;\r
616 \r
617 declaracion_variables_locales : (declaracion_variable_local)* ;\r
618 \r
619 declaracion_variable_local : #(VARIABLE_LOCAL IDENT tipo) ;\r
620 \r
621 declaracion_error : ERROR;\r
622 \r
623 instrucciones [AST tipodev] : (instruccion[tipodev])* ;\r
624 \r
625 instruccion [AST tipodev] : #(INSTRUCCION ( instruccion_simple[tipodev] | instruccion_compuesta[tipodev]))\r
626 ;\r
627 \r
628 instruccion_simple [AST tipodev] : crear\r
629 | llamada_metodo\r
630 | escribir\r
631 | asignacion\r
632 | retorno [tipodev]\r
633 ;\r
634 \r
635 crear{Atr_Expr e1;} : #(CREAR e1=expresion e2:expresion)\r
636 {AS_Crear(e1,#e2);}\r
637 ;\r
638 \r
639 escribir{Atr_Expr e1;}: #(ESCRIBIR e1=e:expresion)\r
640 {AS_Escribir(e1, #e);};\r
641 \r
642 instruccion_compuesta [AST tipodev] :\r
643 condicion [tipodev]\r
644 | iteracion [tipodev]\r
645 ;\r
646 \r
647 asignacion {Atr_Expr e1, e2;}: #(ASIGNACION e1=e3:expresion e2=e4:expresion )\r
648 {       AS_Asignacion(e1,e2,#e3,#e4);\r
649 };\r
650 \r
651 retorno [AST tipodev] {Atr_Expr e;}: #(DEV e=expresion)\r
652 {/*AS_Devolucion(tipodev, e);\r
653 cont_dev++;*/\r
654 cont_dev=AS_Devolucion(tipodev,e,cont_dev);\r
655 }\r
656 ;\r
657 \r
658 llamada_metodo {Atr_Expr a, res; LinkedList l;}:\r
659 #(LLAMADA a=acceso #(EXPRESIONES l=lista_expresiones))\r
660 {res=AS_Llamada(a,l);\r
661  if (res != null && res.getTipo().getType() != VACIO){\r
662         System.out.println("ERROR: Llamada a funcion sin asignar valor devuelto.");\r
663         System.exit(1); \r
664  } \r
665\r
666 ;\r
667 \r
668 lista_expresiones returns [LinkedList l= new LinkedList()] {Atr_Expr e;}:\r
669 (e=expresion {l.add(e);})* ;\r
670 \r
671 condicion [AST tipodev] {Atr_Expr e;} : #(SI e=expresion #(INSTRUCCIONES instrucciones[tipodev])\r
672 (#(INSTRUCCIONES instrucciones[tipodev]))?)\r
673 {AS_Condicional(e);\r
674 }\r
675 ;\r
676 \r
677 iteracion [AST tipodev] {Atr_Expr e;} : #(MIENTRAS e=expresion #(INSTRUCCIONES\r
678 instrucciones[tipodev])) {AS_Condicional(e);\r
679 }\r
680 ;\r
681 \r
682 expresion returns [Atr_Expr res=null] {Atr_Expr e1,e2; LinkedList l;}:\r
683 #(O e1=expresion e2=expresion) {res=AS_Exp_Bin_Log( e1, e2);\r
684 }\r
685 | #(Y e1=expresion e2=expresion) {res=AS_Exp_Bin_Log( e1, e2);\r
686 }\r
687 | #(NO e1=expresion) {res=AS_Exp_Una_Log( e1);\r
688 }\r
689 | #(op1:MAYOR e1=expresion e2=expresion) {res=AS_Exp_Bin_Rel( e1, e2, op1);\r
690 }\r
691 | #(op2:MAYOR_IGUAL e1=expresion e2=expresion) {res=AS_Exp_Bin_Rel( e1, e2, op2);\r
692 }\r
693 | #(op3:MENOR e1=expresion e2=expresion) {res=AS_Exp_Bin_Rel( e1, e2, op3);\r
694 }\r
695 | #(op4:MENOR_IGUAL e1=expresion e2=expresion) {res=AS_Exp_Bin_Rel( e1, e2, op4);\r
696 }\r
697 | #(op5:IGUAL e1=expresion e2=expresion) {res=AS_Exp_Bin_Rel( e1, e2, op5);\r
698 }\r
699 | #(op6:DISTINTO e1=expresion e2=expresion) {res=AS_Exp_Bin_Rel( e1, e2, op6);\r
700 }\r
701 | #(MAS e1=expresion e2=expresion) {res=AS_Exp_Bin_Arit( e1, e2);\r
702 }\r
703 | #(MENOS e1=expresion e2=expresion) {res=AS_Exp_Bin_Arit( e1, e2);\r
704 }\r
705 | #(MENOSUNARIO e1=expresion) {res=AS_Exp_Una_Arit( e1);\r
706 }\r
707 | #(POR e1=expresion e2=expresion) {res=AS_Exp_Bin_Arit( e1, e2);\r
708 }\r
709 | #(DIVISION e1=expresion e2=expresion) {res=AS_Exp_Bin_Arit( e1, e2);\r
710 }\r
711 | #(LLAMADA e1=acceso #(EXPRESIONES l=lista_expresiones))\r
712 {res=AS_Llamada( e1, l);\r
713 if (res != null){\r
714         if (res.getTipo().getType() == VACIO){\r
715                 System.out.println("ERROR: No se puede recoger el valor devuelto por un procedimiento (no devuelve nada).");\r
716                 System.exit(1);\r
717         }\r
718 }\r
719 }\r
720 | #(ACCESO_TABLA e1=acceso #(EXPRESIONES l=lista_expresiones_nv))\r
721 {res=AS_Acceso_Tabla( e1, l);\r
722 }\r
723 | e1=acceso {res=e1;}\r
724 \r
725 | i:LIT_ENTERO {res=AS_Literal( i);}\r
726 | j:LIT_REAL {res=AS_Literal( j);}\r
727 | k:LIT_CAR {res=AS_Literal( k);}\r
728 | m:CIERTO {res=AS_Literal( m);}\r
729 | n:FALSO {res=AS_Literal( n);}\r
730 | #(ENTERO_A_REAL e1=expresion) {res = AS_Entero_A_Real(e1);}\r
731 | #(REAL_A_ENTERO e1=expresion) {res = AS_Real_A_Entero(e1);}\r
732 | ERROR\r
733 ;\r
734 \r
735 acceso returns [Atr_Expr res=null] {Atr_Expr e;}:\r
736 e=acceso_simple {res=e;}\r
737 | #(ACCESO_OBJETO e=r:acceso_simple a:IDENT) {\r
738         res=AS_Acceso_Objeto( e, r, a);\r
739 }\r
740 ;\r
741 \r
742 acceso_simple returns [Atr_Expr res=null]:\r
743 #(ACCESO_SIMPLE IDENT d:declaracion_acceso) {res=AS_Acceso_Simple(#d);}\r
744 ;\r
745 \r
746 declaracion_acceso: declaracion_modulo\r
747 | declaracion_clase1\r
748 | declaracion_elemento_clase1\r
749 | declaracion_parametro1\r
750 | declaracion_variable_local1\r
751 | declaracion_error\r
752 ;\r
753 \r
754 lista_expresiones_nv returns [LinkedList l= new LinkedList()] {Atr_Expr e;}:\r
755 (e=expresion {l.add(e);})+ ;\r
756 \r
757 tipo :\r
758 tipo_predefinido_simple\r
759 | tipo_predefinido_compuesto\r
760 | declaracion_clase1\r
761 | declaracion_error\r
762 ;\r
763 \r
764 tipo_predefinido_simple :\r
765 ENTERO\r
766 | REAL\r
767 | LOGICO\r
768 | CARACTER\r
769 ;\r
770 \r
771 tipo_predefinido_compuesto : formacion\r
772 ;\r
773 \r
774 formacion {AST t=null;}: #(FORMACION #(LISTA_ENTEROS lista_enteros)(tipo_predefinido_simple | declaracion_clase1))\r
775 ;\r
776 \r
777 lista_enteros : (LIT_ENTERO)+ ;\r
778 \r
779 declaracion_clase1 : #(CLASE n:nombre_clase1 cualificador_clase1 definicion_clase1)\r
780 ;\r
781 cualificador_clase1 : INST | NO_INST;\r
782 nombre_clase1 : IDENT \r
783 ;\r
784 definicion_clase1 : declaraciones_elementos_clase1\r
785 ;\r
786 declaraciones_elementos_clase1 : (declaracion_elemento_clase1)* ;\r
787 declaracion_elemento_clase1 :\r
788 #(METODO declaracion_metodo1 cualificador_elemento_clase1)\r
789 | #(ATRIBUTO IDENT tipo1 cualificador_elemento_clase1)\r
790 ;\r
791 cualificador_elemento_clase1: OCULTO | VISIBLE ;\r
792 declaracion_metodo1 : prototipo_metodo1 definicion_metodo1 ;\r
793 prototipo_metodo1 : #(PROTOTIPO IDENT #(PARAMETROS declaracion_parametros1)\r
794 #(RESULTADO (tipo1 | VACIO)))\r
795 ;\r
796 declaracion_parametros1 : (declaracion_parametro1)* ;\r
797 declaracion_parametro1 : #(PARAMETRO IDENT tipo1) ;\r
798 definicion_metodo1 : #(DEFINICION #(VARIABLES_LOCALES declaracion_variables_locales1)\r
799 #(INSTRUCCIONES instrucciones1))\r
800 ;\r
801 declaracion_variables_locales1 : (declaracion_variable_local1)* ;\r
802 declaracion_variable_local1 : #(VARIABLE_LOCAL IDENT tipo1);\r
803 declaracion_error1 : ERROR;\r
804 instrucciones1 : (instruccion1)* ;\r
805 instruccion1 : #(INSTRUCCION (instruccion_simple1 | instruccion_compuesta1))\r
806 ;\r
807 instruccion_simple1 : crear1\r
808 | llamada_metodo1\r
809 | escribir1\r
810 | asignacion1\r
811 | retorno1\r
812 ;\r
813 \r
814 crear1: #(CREAR expresion1 expresion1);\r
815 escribir1: #(ESCRIBIR expresion1);\r
816 \r
817 instruccion_compuesta1 :\r
818 condicion1\r
819 | iteracion1\r
820 ;\r
821 asignacion1 : #(ASIGNACION expresion1 expresion1 ) ;\r
822 retorno1 : #(DEV expresion1) ;\r
823 llamada_metodo1 : #(LLAMADA acceso1 #(EXPRESIONES lista_expresiones1)) ;\r
824 lista_expresiones1 : (expresion1)* ;\r
825 condicion1 : #(SI expresion1 #(INSTRUCCIONES instrucciones1) (#(INSTRUCCIONES\r
826 instrucciones1))?)\r
827 ;\r
828 iteracion1 : #(MIENTRAS expresion1 #(INSTRUCCIONES instrucciones1))\r
829 ;\r
830 expresion1: #(O expresion1 expresion1)\r
831 | #(Y expresion1 expresion1)\r
832 | #(NO expresion1)\r
833 | #(MAYOR expresion1 expresion1)\r
834 | #(MAYOR_IGUAL expresion1 expresion1)\r
835 | #(MENOR expresion1 expresion1)\r
836 | #(MENOR_IGUAL expresion1 expresion1)\r
837 | #(IGUAL expresion1 expresion1)\r
838 | #(DISTINTO expresion1 expresion1)\r
839 | #(MAS expresion1 expresion1)\r
840 | #(MENOS expresion1 expresion1)\r
841 | #(MENOSUNARIO expresion1)\r
842 | #(POR expresion1 expresion1)\r
843 | #(DIVISION expresion1 expresion1)\r
844 | #(LLAMADA acceso1 #(EXPRESIONES lista_expresiones1))\r
845 | #(ACCESO_TABLA acceso1 #(EXPRESIONES lista_expresiones_nv1))\r
846 | acceso1\r
847 | LIT_ENTERO\r
848 | LIT_REAL\r
849 | LIT_CAR\r
850 | CIERTO\r
851 | FALSO\r
852 | NULO\r
853 | #(ENTERO_A_REAL expresion1)\r
854 | #(REAL_A_ENTERO expresion1)\r
855 | ERROR\r
856 ;\r
857 acceso1: #(ACCESO_SIMPLE IDENT declaracion_acceso1)\r
858 | #(ACCESO_OBJETO #(ACCESO_SIMPLE IDENT declaracion_acceso1) IDENT)\r
859 ;\r
860 declaracion_acceso1:\r
861 |declaracion_clase1\r
862 |declaracion_elemento_clase1\r
863 |declaracion_parametro1\r
864 |declaracion_variable_local1\r
865 |declaracion_error1\r
866 ;\r
867 lista_expresiones_nv1 : (expresion1)+ ;\r
868 tipo1 :\r
869 tipo_predefinido_simple1\r
870 | tipo_predefinido_compuesto1\r
871 | declaracion_clase1\r
872 | declaracion_error1\r
873 ;\r
874 tipo_predefinido_simple1 :\r
875 ENTERO\r
876 | REAL\r
877 | LOGICO\r
878 | CARACTER\r
879 ;\r
880 tipo_predefinido_compuesto1 : formacion1\r
881 ;\r
882 formacion1 : #(FORMACION #(LISTA_ENTEROS lista_enteros1)\r
883 (tipo_predefinido_simple1 | declaracion_clase1));\r
884 lista_enteros1 : (LIT_ENTERO)+ \r
885 ;\r