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...