Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Iteradores List STL

Estas en el tema de Iteradores List STL en el foro de C/C++ en Foros del Web. Hola, soy nuevo usando las listas de STL y en el caso que les presentare no funcionan como yo esperaba. Las estoy usando en un ...
  #1 (permalink)  
Antiguo 23/03/2010, 22:43
 
Fecha de Ingreso: diciembre-2003
Ubicación: San Pedro Sula
Mensajes: 165
Antigüedad: 20 años, 11 meses
Puntos: 0
Iteradores List STL

Hola, soy nuevo usando las listas de STL y en el caso que les presentare no funcionan como yo esperaba.

Las estoy usando en un arbol sintactico de un compilador.
Tengo un objeto block que contiene una lista de sentencias:

class block: public TreeNode {
public:
list<statement*> sentencias;
.
.
.
};

Para interpretar el bloque interpreto cada sentencia de la lista...
El problema lo tengo con las sentencias break, continue y return de mi gramatica.

Al interpretar un break sencillamente hago un break dentro del ciclo para que no se sigan interpretando las demas sentencias, si esta dentro de un bloque que no es ciclo (ejemplo IF) tiene que hacer un break para salirse del bloque del IF, y solo

Código PHP:
void block::inter() 
{
     list<
statement*>::iterator stm sentencias.begin();  // lista de sentencias del bloque
     
list<statement*>::iterator itAnterior// iterador para comparar la sentencia anterior

     
exeBreak 0;  // ocurrio un break, var global
     
conti=0;       // ocurrio un continue
     
retorno=0;     // ocurrio un return
     
     
while ( stm != sentencias.end() )      
     {      
               if (
stm != sentencias.begin()) {
                   
itAnteriorstm;
                   
itAnterior--;         
               }
               
              
// sentenciaBreak::inter()  cambio exeBreak a 1 
              // despues de salirse de todos los bloques verificar que quedo despues de una sentencia ciclo para continuar
              
if ( exeBreak==&&   ((*itAnterior)->NodeType() != SENTENCIAW ) || ((*itAnterior)->NodeType() != SENTENCIAF) ) 
                      break;     
                      
// otra opcion era igualar stm = sentencias.end() y saltarse el switch                               
               
else if (exeBreak==1exeBreak 0
              
               
//// sentenciaContinue::inter()  cambio conti a 1 
              // despues de salirse de todos los bloques verificar que el anterior sea un ciclo y ejecutarlo de nuevo
               
if (  conti==1  &&   (*itAnterior)->NodeType() != SENTENCIAW  || (*itAnterior)->NodeType() != SENTENCIAF)
                          break;                         
               else if (
conti==1)     stm itAnterior;
               
               
// verificar que el stm anterior fuera un method_call 
               
if (  retorno==&&  (*itAnterior)->NodeType() != METHODCALLNAME )  break;                         
               else if (
retorno==1retorno 0;
                
               switch ((*
stm)->NodeType())        {                  
                    case 
ASIGNACION: (dynamic_cast<assign*>(*stm))->inter(); break;
                    case 
METHODCALLNAME: (dynamic_cast<method_callname*>(*stm))->inter(); break;
                    case 
SENTENCIAI: (dynamic_cast<sentenciaIF*>(*stm))->inter(); break;
                    case 
SENTENCIAW: (dynamic_cast<sentenciaWHILE*>(*stm))->inter();break;
                    case 
SENTENCIAR: (dynamic_cast<sentenciaReturn*>(*stm))->inter();break;
                    case 
SENTENCIAB: (dynamic_cast<sentenciaBreak*>(*stm))->inter(); break;
                    case 
SENTENCIAC:(dynamic_cast<sentenciaContinue*>(*stm))->inter();break;                                                 
                         
                         
//  etc
                                            
                    
default: break;                    
               };  
               
stm++; // siempre va a la siguiente y despues verifica                       
       
}                            
}; 
Buena esta es una de las tantas formas que he intentado y hay error en tiempo de ejecucion.
Tambien he intentado asignar *stm a un objeto temporal statement* Anterior y en vez de usar *itAnterior->NodeType usar Anterior->NodeType ...

gracias x colaborar...
__________________
J. Alberto Montoya
------------------

Última edición por albert_sps; 25/03/2010 a las 21:14 Razón: correccionde codigo
  #2 (permalink)  
Antiguo 24/03/2010, 04:39
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 5 meses
Puntos: 61
Respuesta: Iteradores List STL

Comentarios para simplificar el codigo:

1. La comparacion
Código C++:
Ver original
  1. (*itAnterior)->NodeType() != SENTENCIAW  || (*itAnterior)->NodeType() != SENTENCIAW )

parece comparar 2 veces lo mismo. Es asi?

2.
Si declaras el metodo inter() en la clase statement y un block lo derivas de statement, no sera necesario hacer los casts

Código C++:
Ver original
  1. (dynamic_cast<assign*>(*stm))->inter();

y podras hacer, directamente

Código C++:
Ver original
  1. (*stm)->inter()

sin necesidad de preguntar por el tipo antes.

3. La lista esta llena de punteros, has descartado que ellos no sean nulos?
Recomiendo hacer:
Código C++:
Ver original
  1. statement* pstatement = *stm;

y luego comparar pstatement contra 0 (null) y usarlo de ahi en adelante, solo si no es null, en vez de hacer
(*strm)-> .. desreferenciando sin chequear..

En ese caso, la sugerencia 2) quedaria
Código C++:
Ver original
  1. pstatement->inter();
  #3 (permalink)  
Antiguo 25/03/2010, 21:59
 
Fecha de Ingreso: diciembre-2003
Ubicación: San Pedro Sula
Mensajes: 165
Antigüedad: 20 años, 11 meses
Puntos: 0
Respuesta: Iteradores List STL

Bueno lastima que en este foro no se pueden subir imagenes pero coloque unas aqui de lo que intento hacer:

http://uv.unitec.edu/perfiles/100110...mpiladores.jpg

1. Oh si en la comparacion en errror de dedo en realidad es SENTENCIAW y SENTENCIAF (while, for)

2. Tanto block como statement son derivadas de la clase TreeNode, block contiene una lista de statement. Hay una clase BlockStatement derivada de Statement. Segun la gramatica:

Metodo -> tipo ID( {tipo ID}* ) block
block-> '{' declaracion_var* stamentent* '}'
statament-> assign
| WHILE '(' expr ')' block
| <block>

Pero en realidad en cuanto a esto no tengo problema porque ya recorri el arbol durante el analisis semantico y verifique los apuntadores nulos para las producciones epsilon o lambda, la interpretacion funciona bien sin las condiciones de arriba (antes del Switch) para las sentencias exceptuando Continue, Return y Break;


Gracias por responder.
__________________
J. Alberto Montoya
------------------
  #4 (permalink)  
Antiguo 25/03/2010, 23:07
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 5 meses
Puntos: 61
Respuesta: Iteradores List STL

Me parece interesante el problema y mantengo mis recomendaciones anteriores, pero ahora incluyo otras:

- Usar el retorno del metodo inter() y
- No usar variables globales.

Si los metodos inter() dejan de ser void y retornaran (después de haber definido las constantes correspondientes)
- EJECUCION_NORMAL si hay ejecucion normal
- BREAK_PENDIENTE si hay un break pendiente
- CONTINUE_PENDIENTE si hay un continue pendiente
- RETURN_PENDIENTE si hay un return pendiente

bastaría con esta definición para resolver el problema.

- Dado que solo puede haber 1 caso pendiente y no 2, no uses mas de 1 variable para controlar el flujo, no es necesario .
- En cada ocasion (en cada inter() relevante), chequearas si lo pendiente lo puedes resolver. Si no puedes, sales retornando el mismo valor. Si puedes resolverlo, lo resuelves y cambias el estado o continuas.
- Dado esto, o se continua o se sale, nunca se vuelve a una sentencia anterior. No es necesario guardar la sentencia anterior. El stack hace el resto.

y por ultimo

- Cada vez que hay punteros, chequea que no sean null. No importa si ya lo hiciste en un proceso anterior.
  #5 (permalink)  
Antiguo 26/03/2010, 01:12
 
Fecha de Ingreso: diciembre-2003
Ubicación: San Pedro Sula
Mensajes: 165
Antigüedad: 20 años, 11 meses
Puntos: 0
Respuesta: Iteradores List STL

Bueno CC gracias, considerare tus recomendaciones, ahi posteo despues una vez solucionado el problema.. hasta luego.
__________________
J. Alberto Montoya
------------------

Etiquetas: c++, iterador, iterator, list, listas, stl
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:00.