I'm trying to implement this right-to-left evaluation algorithm of a postfix expression but I can't seem to get it to work.
for each token in the reversed postfix expression:
if token is an operator:
push token onto the operator stack
pending_operand ← False
else if token is an operand:
operand ← token
if pending_operand is True:
while the operand stack is not empty:
operand_1 ← pop from the operand stack
operator ← pop from the operator stack
operand ← evaluate operator with operand_1 and operand
push operand onto the operand stack
pending_operand ← True
result ← pop from the operand stack
From wikipedia.
This is how the steps are illustrated:
15 7 1 1 + − ÷ 3 × 2 1 1 + + − =
15 7 1 1 + − ÷ 3 × 2 2 + − =
15 7 1 1 + − ÷ 3 × 4 − =
15 7 2 − ÷ 3 × 4 − =
15 5 ÷ 3 × 4 − =
3 3 × 4 − =
9 4 − =
5
I don't really get how this follows from the algorithm. I keep getting the wrong answer trying to evaluate the expression 15 7 1 1 + − ÷ 3 × 2 1 1 + + −
(should be 5
). I've spent hours trying to get it working in assembly and I tried manually going through it but I keep getting the wrong answer. I think part of if lies in , ruled out. Anyways, I threw together this piece of JavaScript to show my interpretation of the algorithm, since it's way clearer than assembly.operate(operand_1, operand)
const rpn = [15, 7, 1, 1, '+', '-', '/', 3, '*', 2, 1, 1, '+', '+', '-'];
const operator_Stack = [];
const operand_Stack = [];
let pending = false;
for (i = rpn.length - 1; i >= 0; i--) {
const token = rpn[i];
if (typeof token === "string") {
operator_Stack.push(token);
pending = false;
} else {
let operand = token;
if (pending) {
while (operand_Stack.length > 0) {
let operand_1 = operand_Stack.pop();
let operator = operator_Stack.pop();
let expr = operand + " " + operator + " " + operand_1;
console.log(expr);
operand = eval(expr);
}
}
operand_Stack.push(operand);
pending = true;
}
}
console.log("The expression evaluates to: " + operand_Stack.pop());
This evaluates the following expression in the following order:
"1 + 1"
"2 + 2"
"1 + 1"
"2 - 3"
"-1 / 4"
"7 * -0.25"
"15 - -1.75"
The first three evaluations appear to be correct. Then things start to go wrong.
As a binary tree 15 7 1 1 + − ÷ 3 × 2 1 1 + + −
would look like this
[-]
/ \
[*] [+]
/ \ / \
[/] [3] [2] [+]
/ \ / \
[15] [-] [1] [1]
/ \
[7] [+]
/ \
[1] [1]
The correct order of evaluation should be:
1 + 1
2 + (1 + 1)
1 + 1
7 - (1 + 1)
15 / (7 - 2)
3 * (15 / 5)
9 - 4
To me, my JavaScript code implements the algorithm as it's stated. Yet obviously it's not correct. As I see there are two possibilities, the algorithm is wrong or, more likely, my interpretation is. Problem is, I can't figure out which of the two it is.
What is it that I'm missing?