acceptance by final state
There are two ways to decide that a pushdown automaton has accepted a string, and the first is the familiar one inherited from finite automata: look at where the control ends up. Under acceptance by final state, the machine accepts a string if, after reading all of the input, the finite control is sitting in one of the designated accepting states F — regardless of what is left on the stack.
Formally, the machine accepts input w by final state if the starting ID (q0, w, Z0) yields, in zero or more steps, some ID (p, ε, γ) where p is in F. Read the three parts of that target: ε means all input has been consumed, p in F means the control is in an accepting state, and γ is whatever happens to be on the stack — it does not matter what, the stack contents are simply ignored. Because the PDA is nondeterministic, accepting means SOME computation path lands in F with the input fully read.
This mode feels natural because it generalises exactly how a DFA accepts: by which state it halts in. The stack did its job of bookkeeping during the run, but at the finish line we only check the control. The key fact, proved separately, is that this is no weaker and no stronger than the other mode: the languages accepted by final state are exactly the languages accepted by empty stack, namely the context-free languages. You may choose whichever mode is more convenient for a given construction.
An a^n b^n machine with F = {q2}: after pushing for a's and popping for b's, an ε-move takes it to q2 only when the stack is back to Z0. If the input is exhausted in q2, it accepts; the stack still holding Z0 is irrelevant.
Accept if input is fully read and the control halts in an accepting state — stack contents ignored.
Final-state acceptance ignores the stack entirely at the end. This is a different convention from empty-stack acceptance, yet the two recognise exactly the same class of languages.