/** * Parse a subexpression and replace it with its result. */ void Calculator::parseSubexpression(QStringList & expressionParts) { int operatorLine = 0; int prioLine = 0; int priority = 0; int parenthesisPos = 0; int functionLine = 0; for(parenthesisPos = 0; parenthesisPos < expressionParts.size(); parenthesisPos++) if((expressionParts[parenthesisPos]== "(") || (expressionParts[parenthesisPos]=="-(")) parseParenthesis(expressionParts, parenthesisPos); else if(expressionParts[parenthesisPos]== ")"){ throw ExExpressionError(tr("Parenthesis syntax error.")); } if(expressionParts.size() < 2) //evaluation is complete, we had a (Expression) return; //now we have all function arguments directly behind the function name if(!(isNumber(expressionParts.last()) || isVariable(expressionParts.last()))) throw ExExpressionError(tr("Last term of expression must be a number.")); //evaluate function values from right to left for(functionLine = expressionParts.size() - 1; functionLine > -1; functionLine--) if(isFunction(expressionParts[functionLine])) evaluateFunction(expressionParts, functionLine); while(operatorLine < expressionParts.size() &&! isOperator(expressionParts[operatorLine])) operatorLine ++; if(operatorLine >= expressionParts.size() - 1) //no operator, invalid expression or nothing to be done throw ExExpressionError(tr("Missing operator.")); //we found an operator, now search for the first operator with highest priority prioLine = operatorLine; priority = operatorPriority(expressionParts[operatorLine]); while( prioLine < expressionParts.size() - 1 ) { prioLine ++; if(operatorPriority(expressionParts[prioLine]) > priority) { operatorLine = prioLine; priority = operatorPriority(expressionParts[prioLine]); } } //Now lets calculate if(operatorLine < 1) //we have a leading operator { if(expressionParts[operatorLine] == "-" | expressionParts[operatorLine] == "+") //we have a sign { if(expressionParts[operatorLine] == "-") expressionParts[0] = expressionParts[0] + expressionParts[1]; //make a negative number expressionParts.removeAt(1); //and delete the sign from list return; } else throw ExExpressionError(tr("No operator allowed in first position.")); } calculateSubExpression(expressionParts, operatorLine); }
bool SizesCalcParser::handleOperator(Vector<CSSParserToken>& stack, const CSSParserToken& token) { // If the token is an operator, o1, then: // while there is an operator token, o2, at the top of the stack, and // either o1 is left-associative and its precedence is equal to that of o2, // or o1 has precedence less than that of o2, // pop o2 off the stack, onto the output queue; // push o1 onto the stack. bool stackOperatorPriority; bool incomingOperatorPriority; if (!operatorPriority(token.delimiter(), incomingOperatorPriority)) return false; if (!stack.isEmpty() && stack.last().type() == DelimiterToken) { if (!operatorPriority(stack.last().delimiter(), stackOperatorPriority)) return false; if (!incomingOperatorPriority || stackOperatorPriority) { appendOperator(stack.last()); stack.removeLast(); } } stack.append(token); return true; }