34 InfixToPostfix::InfixToPostfix() {
38 InfixToPostfix::~InfixToPostfix() {
46 void InfixToPostfix::initialize() {
104 void InfixToPostfix::uninitialize() {
105 for(
int i = 0; i < p_operators.size(); i ++) {
106 delete p_operators[i];
124 QString InfixToPostfix::cleanSpaces(QString equation) {
125 IString equationIStr = equation;
127 while(!equationIStr.empty()) {
154 QString InfixToPostfix::convert(
const QString &infix) {
156 IString equation = tokenizeEquation(infix);
160 std::stack<InfixOperator> theStack;
164 int numConsecutiveOperands = 0;
168 int numConsecutiveOperators = 0;
173 while(!equation.empty()) {
177 QString data = equation.
Token(
" ").
ToQt();
179 if(data.compare(
"(") == 0) {
180 theStack.push(*findOperator(data));
182 else if(data.compare(
")") == 0) {
183 QString postfixQStr = postfix.
ToQt();
184 closeParenthesis(postfixQStr, theStack);
185 postfix = postfixQStr;
187 else if(isKnownSymbol(data)) {
188 QString postfixQStr = postfix.
ToQt();
189 addOperator(postfixQStr, *findOperator(data), theStack);
190 postfix = postfixQStr;
192 if(isFunction(data)) {
195 if(((
InfixFunction *)findOperator(data))->argumentCount() == 0) {
196 numConsecutiveOperators = 0;
197 numConsecutiveOperands ++;
201 numConsecutiveOperators = 1;
202 numConsecutiveOperands = 0;
207 numConsecutiveOperators ++;
208 numConsecutiveOperands = 0;
218 "The operator '" + data +
"' is not recognized.",
223 numConsecutiveOperators = 0;
224 numConsecutiveOperands ++;
226 postfix +=
IString(
' ' + data +
' ');
230 if(numConsecutiveOperators > 1) {
231 throw IException(IException::User,
"Missing an operand near the operator '" + data +
"'.",
_FILEINFO_);
233 else if(numConsecutiveOperands > 1) {
238 while(!theStack.empty()) {
239 IString op = theStack.top().outputString();
244 "There are too many opening parentheses ('(') in the equation.",
248 postfix +=
' ' + op +
' ';
254 postfix = postfix.
Remove(
",");
257 return cleanSpaces(postfix.
ToQt());
268 bool InfixToPostfix::isKnownSymbol(QString representation) {
269 for(
int i = 0; i < p_operators.size(); i++) {
270 if(representation.compare(p_operators[i]->inputString()) == 0) {
285 bool InfixToPostfix::isFunction(QString representation) {
286 if(isKnownSymbol(representation)) {
287 return findOperator(representation)->isFunction();
302 void InfixToPostfix::addOperator(QString &postfix,
const InfixOperator &op, std::stack<InfixOperator> &theStack) {
303 while(!theStack.empty()) {
307 if(top.inputString().compare(
"(") == 0) {
312 if(top.precedence() < op.precedence()) {
317 postfix +=
' ' + top.outputString() +
' ';
331 void InfixToPostfix::closeParenthesis(QString &postfix, std::stack<InfixOperator> &theStack) {
332 bool openingFound =
false;
333 while(!theStack.empty()) {
337 if(op.inputString().compare(
"(") == 0) {
342 postfix +=
' ' + op.outputString() +
' ';
348 "There are too many closing parentheses (')') in the equation.",
363 for(
int i = 0; i < p_operators.size(); i++) {
364 if(representation.compare(p_operators[i]->inputString()) == 0) {
365 return p_operators[i];
370 throw IException(IException::User,
"The operator '" + representation +
"' is not recognized.",
_FILEINFO_);
384 QString InfixToPostfix::tokenizeEquation(
const QString &equation) {
389 for(
int i = 0; i < equation.size(); i++) {
391 if(!equation[i].isLetterOrNumber() && !equation[i].isSpace() && equation[i] !=
'.') {
393 if(equation[i] ==
'[' || equation[i] ==
'{') {
396 else if(equation[i] ==
']' || equation[i] ==
'}') {
400 else if(i < equation.size() - 1 && equation[i] ==
'-' && equation[i+1] ==
'-') {
404 else if(i < equation.size() - 1 && equation[i] ==
'<' && equation[i+1] ==
'<') {
408 else if(i < equation.size() - 1 && equation[i] ==
'>' && equation[i+1] ==
'>') {
412 else if(i < equation.size() - 1 && equation[i] ==
'>' && equation[i+1] ==
'=') {
416 else if(i < equation.size() - 1 && equation[i] ==
'<' && equation[i+1] ==
'=') {
420 else if(i < equation.size() - 1 && equation[i] ==
'=' && equation[i+1] ==
'=') {
424 else if(i < equation.size() - 1 && equation[i] ==
'!' && equation[i+1] ==
'=') {
429 else if((i > 1) && equation[i] ==
'-' && equation[i-1].toLower() ==
'e' && equation[i-2].isLetterOrNumber()) {
430 output += equation[i].toAscii();
433 else if(equation[i] ==
'-') {
434 bool isNegative =
true;
437 for(
int index = i - 1; index >= 0; index --) {
438 if(equation[index] ==
' ') {
442 if(equation[index] !=
'(' && equation[index] !=
'/' &&
443 equation[index] !=
'*' && equation[index] !=
'+') {
460 output += equation[i].toAscii();
465 output += equation[i].toAscii();
469 QString cleanedEquation = cleanSpaces(formatFunctionCalls(output.
DownCase().
ToQt()));
471 return cleanedEquation;
485 QString InfixToPostfix::formatFunctionCalls(QString equation) {
487 equation = cleanSpaces(equation);
492 while(!equation.isEmpty()) {
496 equation = tmp.
ToQt();
499 if(isFunction(element)) {
506 output +=
" ( " + func->inputString() +
" (";
509 if(func->argumentCount() == 0) {
512 equation = tmp.
ToQt();
521 equation = next +
" " + equation;
527 if(tmp.
Token(
" ") !=
")") {
529 "The function " + func->inputString() +
" should not have any arguments.",
532 equation = tmp.
ToQt();
544 if (func->argumentCount() > 1 && tmp.
Token(
" ") !=
"(") {
546 "Missing parenthesis after " + func->inputString(),
550 equation = tmp.
ToQt();
553 if(func->argumentCount() == 1) {
556 QString argument = tmp.
Token(
" ").
ToQt();
557 equation = tmp.
ToQt();
559 if(argument !=
"(") {
563 if(func->inputString() !=
"--") {
565 "Missing parenthesis after " + func->inputString(),
570 if(!isFunction(argument)) {
572 output +=
" " + formatFunctionCalls(argument) +
" ) ) ";
578 QString functionName = argument;
581 QString openParen = tmp.
Token(
" ").
ToQt();
582 equation = tmp.
ToQt();
585 if(openParen !=
"(") {
586 output +=
" " + formatFunctionCalls(functionName) +
" ) ) ";
587 equation = openParen +
" " + equation;
591 functionName +=
" (";
597 while(numParens > -1) {
600 equation = tmp.
ToQt();
604 "Missing closing parentheses after '" + argument +
"'.",
608 if(newElem ==
"(") numParens++;
609 else if(newElem ==
")") numParens--;
611 functionName +=
" " + newElem;
614 output +=
" " + formatFunctionCalls(functionName) +
" ) ) ";
629 QString argument =
"";
632 while(argNum < func->argumentCount()) {
635 equation = tmp.
ToQt();
640 "The definition of '" + func->inputString() +
"' is not complete.",
648 else if(elem ==
")") {
652 if(numParens != -1) {
656 else if(elem ==
"," && numParens == 0) {
657 checkArgument(func->inputString(), argNum, argument);
658 argument = formatFunctionCalls(argument);
659 output +=
" ( " + argument +
" ) , ";
664 if(argNum == func->argumentCount()) {
666 "There were too many arguments supplied to the function '" + func->inputString() +
"'.",
671 argument +=
" " + elem;
674 if(argNum == func->argumentCount() - 1 && numParens == -1) {
675 checkArgument(func->inputString(), argNum, argument);
676 argument = formatFunctionCalls(argument);
678 output +=
" " + argument +
" ) ) ";
683 else if(numParens == -1) {
685 "There were not enough arguments supplied to the function '" + func->inputString() +
"'.",
693 output = output +
" " + element;
700 void InfixToPostfix::checkArgument(QString funcName,
int argNum, QString argument) {
701 argument = argument.remove(QRegExp(
"[ ()]"));
705 "Argument " +
toString(argNum + 1) +
" in function " + funcName +
" must not be empty.",