acceptance by empty stack
The second way a pushdown automaton can declare success ignores the control state entirely and watches the stack instead. Under acceptance by empty stack, the machine accepts a string if, after reading all of the input, it has managed to pop its stack completely empty — including the initial symbol Z0. The state it ends in does not matter at all; emptying the stack IS the signal of success.
Formally, the machine accepts input w by empty stack if the starting ID (q0, w, Z0) yields, in zero or more steps, some ID (p, ε, ε): all input consumed (the second ε) and the stack drained to nothing (the third ε), with the final state p completely irrelevant. There is a subtlety worth knowing: once the stack is truly empty, the machine is stuck — no transition can fire because every PDA move needs a top symbol to pop. So emptying the stack is naturally a terminal event, which is exactly why it works as an acceptance condition.
This mode is especially convenient when you turn a grammar into a PDA: the natural construction builds a machine that simulates a derivation on its stack and, when the derivation is complete and the input matches, has emptied the stack. It is the mode where 'the counting cancelled out perfectly' is literally visible as 'the stack is gone'. As with the final-state mode, this is neither stronger nor weaker — the languages accepted by empty stack are exactly the context-free languages.
An a^n b^n machine accepting by empty stack: it even pops Z0 with the final b (or with a closing ε-move). On aabb it ends with an empty stack and input consumed, so it accepts; on aab a leftover marker keeps the stack nonempty, so it does not.
Accept if input is fully read and the stack is drained empty — final state irrelevant.
Emptying the stack is irreversible: with no top symbol, no transition can fire, so the machine cannot continue. This makes empty-stack acceptance a one-shot, terminal condition by its very nature.