Ahora están resueltos los accesos a objetos....
[PL2.git] / ResNom.g
1 header{
2         import java.util.*; 
3         import antlr.ASTFactory;        
4         import java.util.Hashtable;
5 }
6
7 class ResNom extends TreeParser;
8
9 options{
10         buildAST = true;
11         importVocab=Analex;
12         importVocab=Anasint;
13         
14 }
15
16 {
17         LinkedList<String> leas = new LinkedList<String>();
18         Tabla_Global t;
19         TablaModulos mods;
20         AST importaciones = null;
21         Hashtable<String,String> declaraciones = new Hashtable<String,String>();
22         
23         void resolver_identificadores_tipo(){
24                 Identificador_Tipo elemento;
25                 String nombre;
26                 LinkedList<Identificador_Tipo> i;
27                 i = t.identtiposinresolver.getIdentificadores();
28                 ListIterator<Identificador_Tipo> li = i.listIterator();
29                 while(li.hasNext()){
30                         elemento = (Identificador_Tipo) li.next();
31                         nombre = elemento.getNombre();
32                  
33                         if(t.ambitomodulo.getDeclaracion(nombre) == null &&
34                         mods.Declaracion(nombre, importaciones) == null){
35                                 //identificador de tipo no declarado
36                                 System.out.println("ERROR RN :"+t.ambitomodulo.getNombre()+".mod ("+elemento.getLinea()+"): identificador '" + nombre + "' no declarado");
37                         }
38                 }
39         }
40         
41         AST resolver_acceso_simple(String numero){
42                 int no = Integer.parseInt(numero);
43                 //nombre y ambito contenedor del acceso
44                 Lista_Accesos acsr = t.accesossinresolver;
45                 Acceso acc = t.accesossinresolver.getAcceso(no);
46                 String nom = acc.getNombre();
47                 Ambito amb = acc.getContenedor();
48                 
49                 Simbolo sim;
50                 AST dec = #(#[ERROR, "error"]);
51                 //comprobar si se ha declarado, buscando en la tabla de ambitos y declaraciones
52                 //Hace falta mirar en los modulos, para el crear
53                 if((sim = t.tablaambitos.buscar_simbolo(amb, nom)) == null ){
54                         if (mods.Declaracion(nom, importaciones) != null){
55                                 dec = mods.Declaracion(nom, importaciones);
56                         }
57                         //acceso simple no declarado
58                         else 
59                                 if(!leas.contains(numero)){
60                                         //System.out.println("ERROR RN: acceso simple " + nom + " no declarado");
61                                         System.out.println("ERROR RN :"+t.ambitomodulo.getNombre()+".mod ("+acc.getLinea()+"): acceso simple '" + nom + "' no declarado");
62                                         leas.add(numero);
63                                 }
64                 }
65                 else {
66                         dec = sim.getDeclaracion(); //referencia adelantada
67                 }
68                 
69                 return dec;
70         }
71         AST resolver_acceso_objeto(AST arbol, AST ident){
72                 AST as = arbol.getFirstChild();
73                 
74                 Hashtable<String,String> xx = declaraciones;
75                 String tipo = declaraciones.get(as.getText());
76                 
77                 AST arbol2 = declaracion_tipo(#(#[IDENT, tipo]));
78                 if (arbol2.getType() == ERROR)
79                         arbol2 = mods.Declaracion(tipo, importaciones);
80                 
81                 if (arbol2.getType() == ERROR ){
82                         System.out.println("ERROR RN :"+t.ambitomodulo.getNombre()+".mod ("+((ArbolLineas)ident).getLinea()+"): acceso objeto '" + ident.getText() + "' no declarado");
83                         return #(#[ERROR,"error"]);
84                 }
85                 arbol2 = arbol2.getFirstChild().getNextSibling().getNextSibling();
86                 while(arbol2 != null){
87                         if(arbol2.getType() == ATRIBUTO){
88                                 AST visibilidad = arbol2.getFirstChild().getNextSibling().getNextSibling();
89                                 if(arbol2.getFirstChild().getText().equals(ident.getText())){
90                                         if (visibilidad.getType() != OCULTO){
91                                                 return arbol2;
92                                         }
93                                         else{
94                                                 System.out.println("ERROR RN :"+t.ambitomodulo.getNombre()+".mod ("+((ArbolLineas)ident).getLinea()+"): acceso objeto '" + ident.getText() + "' no es accesible");
95                                                 return #(#[ERROR,"error"]);
96                                         }
97                                 }
98                         }
99                         else if (arbol2.getType() == METODO){
100                                 AST visibilidad = arbol2.getFirstChild().getNextSibling().getNextSibling();
101                                 if(arbol2.getFirstChild().getFirstChild().getText().equals(ident.getText())){
102                                         if (visibilidad.getType() != OCULTO){
103                                                 return arbol2;
104                                         }
105                                         else{
106                                                 System.out.println("ERROR RN :"+t.ambitomodulo.getNombre()+".mod ("+((ArbolLineas)ident).getLinea()+"): acceso objeto '" + ident.getText() + "' no es accesible");
107                                                 return #(#[ERROR,"error"]);
108                                         }
109                                 }
110                         }
111                         arbol2 = arbol2.getNextSibling();
112                 }
113                 System.out.println("ERROR RN :"+t.ambitomodulo.getNombre()+".mod ("+((ArbolLineas)ident).getLinea()+"): acceso objeto '" + ident.getText() + "' no declarado");
114                 return #(#[ERROR,"error"]);
115         }
116         
117         void averiguar_importaciones() {
118                 Ambito a = t.ambitomodulo;
119                 Modulo mx = mods.get(a.getNombre());
120                 importaciones = mx.getImportacion();
121         }
122         
123         //con esta funcion se podrian poner la clases
124         //tipo: i:IDENT {#tipo = declaracion_tipo(#i);}
125         AST declaracion_tipo(AST ident){
126                 AST tipo = #(#[ERROR, "error"]);
127                 Ambito modulo = t.ambitomodulo;
128                 Simbolo s = modulo.getDeclaracion(ident.getText());
129                 if (s != null){
130                         ASTFactory f = new ASTFactory();
131                         tipo = f.dupTree(s.getDeclaracion());
132                 }
133                 return tipo;
134         }
135 }
136
137 declaracion_modulo [Tabla_Global tab, TablaModulos m, Hashtable d]:
138 {t = tab;
139         declaraciones = d;
140         mods = m;
141         averiguar_importaciones();
142         resolver_identificadores_tipo();}
143         #(MODULO nombre_modulo definicion_modulo);
144
145 // =============================== del fichero anasem.g ============================
146
147 nombre_modulo : IDENT ;
148
149 definicion_modulo:
150         (importacion)?
151         (exportacion)+
152         (implementacion)?
153 ;
154
155 importacion : #(IMPORTACION lista_ident);
156 lista_ident: (IDENT)+;
157
158 exportacion : #(EXPORTACION lista_declaraciones_clases);
159
160 implementacion : #(IMPLEMENTACION lista_declaraciones_clases);
161
162 lista_declaraciones_clases: (declaracion_clase)*
163 ;
164
165 declaracion_clase : #(CLASE nombre_clase cualificador_clase definicion_clase)
166 ;
167
168 cualificador_clase : INST | NO_INST ;
169
170 nombre_clase : IDENT ;
171
172 definicion_clase : declaraciones_elementos_clase
173 ;
174
175 declaraciones_elementos_clase : (declaracion_elemento_clase)* ;
176
177 declaracion_elemento_clase :
178 #(METODO declaracion_metodo cualificador_elemento_clase)
179 | #(ATRIBUTO i:IDENT t:tipo cualificador_elemento_clase)
180 ;
181
182 cualificador_elemento_clase: OCULTO | VISIBLE ;
183
184 declaracion_metodo : prototipo_metodo definicion_metodo;
185
186 prototipo_metodo: #(PROTOTIPO IDENT #(PARAMETROS declaracion_parametros)
187 #(RESULTADO (tipo | VACIO)));
188
189 declaracion_parametros : (declaracion_parametro)* ;
190
191 declaracion_parametro : #(PARAMETRO IDENT tipo) ;
192
193 definicion_metodo: #(DEFINICION #(VARIABLES_LOCALES declaracion_variables_locales) #(INSTRUCCIONES instrucciones))
194 ;
195
196 declaracion_variables_locales : (declaracion_variable_local)* ;
197
198 declaracion_variable_local : #(VARIABLE_LOCAL i:IDENT t:tipo) ;
199
200 declaracion_error : ERROR;
201
202 instrucciones : (instruccion)* ;
203
204 instruccion : #(INSTRUCCION ( instruccion_simple | instruccion_compuesta))
205 ;
206
207 instruccion_simple : llamada_metodo
208 | crear
209 | escribir 
210 | asignacion
211 | retorno
212 ;
213
214 instruccion_compuesta  :
215 condicion
216 | iteracion 
217 ;
218
219 crear : #(CREAR expresion expresion);
220 escribir : #(ESCRIBIR expresion);
221
222 asignacion : #(ASIGNACION expresion expresion );
223
224 retorno: #(DEV expresion)
225 ;
226
227 llamada_metodo :
228 #(LLAMADA acceso #(EXPRESIONES lista_expresiones)) 
229 ;
230
231 lista_expresiones: (expresion)* ;
232
233 condicion: #(SI expresion #(INSTRUCCIONES instrucciones)
234 (#(INSTRUCCIONES instrucciones))?)
235 ;
236
237 iteracion : #(MIENTRAS expresion #(INSTRUCCIONES
238 instrucciones));
239
240 expresion:
241 #(O expresion expresion)
242 | #(Y expresion expresion)
243 | #(NO expresion)
244 | #(op1:MAYOR expresion expresion)
245 | #(op2:MAYOR_IGUAL expresion expresion)
246 | #(op3:MENOR expresion expresion)
247 | #(op4:MENOR_IGUAL expresion expresion)
248 | #(op5:IGUAL expresion expresion)
249 | #(op6:DISTINTO expresion expresion)
250 | #(MAS expresion expresion)
251 | #(MENOS expresion expresion)
252 | #(MENOSUNARIO expresion)
253 | #(POR expresion expresion)
254 | #(DIVISION expresion expresion)
255 | #(LLAMADA acceso #(EXPRESIONES lista_expresiones))
256 | #(ACCESO_TABLA acceso #(EXPRESIONES lista_expresiones_nv))
257 | acceso
258 | LIT_ENTERO
259 | LIT_REAL 
260 | LIT_CAR 
261 | CIERTO 
262 | FALSO 
263 | #(ENTERO_A_REAL expresion)
264 | #(REAL_A_ENTERO expresion)
265 | ERROR
266 ;
267
268 acceso : acceso_simple
269 | #(ACCESO_OBJETO as:acceso_simple acceso_objeto[#as])
270 ;
271
272 acceso_objeto [AST arbol] : a:IDENT {#acceso_objeto = resolver_acceso_objeto(arbol, #a);};
273
274 acceso_simple : #(ACCESO_SIMPLE i:IDENT d:declaracion_acceso)
275 ;
276
277 declaracion_acceso: declaracion_modulo[t, mods, declaraciones]
278 | declaracion_clase
279 | declaracion_elemento_clase
280 | declaracion_parametro
281 | declaracion_variable_local
282 | declaracion_error
283 | i:LIT_ENTERO
284 {#declaracion_acceso = resolver_acceso_simple(i.getText());
285 }
286 ;
287
288 lista_expresiones_nv : (expresion)+;
289
290 tipo :
291 tipo_predefinido_simple
292 | tipo_predefinido_compuesto
293 | declaracion_error
294 | i:IDENT {#tipo = declaracion_tipo(#i);}
295 ;
296
297 tipo_predefinido_simple :
298 ENTERO
299 | REAL
300 | LOGICO
301 | CARACTER
302 ;
303
304 tipo_predefinido_compuesto : formacion;
305
306 formacion : #(FORMACION #(LISTA_ENTEROS lista_enteros) tipo);
307
308 lista_enteros : (LIT_ENTERO)+ ;