/** * * @brief creates transitions for 'dup' mirroring 'orig' outgoing transitions * * @param - orig: the state that is being duplicated * @param - dup: the state that is duplicating 'orig' * */ void TransitionStorage::dupTransOutgoing( State orig, State dup ) { // Duplicate outgoing internal transitions. const Info::Internals & from = T_info.fromTrans(orig); for( Info::InternalIterator it = from.begin(); it != from.end(); it++ ) { Internal iTrans(dup,getInternalSym(*it),getTarget(*it)); addInternal(iTrans); } // Duplicate call site call transitions. const Info::Calls & call = T_info.callTrans(orig); for( Info::CallIterator it = call.begin(); it != call.end(); it++ ) { Call cTrans(dup,getCallSym(*it),getEntry(*it)); addCall(cTrans); } // Duplicate exit point return transitions. const Info::Returns & exit = T_info.exitTrans(orig); for( Info::ReturnIterator it = exit.begin(); it != exit.end(); it++ ) { Return rTrans(dup,getCallSite(*it),getReturnSym(*it),getReturnSite(*it)); addReturn(rTrans); } // Q: Do we want to do these? Seems inconsistent. -Evan // A: Aditya says 'yes', and thinks we need it. So we definitely don't // want to change it without looking at uses and compensating. // Duplicate call predecessor return transitions. const Info::Returns & pred = T_info.predTrans(orig); for( Info::ReturnIterator it = pred.begin(); it != pred.end(); it++ ) { Return rTrans(getExit(*it),dup,getReturnSym(*it),getReturnSite(*it)); addReturn(rTrans); } }
void UContainerTag::menu(QMenu &menu) { QMenu *m; if(isIndependent()) { m=menu.addMenu("Insert within"); }else m=&menu; m->addAction(" - Insert -")->setEnabled(false); m->addAction("Condition",this,SLOT(addCondition())); m->addAction("Traverse",this,SLOT(addTraverse())); m->addAction("Loop",this,SLOT(addLoop())); m->addAction("Break loop",this,SLOT(addBreak())); m->addAction("Continue loop",this,SLOT(addContinue())); m->addAction("Function call",this,SLOT(addFunction())); m->addAction("Variable assign",this,SLOT(addAssign())); m->addAction("Return",this,SLOT(addReturn())); m->addAction("Python command",this,SLOT(addExec())); m->addAction("Comment",this,SLOT(addComment())); }
/** * * @brief add all transitions in the given collection of transitions to this * collection of transitions * * @param - addTransitionStorage: the collection of transitions to add to this * collection of transitions * */ void TransitionStorage::addAllTrans( TransitionStorage addTransSet ) { //Add call transitions. for(CallIterator it = addTransSet.beginCall(); it != addTransSet.endCall(); it ++ ) { addCall(*it); } //Add internal transitions. for(InternalIterator it = addTransSet.beginInternal(); it != addTransSet.endInternal(); it ++ ) { addInternal(*it); } //Add return transitions. for(ReturnIterator it = addTransSet.beginReturn(); it != addTransSet.endReturn(); it ++ ) { addReturn(*it); } }
nodeADT parse(FILE * file, int state) { nodeADT first; nodeADT current; tNumbers vecWhile; tNumbers vecIf; tNumbers vecBalance; vecWhile.numbers = malloc((sizeof(int)) * BLOQUE); vecWhile.pos = 0; vecIf.numbers = malloc(sizeof(int) * BLOQUE); vecIf.pos = 0; vecBalance.numbers = calloc(sizeof(int), BLOQUE); vecBalance.pos = 0; char * string = malloc(sizeof(char) * BLOQUE); int index = 0; int c, i; Commands com = empty; int isFirst = TRUE; Stack stack; stack_init(&stack); while ((c = fgetc(file)) != EOF) { switch (c) { case '(': vecBalance.numbers = resizeMemInt(vecBalance.pos, vecBalance.numbers); (vecBalance.numbers)[vecBalance.pos] = c; for (i = 0; i < index; i++) { string[i] = toupper(string[i]); } if (strncmp(string, "INC", index) == 0) { com = inc; } else if (strncmp(string, "DEC", index) == 0) { com = dec; } else if (strncmp(string, "MR", index) == 0) { com = mr; } else if (strncmp(string, "ML", index) == 0) { com = ml; } else if (strncmp(string, "CZ", index) == 0) { com = cz; } else if (strncmp(string, "IF", index) == 0) { com = ifa; } else if (strncmp(string, "ENDIF", index) == 0) { com = endif; } else if (strncmp(string, "WHILE", index) == 0) { com = whilea; } else if (strncmp(string, "ENDWHILE", index) == 0) { com = endwhile; } else { fprintf(stderr, "Parser invalido1\n"); exit(1); } if (isFirst) { first = newNode(com); current = first; isFirst = FALSE; } else { nodeADT next = newNode(com); addNext(current, next); current = next; } index = 0; break; case ')': if (vecBalance.numbers[vecBalance.pos] != '(') { if (state) { fseek(file, -1, SEEK_CUR); return first; } else { fprintf(stderr, "Parser invalido2\n"); exit(1); } } else { vecBalance.numbers[vecBalance.pos] = 0; } if (index == 0) { if (com != cz) { fprintf(stderr, "Parser invalido3\n"); exit(1); } else { addParam(current, -1); } } else { if (com == endif) { if (vecIf.numbers[(vecIf.pos) - 1] != toInt(string, index)) { fprintf(stderr, "Parser invalido4\n"); exit(1); } (vecIf.pos) -= 1; nodeADT returnTO = (nodeADT) stack_top(&stack); stack_pop(&stack, 0); addReturn(current, returnTO); //le digo al ENDIF cual es su IF correspondiente addJump(returnTO, current); //le digo al IF cual es su ENDIF correspondiente addParam(current, getParam(returnTO)); } else if (com == endwhile) { if (vecWhile.numbers[(vecWhile.pos) - 1] != toInt(string, index)) { fprintf(stderr, "Parser invalido5\n"); exit(1); } (vecWhile.pos) -= 1; nodeADT returnTO = (nodeADT) stack_top(&stack); //castear, maybe stack_pop(&stack, 0); addReturn(current, returnTO); addJump(returnTO, current); addParam(current, getParam(returnTO)); } else if (com == cz) { fprintf(stderr, "Parser invalido6\n"); exit(1); } else { hasNumbers(string, index); addParam(current, toInt(string, index)); } vecBalance.numbers[vecBalance.pos] = 0; index = 0; } break; case ',': if (index != 0 && (com == ifa || com == whilea)) { hasNumbers(string, index); addParam(current, toInt(string, index)); if (com == ifa) { vecIf.numbers = resizeMemInt(vecIf.pos, vecIf.numbers); vecIf.numbers[(vecIf.pos)++] = toInt(string, index); } else { vecWhile.numbers = resizeMemInt(vecWhile.pos, vecWhile.numbers); vecWhile.numbers[(vecWhile.pos)++] = toInt(string, index); } stack_push(&stack, current); addExe(current, parse(file, TRUE)); } else { fprintf(stderr, "Parser invalido7\n"); exit(1); } break; case ' ': case '\n': case '\t': break; default: string = resizeMemChar(index, string); string[index++] = c; break; } } if (vecBalance.numbers[vecBalance.pos] != 0) { fprintf(stderr, "Parser invalido8\n"); exit(1); } return first; }
/** * * @brief add a return transition to the NWA * * @param - from: the state the edge departs from * @param - pred: the state from which the call was initiated * @param - sym: the symbol labeling the edge * @param - to: the state the edge arrives to * @return false if the return transition already exists in the NWA * */ bool TransitionStorage::addReturn( State from, State pred, Symbol sym, State to ) { Return rt(from,pred,sym,to); return addReturn(rt); }
/** * * @brief creates transitions for 'dup' mirroring 'orig' transitions * * @param - orig: the state that is being duplicated * @param - dup: the state that is duplicating 'orig' * */ void TransitionStorage::dupTrans( State orig, State dup ) { //Duplicate outgoing internal transitions. const Info::Internals & from = T_info.fromTrans(orig); for( Info::InternalIterator it = from.begin(); it != from.end(); it++ ) { Internal iTrans(dup,getInternalSym(*it),getTarget(*it)); addInternal(iTrans); // Q: This is also inconsistent with dupTransOutgoing, which didn't do // anything special with self loops. -Evan // A: Aditya says yes, but this is again what McVeto(?) needs. // dupTrans is used in 'duplicateState', but dupTransOutgoing is // different. if( orig == getTarget(*it) ) //Handle self-loops. { Internal loop(dup,getInternalSym(*it),dup); addInternal(loop); } } //Duplicate incoming internal transitions. const Info::Internals & to = T_info.toTrans(orig); for( Info::InternalIterator it = to.begin(); it != to.end(); it++ ) { Internal iTrans(getSource(*it),getInternalSym(*it),dup); addInternal(iTrans); } //Duplicate call site call transitions. const Info::Calls & call = T_info.callTrans(orig); for( Info::CallIterator it = call.begin(); it != call.end(); it++ ) { Call cTrans(dup,getCallSym(*it),getEntry(*it)); addCall(cTrans); if( orig == getEntry(*it) ) //Handle self-loops. { Call loop(dup,getCallSym(*it),dup); addCall(loop); } } //Duplicate entry point call transitions. const Info::Calls & entry = T_info.entryTrans(orig); for( Info::CallIterator it = entry.begin(); it != entry.end(); it++ ) { Call cTrans(getCallSite(*it),getCallSym(*it),dup); addCall(cTrans); } //Duplicate exit point return transitions. const Info::Returns & exit = T_info.exitTrans(orig); for( Info::ReturnIterator it = exit.begin(); it != exit.end(); it++ ) { Return rTrans(dup,getCallSite(*it),getReturnSym(*it),getReturnSite(*it)); addReturn(rTrans); if( orig == getCallSite(*it) ) //Handle self-loops. { Return loop(dup,dup,getReturnSym(*it),getReturnSite(*it)); addReturn(loop); } if( orig == getReturnSite(*it) ) //Handle self-loops. { Return loop(dup,getCallSite(*it),getReturnSym(*it),dup); addReturn(loop); } if( orig == getCallSite(*it) && orig == getReturnSite(*it) ) //Handle self-loops. { Return loop(dup,dup,getReturnSym(*it),dup); addReturn(loop); } } //Duplicate call predecessor return transitions. const Info::Returns & pred = T_info.predTrans(orig); for( Info::ReturnIterator it = pred.begin(); it != pred.end(); it++ ) { Return rTrans(getExit(*it),dup,getReturnSym(*it),getReturnSite(*it)); addReturn(rTrans); if( orig == getReturnSite(*it) ) //Handle self-loops. { Return loop(getExit(*it),dup,getReturnSym(*it),dup); addReturn(loop); } } //Duplicate return site return transitions. const Info::Returns & ret = T_info.retTrans(orig); for( Info::ReturnIterator it = ret.begin(); it != ret.end(); it++ ) { Return rTrans(getExit(*it),getCallSite(*it),getReturnSym(*it),dup); addReturn(rTrans); } }