Ejemplo n.º 1
0
void in2pre (char *inexp) {
    char t;
    char preExp[25];
    char *rInExp;
    char *rPreExp;
    int i,j;
    struct Stack* stack;
    i=j=0;
    printf("\nInput Infix Expression is : %s",inexp);
    rInExp = strrev(inexp);
    printf("\nReversed input Infix Expression is : %s",rInExp);
    stack = createStack(25);
    while(rInExp[i] != '\0') {

        if(isParenthesis(rInExp[i]) == 1) {  //Left Parenthesis
                printf("\nLeft Parenthesis Encountered.");
                while(peek(stack) != ')') { // pop until a Right parenthesis encounters
                    if(peek(stack) != CHAR_MIN){
                       preExp[j] = pop(stack);
                       j++;
                    }
                }
                pop(stack); //Remove Left Parenthesis
        }

        else if(isParenthesis(rInExp[i]) == 2 || isOperator(rInExp[i]) == 1) {        //Operator or Right Parenthesis
            if(isParenthesis(rInExp[i]) == 2 ) {
                printf("\nRight Parenthesis Encountered.");
                push(stack, rInExp[i]);  // Push Right Parenthesis on Stack
            }
            if (isOperator(rInExp[i]) == 1) {
                printf("\nOperator Encountered.");
                while((getPrecedence(rInExp[i]) < getPrecedence(peek(stack))) && (peek(stack) != CHAR_MIN) && (isParenthesis(peek(stack)) != 2 )  ) {
                   preExp[j] = pop(stack);
                   j++;
                }
                push(stack, rInExp[i]);
            }
        }
        else{  //if t is operand
            preExp[j] = rInExp[i];
            printf("\nOperand : %c",preExp[j]);
            j++;
        }
        i++;

    }
    while(peek(stack) != CHAR_MIN) {
        preExp[j] = pop(stack);
        j++;
    }
    preExp[j] = '\0';
    printf("\nPreFix : %s\n",preExp);
    rPreExp = strrev(preExp);
    printf("\nFinal PreFix : %s\n",rPreExp);
    //printf("%c popped from stack\n", pop(stack));
    //printf("%c popped from stack\n", pop(stack));
    //printf("%c popped from stack\n", pop(stack));
    //printf("%c popped from stack\n", pop(stack));
}
std::string Calculator::checkForUnaryMinus(std::string& expression)
{
	for (size_t i = 0; i < expression.length(); i++)
	{
		const std::string token = expression.substr(i, 1);

		if (token == "-")
		{
			if (token == expression.substr(0, 1) && expression.substr(i + 1, 1) == "(") // If "-" is in front of an entire expression in parentheses (e.g., -(3+2))
			{
				negateAnswer(); // Set flag to signify that evaluated expression should be negated
				expression.erase(i, 1); // Removes minus from string
			}
			else if (token == expression.substr(0, 1) && isNumber(expression.substr(i + 1, 1))) // First character in string is a negative number
			{
				expression.replace(i, 1, "u"); // Replace unary minus with "u"
			}
			else if (isOperator(expression.substr(i - 1, 1)) || isParenthesis(expression.substr(i-1,1))) // Unary minuses occuring within the string
			{
				expression.replace(i, 1, "u"); // Replace unary minus with "u"
			}
		}
	}
	return expression;
}
Ejemplo n.º 3
0
/**
  * Parses and calculates outer parenthesis pair.
  * May be called recursively.
  * Returns the result as a QString.
  */
void Calculator::parseParenthesis(QStringList & expressionParts, int openingParenthesisPos)
{
    int parenthesisCount = 1;
    int nextParenthesisPos = openingParenthesisPos;
    QStringList innerParenthesisExpression; //the expression inside the parenthesis without ()
    if(!isParenthesis(expressionParts[openingParenthesisPos]))
        throw ExExpressionError("Calculator::parseParenthesis: Parenthesis expected! Found:"
                                + expressionParts[openingParenthesisPos]);
    bool isNegative = expressionParts[openingParenthesisPos] == "-(";

    while(parenthesisCount > 0 && nextParenthesisPos < expressionParts.count() - 1) //find matching closing parenthesis
    {
        nextParenthesisPos++;
        if(expressionParts[nextParenthesisPos] == "(")
            parenthesisCount++;
        else if(expressionParts[nextParenthesisPos] == ")")
            parenthesisCount--;

    }
    //Not enough closing parenthesises until end of list
    if(parenthesisCount > 0)
         throw ExExpressionError(tr("Closing parenthesis missing!"));
    if(nextParenthesisPos == openingParenthesisPos + 1)
        throw ExExpressionError(tr("Empty parenthesis pair."));
    //make the inner expression
    for(int part = openingParenthesisPos + 1; part < nextParenthesisPos; part++)
        innerParenthesisExpression+= expressionParts[part];
    //parse it. This loop will calculate the result and put it into parenthesisExpression[0]
    while(innerParenthesisExpression.count() > 1)
       parseSubexpression(innerParenthesisExpression);
    //finally replace the whole parenthesis expression with its result
    //remove parts backwards from closing parenthesis to opening parenthesis + 1
    for(int toRemove = nextParenthesisPos; toRemove > openingParenthesisPos; toRemove--)
        expressionParts.removeAt(toRemove);
    //replace opening parenthesis with the result
    QString result = innerParenthesisExpression[0];
    if(isNegative) //take care of sign
    {
        if(result[0] != '-')
           result = "-" + result; // add -
        else result = result.right(result.length() -1); //delete -
    }
    expressionParts[openingParenthesisPos] = result;
}
Ejemplo n.º 4
0
/**Changes sign of last term in expression
  */
void Calculator::changeSign()
{
    if(m_ExpressionParts.size() == 0) //first input
    {
        m_ExpressionParts.append("-"); //that's all
        return;
    }

    //we have text, lets see what we have
    QString lastElement = m_ExpressionParts.last();
    m_ExpressionParts.removeLast();
    if(isOperator(lastElement)) //we have an operator
    {
        if(lastElement == "-")
            lastElement = "+";
        else {
           m_ExpressionParts.append(lastElement);
           m_ExpressionParts.append("-"); // * -, / - or + -
        }

    }
    else if(isParenthesis(lastElement)) //process a parenthesis expression as a unit
    {
        if(lastElement == "(" || lastElement == "-(") //opening, positive or negative
            changeGroupSign(m_ExpressionParts.size() - 1, &lastElement);
        else //closing parenthesis, make the whole expression negative
        {
            //search for corresponding opening parenthesis
            int parenthesiscount = 1;
            int pos= m_ExpressionParts.size();
            while (parenthesiscount > 0 && pos > 0)
            {
                pos--;
                if(m_ExpressionParts[pos] == ")")
                    parenthesiscount++;
                if(m_ExpressionParts[pos] == "(" || m_ExpressionParts[pos] == "-(")
                    parenthesiscount--;
            }
            changeGroupSign(pos - 1, &m_ExpressionParts[pos]);
        }
        m_ExpressionParts.append(lastElement); //finally add the parenthesis
    }
    else{ //no operator, no parenthesis: this leaves a number or a variable
        QString exponent;
        int ePos = lastElement.indexOf("E");
        if(ePos > 0) //we have a number with exponent, change sign of exponent
        {
            exponent = lastElement.right(lastElement.length() - ePos - 1);
            if(exponent[0] == '-')
                exponent.remove(0, 1); //remove sign
            else exponent = '-' + exponent; //add sign
            lastElement = lastElement.left(ePos + 1) + exponent;
        }
        else { //number without exponent or variable
            if(lastElement[0] == '-'){
                lastElement.remove(0, 1); //negative number, remove sign
            }
            else if(m_ExpressionParts.size() > 1 && m_ExpressionParts.last() =="-") // "-" operation
                m_ExpressionParts.last() = "+"; //change to "+"
            else if(m_ExpressionParts.size() > 1 && m_ExpressionParts.last() =="+") // "+" operation
                m_ExpressionParts.last() = "-"; //change to "-"
            else lastElement = '-' + lastElement; //add sign to number
        }
        m_ExpressionParts.append(lastElement);
    }
}
Ejemplo n.º 5
0
/** Append text to Expression. Overwrites a trailing operator with the new one, if a sequence of
  * two operators is input.
  * Recognizes and executes C, AC and = commands.
  */
void Calculator::addToExpressionText(const QString & buttonText)
{
    QString text = buttonText;
    try{
        if(text == "C")
            clearLast();
        else if(text == "AC")
            clearAll();
        else if(text == "+/-")
            changeSign();
        else if(text == m_TextRad)
            setAngleMode(text);
        else if(text == m_TextDeg)
            setAngleMode(text);
        else if(text == "=")
        {
            if(isPlotExpression())
                createPlot();
            else parseExpression();
        }
        else if(text=="x")
            addVariable(text);
        else if(text.startsWith("Plot"))
                plotter.processPlotCommand(text);
        else{ //we have a digit, operator or function
            //no clear or evaluate command
            if(text == "x^y") //convert to operator
                text = "^";
            if(isNumber(text)){ //No parenthesis, we have a digit or a decimal separator
                addDigit(text);
                emit guiStateSuggested(STATE_STANDARD); //return to std page, if on Fn Page for entering E
            }
            else if(isOperator(text)) //operator or digit
            {
                addOperator(text);
            }
            else if(isParenthesis(text)) //we have a parenthesis
            {
                addParenthesis(text);
            }
            else if(isFunction(text)) //we have a function
            {
                addFunctionCall(text);
            }
            else if(isVariable(text)) //we have a variable
            {
                addVariable(text);
            }
            else throw ExExpressionError(tr("Unknown command:") + text);

        } //end digit operator or function

        m_ExpressionText = m_ExpressionParts.join("");
        if(isPlotExpression())
            emit expressionTextChanged("y=" + m_ExpressionText);
        else emit expressionTextChanged(m_ExpressionText);
    } //end try
    catch(ExExpressionError e)
    {
        emit guiStateSuggested(STATE_STANDARD);
        emit errorMessage(tr("Input Error"),e.what());
    }
    catch(std::exception e)
    {
        emit guiStateSuggested(STATE_STANDARD);
        emit errorMessage(tr("Unknown Input Error"),e.what());
    }
}
/*
* Prototype: int parseExpression(const std::string&)

* What: This method converts the expression (entered in postfix notation) to prefix notation, Reverse Polish Notation (RPN).

* How to Call: This method is called in the main function in the test file.
ex: Calculator myCalc; std::string myExpression; myCalc.parseExpression(myExpression);

* Pre-Conditions:
- A Calculator object must have been built.
- User must pass in an expression.

* Post-Conditions:
- Expression will be parsed into RPN and stored in the member container: Queue<std::string> output
- Will call the function evaluateExpression() and return an int to either signify a successful calculation, or and error (e.g., division by zero, mismatched parentheses, etc.).
*/
int Calculator::parseExpression(std::string& expression)
{
	expression = checkForUnaryMinus(expression);
	for (size_t i = 0; i < expression.length(); i++)
	{
		const std::string token = expression.substr(i, 1);

		if (token == " ") // If space, skip iteration and throw it out.
			continue;

		else if (token == "u")
		{
			std::string newToken = "-";
			i++; // Skip over the u
			while (i < expression.length() && !isOperator(expression.substr(i, 1)) && !isParenthesis(expression.substr(i, 1)))
				newToken.append(expression.substr(i++, 1));
			i--; // For loop will increment i, causing it to skip over operators and such, so decrement i here
			output.enqueue(newToken);
		}

		else if (isOperator(token))
		{
			if (!operators.empty())
			{
				std::string op2 = operators.top();

				while (isOperator(op2) && ((isLeftAssoc(token) && checkPrecedence(token, op2) == 1) || (checkPrecedence(token, op2) == 0)))
				{
					output.enqueue(op2);
					operators.pop();

					if (!operators.empty())
						op2 = operators.top();
					else
						break;
				}
			}
			operators.push(token);
		}

		else if (isParenthesis(token))
		{
			if (token == "(")
				operators.push(token);
			else
			{
				if (!operators.empty())
				{
					std::string top = operators.top();

					while (top != "(")
					{
						output.enqueue(top);
						operators.pop();
						if (operators.empty())
							break; // Mismatched Parentheses

						top = operators.top();
					}

					if (!operators.empty()) // You've found the left parenthesis!
						operators.pop();
					if (top != "(")
						return 1; // Mismatched Parentheses
				}
			}
		}

		else if (isNumber(token))
		{
			std::string newToken;
			while (i < expression.length() && !isOperator(expression.substr(i, 1)) && !isParenthesis(expression.substr(i, 1)))
				newToken.append(expression.substr(i++, 1));
			i--; // For loop will increment i, causing it to skip over operators and such, so decrement i here
			output.enqueue(newToken);
		}

		else
			return 5; // Invalid character
	}

	while (!operators.empty())
	{
		std::string top = operators.top();

		if (isParenthesis(top))
			return 1; // Mismatched Parentheses

		output.enqueue(top);
		operators.pop();
	}

	return (evaluateExpression());
}