Impix or reverse polish notation
I am currently working on a (Windows GUI) calculator that accepts impix notation and (hopefully) will contain most of the features of a standard scientific calculator (like sin, cos and tan) w/ the eventual aim being for it to do calculus. However the first objective is to perform standard operations.
I was wondering if it would be easier to work completely in impix or convert impix into reverse polish. Richie & Kerrigan provide algorithms for working in reverse polish but don't mention the shunting yard algorithm or conversion between these two notations. If it is easier to work in impix then how would this be achieved, remember the program needs to work w/ brackets and numbers more than one digit. Otherwise, I need help w/ my 'Shunting yard algorithm' as follows, which gives afew warnings:
Code:
//Pass in inputqueue for reading, and outputqueue for writing
char ConvertToPolishNotation(char inputqueue[], char outputqueue[]) {
int length = sizeof(inputqueue);
char operatorqueue[50];
int i, counter = 0;
for (i=0;i<length; i++) { //Read token
if ((inputqueue[i] >= '0') && (inputqueue[i] <= '9')) //NUMBER
pushelement(inputqueue[i], outputqueue);
else if ((inputqueue[i] < 42) || (inputqueue[i] > 45)
&& (inputqueue[i] != 47) && (inputqueue[i] != 94)) //OPERATOR
pushelement(inputqueue[i], operatorqueue);
else if (inputqueue[i] == 40) //BRACKET
pushelement(inputqueue[i], operatorqueue);
else if (inputqueue[i] == 41) {//BRACKET
while ((strcmp(operatorqueue[counter],"(") != 0) && (counter < 50)) {
//Until the token at the top of the stack is a left parenthesis,
//pop operators off the stack onto the output queue
outputqueue[i+1] = popelement(counter, operatorqueue);
counter++;
} //ENDWHILE
if (counter == 50) { //BRACKET MISMATCH
MessageBox(NULL, "Bracket Mismatch", "Error", MB_OK);
return 0;
}
//Pop the left parenthesis from the stack, but not onto the output queue.
popelement(counter, operatorqueue);
} //END BRACKET
} //NO MORE TOKENS
counter = 0;
//While there are still operator tokens in the stack:
while (strcmp(operatorqueue[counter], "") != 0) {
if ((operatorqueue[counter] == ")") || (operatorqueue[counter] == "(")) {//BRACKET
MessageBox(NULL, "Bracket Mismatch", "Error", MB_OK);
return 0;
}
outputqueue[i] = popelement(counter, operatorqueue);
}
return &outputqueue;
}
What I don't think I have accounted for:
1. Operator preceedance
2. Working w/ digits > 9
3. Functions (like sin x etc.)
Warnings: return makes integer from pointer without a cast, function returns address of local variable. Also, sorry for the long post & I wasn't sure whether I should put this in Windows Programming, but I figured this would be alright as it doesn't require any windows-only function calls.
Still having trouble, Please help!
Sorry for double posting, but I am still stuck. I have found what is going wrong and what needs to be fixed though, so I have only included the lines where the problem occurs. The first problem is that *lastwritteninoq is meant to point to the last element, but instead points to the first so the operator gets placed at the begining of the list instead of the end. The second problem is that left brackets don't get removed from the operator queue. After these two problems are fixed, then the function should be finished.
Code:
while (*currentpointer != '\0') { /*or whatever your end of input is*/
if (isdigit(*currentpointer)) {
*lastwritteninoq++ = *currentpointer;
currentpointer++;
} /*or if you're reading an entire number, += number_of_digits_read */
else if (*currentpointer=='+' || *currentpointer == '-' ||
*currentpointer=='*' || *currentpointer == '/') {
*oqpointer++ = *currentpointer;
currentpointer++;
}
else if (*currentpointer=='(') {//Push it onto stack
*oqpointer++ = *currentpointer;
currentpointer++;
}
else if (*currentpointer==')') {
while ((*oqpointer != '(') && (*currentpointer != '\0')
&& (counter < 50)) {
//Until the token at the top of the stack is a left parenthesis,
//pop operators off the operator stack onto the output queue
outputqueue[*lastwritteninoq] = *--oqpointer;
counter++;
lastwritteninoq++;
currentpointer++;
}
if (counter == 50) { //BRACKET MISMATCH
MessageBox(NULL, "Bracket Mismatch", "Error", MB_OK);
return -1;
}
//This line is meant to pop the left bracket from the stack, but not onto the output queue, but doesn't work
*--oqpointer;
} //END BRACKET