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()) {
                   itAnterior= stm;
                   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==1 &&   ((*itAnterior)->NodeType() != SENTENCIAW ) || ((*itAnterior)->NodeType() != SENTENCIAF) ) 
                      break;     
                      // otra opcion era igualar stm = sentencias.end() y saltarse el switch                               
               else if (exeBreak==1) exeBreak = 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==1 &&  (*itAnterior)->NodeType() != METHODCALLNAME )  break;                         
               else if (retorno==1) retorno = 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                       
       }                            
}; 
    Tambien he intentado asignar *stm a un objeto temporal statement* Anterior y en vez de usar *itAnterior->NodeType usar Anterior->NodeType ...
gracias x colaborar...
 
 
 en realidad es SENTENCIAW y SENTENCIAF  (while, for)
 

