/******************************************************* * MP5.cpp * ******************************************************* * The programm will convert the infix expression * * into the postfix and than evaluate. * * The stack class will be used for conversion and * * evaluation. The equations will be accepted only in * * the infix form. * * Quits when encounters # key. * ******************************************************* * Written by: Olesia Kovalenko * * For: CS 107 * * Date: 4/28/2003 * *******************************************************/ #include #include using namespace std; ///////////////////////////////////////////////////////// // definition of class provided by the professor Troy // ///////////////////////////////////////////////////////// class StackElem { // This class will store either a character or double data type. // The names reflect the intended usage of this class with a program // for infix to postfix equation translation and postfix equation // evaluation. // The class has two data members: // the first is an instance of an enumerated type to tell whether // the instance of the class is an operator/character or a // number/double. THis value could be undefined in case the // instance of the class is created by the default constructor. // // the second is an instance of a union that will hold either the // character value or the double value public: // create the enumerated type to determine the value stored in // the instance enum SEType {UNDEFINED, OPERATOR, NUMBER}; private: // create the union to hold either the character or the double value union SEUnion { char oper; double numb; }; // data member definition SEType et; // the instance of the enumerated type SEUnion eu; // the instance of the union public: // default constructor - type is unknown StackElem () { et = UNDEFINED; eu.oper = '\0'; eu.numb = 0.0; } // constructor to set up the instance to hold an operator StackElem (char op) { et = OPERATOR; eu.oper = op; } // constructor to set up the instance to hold a numeric value StackElem (double num) { et = NUMBER; eu.numb = num; } // a method to store an operator in the instance void setOperator(char op) { et = OPERATOR; eu.oper = op; } // a method to store a numeric value in the instance void setNumber(double num) { et = NUMBER; eu.numb = num; } // a method to return the type of value stored in the instance SEType getType() { return et; } // a method to access an operator value // This method will return true if the instance does indeed // store an operator and false otherwise // The method uses a pass-by-reference parameter to send the // operator value back to the calling code. If the instance // does not contain an operator the null character is sent // back to the calling code. bool getOperator (char &op) { if (et == OPERATOR) { op = eu.oper; return true; } else { op = '\0'; return false; } } // a method to access an operator value // This method will return the operator value if the // instance does indeed store an operator value. // Otherwise the null character is returned. char getOperator () { if (et == OPERATOR) return eu.oper; else return '\0'; } // a method to access a numeric value // This method will return true if the instance does indeed // store a numeric and false otherwise // The method uses a pass-by-reference parameter to send the // numeric value back to the calling code. If the instance // does not contain an numeric the value of 0.0 is sent // back to the calling code. bool getNumber (double &num) { if (et == NUMBER) { num = eu.numb; return true; } else { num = 0.0; return false; } } // a method to access a numeric value // This method will return the numeric value if the // instance does indeed store a numeric value. // Otherwise the value of 0.0 is returned. double getNumber () { if (et == NUMBER) return eu.numb; else return 0.0; } // This method is meant for debugging purposes. // It outputs the type and value of the instance to cout. void output () { if (et == UNDEFINED) cout << "UNDEFINED."; else if (et == OPERATOR) cout << "OPERATOR: " << eu.oper; else if (et == NUMBER) cout << "NUMBER: " << eu.numb; } }; ///////////////////////////// //Definition of the class // ///////////////////////////// //1. Stack class. //The class will serve the purpose of the stack //used to convert from infix form into postfix and evaluate class Stack { private: int maxSize; StackElem* mystack; int numberUsed; public: //default constractor Stack() { maxSize = 5; mystack = new StackElem[maxSize]; numberUsed=0; } //copy constractor Stack (const Stack& somestack) { maxSize=2*somestack.maxSize; mystack = new StackElem[maxSize]; for (int i=0; i= currentSizeInput) { grow(input, currentSizeInput); } } // close the expression with ';' element.setOperator(';'); input[char_read]=element; char_read++; //return true is completed successfully return(true); } // 4. // The function will display the equation upon request // IN: Dinamic array, and number of elements in it // OUT: None. the contents of the dynamic array are displayed. void dispEq( StackElem* &input, int char_read) { cout<=stack.getMaxSize()) { growS(stack); } //push the current operator on stack stack.push(input[pos]); } //if closing parenthesis encountered pop the stack into the postfix and ( is not found or empty else if(input[pos].getOperator()==')') { if(!(stack.isEmpty())) { temp=stack.top(); } while(!(stack.isEmpty()) && (temp.getOperator()!='(')) { //pop into postfix array postfix[size_postfix]=stack.pop(); size_postfix++; //check what is new value on top if(!(stack.isEmpty())) { temp=stack.top(); } } //if stack is empty return to the main if(stack.isEmpty()) { cout<<"ERROR: unmatched closing parenthesis."<op2 // -1 if op1precLevel(operator2)) return(1); else if(precLevel(operator1)=stack.getMaxSize()) { growS(stack); } stack.push(postfix[count]); } //if the operator is encountered pop the two values of the stack //note that the value poped second is the one from which is substracted //and which is divided else if (postfix[count].getType()==StackElem::OPERATOR) { //if the stack is not empty perform operation //if the stack becomes empty than the operands obtained //than expression is unbalanced if(!(stack.isEmpty())) //pop the value of the stack numw=stack.pop(); else error=true; if(!(stack.isEmpty())) //pop the second value of the stack numf=stack.pop(); else error=true; //if no error was encountered perform operation if(!error) { //grow the stack if needed if (stack.getNumberUsed()>=stack.getMaxSize()) { growS(stack); } //push the result on the stack stack.push(operation(numf,numw,postfix[count])); } } //increment the count count++; } //the last operator has to be ; since it was put artificially into the postfix //if not than there is a definite error if(postfix[count].getOperator()==';') { //if there is no error pop the result off the stack if(!(stack.isEmpty())) { temp=stack.pop(); } else { error=true; } //if the stack at that point is not empty or the value on the stack is not a number //than it is an error if( (!(stack.isEmpty())) || (temp.getType()!=StackElem::NUMBER) ) { error=true; } //if the error was encountered print the error message and return if(error) { cout<