void test_tryEvaluateOperatorOnStackThenPush_will_push_OperatorToken_if_Operator_Stack_is_empty(void){ Stack numberStack; Stack operatorStack; Operator *opeToken; stackPop_ExpectAndReturn(&operatorStack,NULL); stackPush_Expect(opeToken,&operatorStack); tryEvaluateOperatorOnStackThenPush(opeToken,&numberStack,&operatorStack); }
void evaluatePostfixesPrefixesAndInfixes(char *expression,Token *token,Stack *numberStack,Stack *operatorStack){ if(token!=NULL){ if(isOperator(token)){ if(((Operator*)token)->info->affix == INFIX ){ tryEvaluateOperatorOnStackThenPush((Operator*)token,numberStack,operatorStack); }else if(((Operator*)token)->info->affix == PREFIX || ((Operator*)token)->info->affix == POSTFIX){ tryEvaluatePrefixOperatorOnStackThenPush((Operator*)token,numberStack,operatorStack); }else{ Throw(ERR_EXPECTING_OPERATOR); } }else if(isNumber(token)){ stackPush(token,numberStack); }else{ Throw(ERR_EXPECTING_NUMBER_OR_PREFIX); } } }
int evaluate(char *expression,Stack *dataStack,Stack *operatorStack){ Tokenizer *tokenizer; Token *token; Token *ansToken; ErrorCode e; int i; int counter =0; NumberToken *result; dataStack=stackNew(); operatorStack=stackNew(); tokenizer = tokenizerNew(expression); if(expression ==NULL){ Throw(ERR_NO_EXPRESSION); } while((token=nextToken(tokenizer))!=NULL){ if(counter%2==0&&token->type==OPERATOR_TOKEN){ Throw(ERR_NOT_DATA); } else if(counter%2==1&&token->type==NUMBER_TOKEN){ Throw(ERR_NOT_OPERATOR); } if(isNumber(token)){ push(token,dataStack); } else if(isOperator(token)) { tryEvaluateOperatorOnStackThenPush((OperatorToken*)token,dataStack,operatorStack); } counter ++; } evaluateAllOperatorOnStack(dataStack,operatorStack); result=(NumberToken*)pop(dataStack); printf("counter needed for each expression : %d \n",counter); return result->value; }
/******************************************************************************************* * This function is to evaluate the expression which contains numbers and operators and * return the results in number form. * This function is a prototype function which use as reference to * improve in the evaluateExpression(char*expression) function. * Thus, this function could not evaluate expression like -2,*2,(((2))), +-+-2... * * input : expression * output : none * return : ((Number*)token)->value * ********************************************************************************************/ int evaluate(char *expression){ Token *token; Number *result; Stack *numberStack=createStack(); Stack *operatorStack=createStack(); if(expression ==NULL){ Throw(ERR_NO_ARGUMENT); } Text *newText=textNew(expression); String *tokenizer = stringNew(newText); while((token=getToken(tokenizer))!=NULL ){ if(isNumber(token)){ stackPush(token,numberStack); } else if(isOperator(token)) { if(((Operator*)token)->info->id==OPENING_BRACKET_OP || ((Operator*)token)->info->id==CLOSING_BRACKET_OP) { tryEvaluatePrefixOperatorOnStackThenPush((Operator*)token,numberStack,operatorStack); } else{ tryEvaluateOperatorOnStackThenPush((Operator*)token,numberStack,operatorStack); } } } if(operatorStack == NULL){ operatorPrefixEvaluate(numberStack ,(Operator*)token); }else{ evaluateAllOperatorOnStack(numberStack,operatorStack); } result=(Number*)stackPop(numberStack); destroyStack(numberStack); if(operatorStack !=NULL){ destroyStack(operatorStack); } return result->value; }
void test_tryEvaluateOperatorOnStackThenPush_will_push_OperatorTOken_into_Operator_Stack_if_newToken_precendence_is_higher_than_previousToken(void) { Stack numberStack; Stack operatorStack; Operator plus = {.type= OPERATOR, .id=ADD , .precedence =70}; Operator multiply = {.type= OPERATOR, .id=MULTIPLY , .precedence =100}; stackPop_ExpectAndReturn(&operatorStack,&plus); stackPush_Expect(&plus,&operatorStack); stackPush_Expect(&multiply,&operatorStack); tryEvaluateOperatorOnStackThenPush(&multiply,&numberStack,&operatorStack); } void test_tryEvaluateOperatorOnStackThenPush_will_not_push_OperatorTOken_into_Operator_Stack_if_newToken_precendence_is_lower_than_previousToken(void) { Stack numberStack; Stack operatorStack; //1*2+3 Number number1 = {.type= NUMBER, .value=1}; Operator multiply = {.type= OPERATOR, .id=MULTIPLY, .precedence=100}; Number number2 = {.type= NUMBER, .value=2}; Operator plus = {.type= OPERATOR, .id=ADD, .precedence=70}; Number number3 = {.type= NUMBER, .value=3}; Number tempAns = {.type= NUMBER, .value=2}; Token *tempAnsToken =(Token*)&tempAns; stackPop_ExpectAndReturn(&operatorStack,&multiply); stackPop_ExpectAndReturn(&numberStack,&number2); stackPop_ExpectAndReturn(&numberStack,&number1); createNumberToken_ExpectAndReturn(2,tempAnsToken); stackPush_Expect(&tempAns,&numberStack); stackPop_ExpectAndReturn(&operatorStack,NULL); stackPush_Expect(&plus,&operatorStack); tryEvaluateOperatorOnStackThenPush(&plus,&numberStack,&operatorStack); } void test_tryEvaluateOperatorOnStackThenPush_evaluate_newToke_and_previousToken_if_both_have_same_precedence(void) { Stack numberStack; Stack operatorStack; //100-20-16 Number number100 = {.type= NUMBER, .value=100}; Operator minus = {.type= OPERATOR, .id=SUBTRACT, .precedence=70}; Number number20 = {.type= NUMBER, .value=20}; Operator minusA = {.type= OPERATOR, .id=SUBTRACT , .precedence=70}; Number number16 = {.type= NUMBER, .value=16}; Number tempAns = {.type= NUMBER, .value=80}; Token *tempAnsToken =(Token*)&tempAns; stackPop_ExpectAndReturn(&operatorStack,&minus); stackPop_ExpectAndReturn(&numberStack,&number20); stackPop_ExpectAndReturn(&numberStack,&number100); createNumberToken_ExpectAndReturn(80,tempAnsToken); stackPush_Expect(&tempAns,&numberStack); stackPop_ExpectAndReturn(&operatorStack,NULL); stackPush_Expect(&minusA,&operatorStack); tryEvaluateOperatorOnStackThenPush(&minusA,&numberStack,&operatorStack); } void test_tryEvaluateOperatorOnStackThenPush_evaluate_all_operatorTokens_to_be_push_in_the_operator_stack_1(void) { Stack numberStack; Stack operatorStack; //21*22+30/6 Number number21 = {.type= NUMBER, .value=21}; Operator multiply = {.type= OPERATOR, .id=MULTIPLY, .precedence=100}; Number number22 = {.type= NUMBER, .value=22}; Number tempAns = {.type= NUMBER, .value=462}; Token *tempAnsToken =(Token*)&tempAns; Operator plus = {.type= OPERATOR, .id=ADD, .precedence=70}; Number number30 = {.type= NUMBER, .value=30}; Operator divide = {.type= OPERATOR, .id=DIVIDE, .precedence=100}; Number number6 = {.type= NUMBER, .value=6}; stackPop_ExpectAndReturn(&operatorStack,&multiply); stackPop_ExpectAndReturn(&numberStack,&number22); stackPop_ExpectAndReturn(&numberStack,&number21); createNumberToken_ExpectAndReturn(462,tempAnsToken); stackPush_Expect(tempAnsToken,&numberStack); stackPop_ExpectAndReturn(&operatorStack,&plus); stackPush_Expect(&plus,&operatorStack); stackPush_Expect(÷,&operatorStack); tryEvaluateOperatorOnStackThenPush(÷,&numberStack,&operatorStack); } void test_tryEvaluateOperatorOnStackThenPush_evaluate_all_operatorTokens_to_be_push_in_the_operator_stack_2(void) { Stack dataStack; Stack operatorStack; //21+22&30|6 Number number21 = {.type= NUMBER, .value=21}; Operator plus = {.type= OPERATOR, .id=ADD, .precedence=70}; Number number22 = {.type= NUMBER, .value=22}; Number tempAns1 = {.type= NUMBER, .value=43}; Token *tempAnsToken1 =(Token*)&tempAns1; Operator bitwiseAND = {.type= OPERATOR, .id=BITWISE_AND, .precedence=20}; Number number30 = {.type= NUMBER, .value=30}; Operator bitwiseOR = {.type= OPERATOR, .id=BITWISE_OR, .precedence=10}; Number number6 = {.type= NUMBER, .value=6}; Number tempAns2 = {.type= NUMBER, .value=6}; Token *tempAnsToken2 =(Token*)&tempAns2; stackPop_ExpectAndReturn(&operatorStack,&plus); stackPop_ExpectAndReturn(&dataStack,&number22); stackPop_ExpectAndReturn(&dataStack,&number21); createNumberToken_ExpectAndReturn(43,tempAnsToken1); stackPush_Expect(tempAnsToken1,&dataStack); stackPop_ExpectAndReturn(&operatorStack,&bitwiseAND); stackPop_ExpectAndReturn(&dataStack,&number30); stackPop_ExpectAndReturn(&dataStack,&number6); createNumberToken_ExpectAndReturn(6,tempAnsToken2); stackPush_Expect(tempAnsToken2,&dataStack); stackPop_ExpectAndReturn(&operatorStack,NULL); stackPush_Expect(&bitwiseOR,&operatorStack); tryEvaluateOperatorOnStackThenPush(&bitwiseOR,&dataStack,&operatorStack); }