//put crtOp on stack respecting operator precedence; i.e. * can be pushed on top of + or - but not the other way round void putOperatorOnStack(char* crtOp, FILE* out) { char name[20]; char* topOp = topElement(&opStack); if (DEBUG) {printf("putOperatorOnStack(%s): crtOp = %s topOp = %s\n", D(crtOp), D(crtOp), D(topOp));} //BASE CASE: left paranthesis; push and resume if (!isOperator(topOp)) { if (DEBUG) {printf("putOperatorOnStack(%s): OP_PUSH(%s)\n", D(crtOp), D(crtOp));} push(createVElement(crtOp), &opStack, -1); return; } int opPerformed = 0; while (isOperator(topOp)) { //If the precedence of the operator which needs to be put on the stack crtOp is lower than the precedence of the operator //on the top of the stack, topOp, perform the operation denoted by topOp and the top two numbers from the RESULT_STACK. //An optimization step is performed by using the ACC, thus avoiding the need to create extra temporary variables. if (getPrecedence(crtOp) <= getPrecedence(topOp)) { if (!opPerformed) { //in the very first iteration load number from RESULT_STACK into ACC VElement* temp = pop(&resStack); if (DEBUG) {printf("putOperatorOnStack(): RES_POP(%s)\n", D(temp->data));} fprintf(out, "\tLOAD\t%s\n", temp->data); } if (DEBUG) {printf("putOperatorOnStack(%s): getPrecedence(%s) <= getPrecedence(%s)\n", D(crtOp), D(crtOp), D(topOp));} //perform operation topOp between ACC and the number on the top of the RESULT_STACK performOperationWithACC(out); opPerformed = 1; }else{ if (DEBUG) {printf("putOperatorOnStack(%s): getPrecedence(%s) > getPrecedence(%s)\n", D(crtOp), D(crtOp), D(topOp));} break; } //fetch next operand topOp = topElement(&opStack); } if (opPerformed) { //store result from ACC into temporary variable strcpy(name, newName(VAR)); fprintf(out, "\tSTORE\t%s\n", name); if (DEBUG) {printf("putOperatorOnStack(): RES_PUSH(%s)\n", D(name));} push(createVElement(name), &resStack, -1); } if (DEBUG) {printf("putOperatorOnStack(%s): OP_PUSH(%s)\n", D(crtOp), D(crtOp));} push(createVElement(crtOp), &opStack, -1); }
//process all operators from the OPERATOR_STACK, going from top to the bottom up to the first "(" operator or an empty stack, whichever comes first void reduceParanthesis(FILE* out, int withLPar) { char name[20]; if (isStackEmpty(&opStack)) { if (DEBUG) {printf("reduceParanthesis(): OP stack is empty\n");} return; } char* topOp = topElement(&opStack); if (!isOperator(topOp)) { if (DEBUG) {printf("reduceParanthesis(): OP_POP(%s)\n", D(topOp));} pop(&opStack); return; } if (DEBUG) {printf("reduceParanthesis(): topOp = %s\n", D(topOp));} //1. take the number at the top of the RESULT_STACK VElement* temp = pop(&resStack); if (DEBUG) {printf("reduceParanthesis(): RES_POP(%s)\n", D(temp->data));} //2. load it into ACC fprintf(out, "\tLOAD\t%s\n", temp->data); while (isOperator(topOp)) { if (DEBUG) { printf("reduceParanthesis(): OP stack is: \n"); displayStack(&opStack); printf("reduceParanthesis(): RES stack is: \n"); displayStack(&resStack); } //3. perform operation between ACC, number on top of RESULT_STACK using operator on top of OPERATOR_STACK; store result in ACC performOperationWithACC(out); topOp = topElement(&opStack); }//repeat until empty stack or "(" is encountered if (withLPar) { //remove left paranthesis and store ACC on RESULT_STACK strcpy(name, newName(VAR)); fprintf(out, "\tSTORE\t%s\n", name); if (DEBUG) {printf("reduceParanthesis(): RES_PUSH(%s)\n", D(name));} push(createVElement(name), &resStack, -1); if (DEBUG) {printf("reduceParanthesis(): OP_POP(%s)\n", D(topOp));} pop(&opStack); } }
/************************ convertSubTaskOperator ******************************* void convertSubTaskOperator(Stack stack, Out out, Element *pElement) Purpose: This function handles the case of an operator token. The operators in the stack with a higher or equal precedence get outted and the new operator gets pushed to the stack. Parameters: I/O Stack stack The current stack. O Out out The out structure used in the conversion. I Element *pElement The operator element. Returns: stack parm - the updated stack. out parm - the updated out structure. Notes: This is a sub task of the query conversion from infix format to postfix format. *******************************************************************************/ void convertSubTaskOperator(Stack stack, Out out, Element *pElement) { while(isEmpty(stack) == FALSE && pElement->iPrecedence <= topElement(stack).iPrecedence) //loop until the stack is empty or there's no more operator in the stack with a lower //precedence than the top of the stack { addOut(out, pop(stack)); //POP and OUT the higher precedence operator from the stack } push(stack, *pElement); }
/*********************** convertSubTaskRemainingStack ************************** int convertSubTaskRemainingStack(Stack stack, Out out) Purpose: This function handles the rest of the stack once we've gone through all of the tokens in the input. It also handles the case of a leftover unmatched parenthesis in the stack. Parameters: I/O Stack stack The current stack. O Out out The out structure used in the conversion. Returns: stack parm - the freed stack. out parm - the final out structure. Notes: This is a sub task of the query conversion from infix format to postfix format. *******************************************************************************/ int convertSubTaskRemainingStack(Stack stack, Out out) { while (isEmpty(stack) == FALSE) //goes through the remaining stack until empty { if (topElement(stack).iCategory == CAT_LPAREN)//if an unmatched ( is found { freeStack(stack); //at this point we are done using the stack return WARN_MISSING_RPAREN; //return error } addOut(out, pop(stack)); //POP and OUT the stack } freeStack(stack); //at this point we are done using the stack }
/************************** convertSubTaskRParen ******************************* int convertSubTaskRParen(Stack stack, Out out) Purpose: This function handles the case of a right parenthesis token. The elements in the stack get outted until we find the matching right parenthesis if there is one. Parameters: I/O Stack stack The current stack. O Out out The out structure used in the conversion. Returns: stack parm - the updated stack. out parm - the updated out structure. Notes: This is a sub task of the query conversion from infix format to postfix format. *******************************************************************************/ int convertSubTaskRParen(Stack stack, Out out) { while (isEmpty(stack) == FALSE && topElement(stack).iCategory != CAT_LPAREN) { addOut(out, pop(stack)); //POP and OUT content of the stack until left parenthesis is found } if (isEmpty(stack) == TRUE) //if we didn't find a ( { freeStack(stack); //at this point we are done using the stack return WARN_MISSING_LPAREN; //return error } pop(stack); //POP and get rid of ( }
bool Regola::applyMetadata(QTreeWidget *tree, MetadataInfo *info) { //--- bool result = true; int operations = 0 ; // build a list of commands QList<PseudoAttribute*>updateDataList; QList<PseudoAttribute*>insertDataList; QList<PseudoAttribute*>deleteDataList; // populate the lists updateDataList = info->manualAttributeListByCondition(true, true); insertDataList = info->manualAttributeListByCondition(false, true); deleteDataList = info->manualAttributeListByCondition(true, false); if((updateDataList.size() + insertDataList.size() + deleteDataList.size()) == 0) { return true ; } _undoStack.beginMacro(tr("Metadata")); // update in place foreach(PseudoAttribute * attr, updateDataList) { int row = attr->row(); Element *metaElement = topElement(row); if((NULL == metaElement) || ((NULL != metaElement) && (metaElement->getType() != Element::ET_PROCESSING_INSTRUCTION) && (metaElement->getPITarget() != MetadataInfo::QXMLEDIT_TARGET_PI))) { result = false ; } else { QString newData = attr->toStringComplete(); UndoEditCommand *undoCommand = new UndoEditCommand(tree, this, metaElement->indexPath()); undoCommand->setOriginalElement(metaElement); metaElement->setPIData(newData); metaElement->display(metaElement->getUI(), paintInfo); metaElement->markEdited(); undoCommand->setModifiedElement(metaElement); operations++; _undoStack.push(undoCommand); } }