Concepts / Stacks: Push and Pop Operations

Stacks: Push and Pop Operations

A stack-based evaluation algorithm can detect errors in a postfix expression without needing parentheses or a human reader.

  • Programming

Catching Mistakes Without Reading the Expression

A postfix expression places each operator after the operands it works on. Because of this placement, an expression can be evaluated from left to right using a stack, with no parentheses needed. The same structure also makes certain mistakes easy to catch. A stack-based evaluation algorithm can reject a malformed expression on its own, without a person reading it.

Two kinds of malformed input are worth studying. In the first, an operator appears with too few operands before it. In the second, operands are left over with too few operators after them. Both expressions look close to valid input, and both are caught by the same algorithm. The question this article answers is when the algorithm knows something is wrong, and which kind of error it has found at that moment.

Tracing the Stack Token by Token

The algorithm reads the expression one token at a time. Each number is pushed onto the stack. Each operator takes its operands from the top of the stack: it pops two values, combines them, and pushes the result back. The stack is the only place where values wait, so its contents at each step show whether the expression is still consistent.

Worked example

Tracing the faulty expression 2 3 + *

Evaluate the postfix expression 2 3 + * with the stack algorithm and state where the error is detected.

  1. 1
    Push 2 and push 3

    Both numbers are legal on their own, so each one is pushed. The stack now holds 2 and 3, with 3 on top.

  2. 2
    Read the plus operator

    The plus operator pops two values, 3 and 2, adds them, and pushes 5 back. The stack now holds only 5.

  3. 3
    Read the multiplication operator

    This operator also needs two values. It pops 5, which succeeds, and then tries to pop a second value from an empty stack. The + consumed both numbers, so there is no second operand left.

  4. 4
    State where the error is found

    The error is an insufficient operands error. It is detected during processing, at the multiplication operator, not after the last token.

Result

Insufficient operands error, detected while processing the final operator *.

Insufficient Operands: Caught During Processing

An insufficient operands error is detected when an operator tries to pop its second operand from an empty stack. Each operator needs two values, so before it acts, the algorithm checks that the stack can supply them. The check happens while the operator is being processed, which is why this error is found earlier than the other kind.

The diagram shows the decision that matters. For a number, the algorithm pushes it and moves on. For an operator, it checks whether the stack holds two values. If it does, the operator pops both, combines them, and pushes the result. If it does not, the algorithm stops with an insufficient operands error. In the faulty expression 2 3 + *, the operator that fails is the multiplication, because the plus has already reduced the stack to a single value.

Insufficient Operators: Caught at the End

An insufficient operators error is detected when values remain on the stack at the end of the algorithm. A valid expression reduces to exactly one value once every token has been read. If more than one value is still on the stack, there were not enough operators to combine all the operands, and the error is found only at this final checkpoint.

Consider 2 3 4 +. Every token is legal on its own: three numbers and one operator. The plus pops only the two numbers on top, 4 and 3, and pushes 7. The number 2 at the bottom is left over, so the stack ends with two values. No operator ever failed, so the algorithm cannot catch this mistake until all tokens have been read.

What do you think happens?

In the expression 2 3 4 +, does any operator fail while the tokens are being read, or is the error found only after the last token?

  • An operator fails during processing

  • The error is found only after the last token

Reveal answer
Answer:

The error is found only after the last token

The plus operator always finds two values, so it never fails. The stack still holds 2 and 7 when reading ends, and that leftover value is what reveals the error.

Mistakes When Locating Each Error

  • Common mistake

    Assuming every faulty expression fails at the last token

    What it looks like

    In 2 3 + *, the error is found at the multiplication operator, which is not the last token in a sense that matters: the stack check fails there, during processing.

    Why it fails

    Insufficient operands errors are found during processing, when an operator cannot pop its second operand.

    Do this instead

    Check each operator as it is read. If it cannot pop two values, stop at that operator.

  • Common mistake

    Thinking that a stack holding several values during processing is always an error

    What it looks like

    After reading 2 and 3 in 2 3 + *, the stack holds two values, which is perfectly normal.

    Why it fails

    Operands are supposed to wait on the stack until an operator uses them. Extra values are only a problem if they remain at the end.

    Do this instead

    Only check the stack size at the end for an insufficient operators error, and check the operand count at each operator for an insufficient operands error.

  • Common mistake

    Expecting an insufficient operators error to be caught while an operator runs

    What it looks like

    In 2 3 4 +, the plus operator runs without any problem.

    Why it fails

    The plus always finds two values, so no operator fails. The leftover 2 is only visible once reading has ended.

    Do this instead

    Look for an insufficient operators error after the final token, by counting the values still on the stack.

Comparing a Valid and a Faulty Trace

The same algorithm handles valid and faulty input. The only difference is what the stack looks like at the moment of the operator check or at the end of reading. The table below places the three expressions side by side. The first two come from the source, and the valid expression 2 3 + 4 * is a generated contrast example.

ExpressionWhere the stack ends or failsError typeCheckpoint
2 3 + 4 * (valid)One value, 20NoneFinal stack holds exactly one value
2 3 + * (faulty)Fails at the multiplication, after popping 5Insufficient operandsDuring processing, at the operator
2 3 4 + (faulty)Two values, 2 and 7Insufficient operatorsAfter the last token

Three traces under the same stack algorithm. The valid expression ends with one value, and each faulty expression is caught at a different checkpoint.

Practice Tracing a Faulty Expression

EASY

Trace the postfix expression 1 2 + + with the stack algorithm. State which error type occurs, the token where it is detected, and the stack contents just before that token.

Hints
  • After reading 1 and 2, what is on the stack, and what does the first plus do to it?
  • When the second plus arrives, how many values does the stack hold?
  • Decide whether the error is found during processing or only after the last token.

Summary

At a glance

  • A stack-based evaluation algorithm reads a postfix expression one token at a time, pushing numbers and having each operator pop two values, combine them, and push the result.
  • An insufficient operands error is detected during processing, when an operator tries to pop its second operand from an empty stack.
  • An insufficient operators error is detected after the last token, when more than one value still remains on the stack.
  • Trace the stack token by token to find the exact checkpoint where an error appears, and state which error type it is.