8#include "InfixToPostfix.h"
12#include "IException.h"
23 InfixToPostfix::~InfixToPostfix() {
90 for(
int i = 0; i < p_operators.size(); i ++) {
91 delete p_operators[i];
110 IString equationIStr = equation;
112 while(!equationIStr.empty()) {
145 std::stack<InfixOperator> theStack;
149 int numConsecutiveOperands = 0;
153 int numConsecutiveOperators = 0;
158 while(!equation.empty()) {
162 QString data = equation.
Token(
" ").
ToQt();
164 if(data.compare(
"(") == 0) {
167 else if(data.compare(
")") == 0) {
168 QString postfixQStr = postfix.ToQt();
170 postfix = postfixQStr;
173 QString postfixQStr = postfix.ToQt();
175 postfix = postfixQStr;
181 numConsecutiveOperators = 0;
182 numConsecutiveOperands ++;
186 numConsecutiveOperators = 1;
187 numConsecutiveOperands = 0;
192 numConsecutiveOperators ++;
193 numConsecutiveOperands = 0;
203 "The operator '" + data +
"' is not recognized.",
208 numConsecutiveOperators = 0;
209 numConsecutiveOperands ++;
211 postfix +=
IString(
' ' + data +
' ');
215 if(numConsecutiveOperators > 1) {
218 else if(numConsecutiveOperands > 1) {
223 while(!theStack.empty()) {
224 IString op = theStack.top().outputString();
229 "There are too many opening parentheses ('(') in the equation.",
233 postfix +=
' ' + op +
' ';
239 postfix = postfix.Remove(
",");
254 for(
int i = 0; i < p_operators.size(); i++) {
255 if(representation.compare(p_operators[i]->inputString()) == 0) {
288 while(!theStack.empty()) {
292 if(top.inputString().compare(
"(") == 0) {
297 if(top.precedence() < op.precedence()) {
302 postfix +=
' ' + top.outputString() +
' ';
317 bool openingFound =
false;
318 while(!theStack.empty()) {
322 if(op.inputString().compare(
"(") == 0) {
327 postfix +=
' ' + op.outputString() +
' ';
333 "There are too many closing parentheses (')') in the equation.",
348 for(
int i = 0; i < p_operators.size(); i++) {
349 if(representation.compare(p_operators[i]->inputString()) == 0) {
350 return p_operators[i];
374 for(
int i = 0; i < equation.size(); i++) {
376 if(!equation[i].isLetterOrNumber() && !equation[i].isSpace() &&
377 equation[i] !=
'.' && equation[i] !=
'_') {
379 if(equation[i] ==
'[' || equation[i] ==
'{') {
382 else if(equation[i] ==
']' || equation[i] ==
'}') {
386 else if(i < equation.size() - 1 && equation[i] ==
'-' && equation[i+1] ==
'-') {
390 else if(i < equation.size() - 1 && equation[i] ==
'<' && equation[i+1] ==
'<') {
394 else if(i < equation.size() - 1 && equation[i] ==
'>' && equation[i+1] ==
'>') {
398 else if(i < equation.size() - 1 && equation[i] ==
'>' && equation[i+1] ==
'=') {
402 else if(i < equation.size() - 1 && equation[i] ==
'<' && equation[i+1] ==
'=') {
406 else if(i < equation.size() - 1 && equation[i] ==
'=' && equation[i+1] ==
'=') {
410 else if(i < equation.size() - 1 && equation[i] ==
'!' && equation[i+1] ==
'=') {
414 else if(i < equation.size() - 1 && equation[i] ==
'|' && equation[i+1] ==
'|') {
418 else if(i < equation.size() - 1 && equation[i] ==
'&' && equation[i+1] ==
'&') {
423 else if((i > 1) && equation[i] ==
'-' && equation[i-1].toLower() ==
'e' && equation[i-2].isLetterOrNumber()) {
424 output += equation[i].toLatin1();
427 else if(equation[i] ==
'-') {
428 bool isNegative =
true;
431 for(
int index = i - 1; index >= 0; index --) {
432 if(equation[index] ==
' ') {
436 if(equation[index] !=
'(' && equation[index] !=
'/' &&
437 equation[index] !=
'*' && equation[index] !=
'+') {
454 output += equation[i].toLatin1();
459 output += equation[i].toLatin1();
465 return cleanedEquation;
486 while(!equation.isEmpty()) {
489 QString element = tmp.Token(
" ").ToQt();
490 equation = tmp.ToQt();
500 output +=
" ( " + func->inputString() +
" (";
503 if(func->argumentCount() == 0) {
505 QString next = tmp.Token(
" ").ToQt();
506 equation = tmp.ToQt();
515 equation = next +
" " + equation;
521 if(tmp.Token(
" ") !=
")") {
523 "The function " + func->inputString() +
" should not have any arguments.",
526 equation = tmp.ToQt();
538 if (func->argumentCount() > 1 && tmp.Token(
" ") !=
"(") {
540 "Missing parenthesis after " + func->inputString(),
544 equation = tmp.ToQt();
547 if(func->argumentCount() == 1) {
550 QString argument = tmp.Token(
" ").ToQt();
551 equation = tmp.ToQt();
553 if(argument !=
"(") {
557 if(func->inputString() !=
"--") {
559 "Missing parenthesis after " + func->inputString(),
572 QString functionName = argument;
575 QString openParen = tmp.Token(
" ").ToQt();
576 equation = tmp.ToQt();
579 if(openParen !=
"(") {
581 equation = openParen +
" " + equation;
585 functionName +=
" (";
591 while(numParens > -1) {
593 QString newElem = tmp.Token(
" ").ToQt();
594 equation = tmp.ToQt();
598 "Missing closing parentheses after '" + argument +
"'.",
602 if(newElem ==
"(") numParens++;
603 else if(newElem ==
")") numParens--;
605 functionName +=
" " + newElem;
623 QString argument =
"";
626 while(argNum < func->argumentCount()) {
628 QString elem = tmp.Token(
" ").ToQt();
629 equation = tmp.ToQt();
634 "The definition of '" + func->inputString() +
"' is not complete.",
642 else if(elem ==
")") {
646 if(numParens != -1) {
650 else if(elem ==
"," && numParens == 0) {
651 checkArgument(func->inputString(), argNum, argument);
653 output +=
" ( " + argument +
" ) , ";
658 if(argNum == func->argumentCount()) {
660 "There were too many arguments supplied to the function '" + func->inputString() +
"'.",
665 argument +=
" " + elem;
668 if(argNum == func->argumentCount() - 1 && numParens == -1) {
669 checkArgument(func->inputString(), argNum, argument);
672 output +=
" " + argument +
" ) ) ";
677 else if(numParens == -1) {
679 "There were not enough arguments supplied to the function '" + func->inputString() +
"'.",
687 output = output +
" " + element;
694 void InfixToPostfix::checkArgument(QString funcName,
int argNum, QString argument) {
695 argument = argument.remove(QRegExp(
"[ ()]"));
699 "Argument " +
toString(argNum + 1) +
" in function " + funcName +
" must not be empty.",
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Adds specific functionality to C++ strings.
IString Token(const IString &separator)
Returns the first token in the IString.
QString ToQt() const
Retuns the object string as a QString.
InfixOperator and InfixFunction are helper classes for InfixToPostfix.
InfixOperator and InfixFunction are helper classes for InfixToPostfix.
virtual InfixOperator * findOperator(QString representation)
This method will return a pointer to the operator represented by 'representation.
QString convert(const QString &infix)
This method converts infix to postfix.
bool isFunction(QString representation)
This method will return true if 'representation' is a known function.
QString cleanSpaces(QString equation)
This function takes a space-delimited string and removes empty delimiters.
void initialize()
This populates the known operators/functions list.
virtual bool isKnownSymbol(QString representation)
This method will return true if it believes the argument represents a valid function or operator.
void uninitialize()
This cleans the known operators/functions list.
InfixToPostfix()
Constructor.
QString tokenizeEquation(const QString &equation)
This method will add spaces between all operators and numbers, making it possible to get each element...
void closeParenthesis(QString &postfix, std::stack< InfixOperator > &theStack)
This is straight from the algorithm found on page 159 of "Data Structures & Algorithms in Java" Secon...
void addOperator(QString &postfix, const InfixOperator &op, std::stack< InfixOperator > &theStack)
This is straight from the algorithm found on page 159 of "Data Structures & Algorithms in Java" Secon...
QString formatFunctionCalls(QString equation)
This method looks through equation for function calls, parenthesizes them, and calls itself again wit...
This is free and unencumbered software released into the public domain.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
double toDouble(const QString &string)
Global function to convert from a string to a double.
Namespace for the standard library.