Theory of Computation & Computer Graphics β Introduction to Context Free Language, NEC licence examination syllabus (Nepal Engineering Council).
Pushdown Automata (PDA)
A finite automaton with a stack β and the stack is exactly the unbounded memory that regular languages lacked.
π Where this lives: The stack in a pushdown automaton is the same stack your program uses for function calls. When a function calls another, the return address is pushed; when it returns, the address is popped β last in, first out. That is why recursion works, why a stack overflow happens when recursion runs too deep, and why nested structures of any kind β brackets, XML tags, block scopes β are handled naturally by exactly this mechanism. Search "call stack recursion pushdown automaton nested structure".
Definition and operation
A PUSHDOWN AUTOMATON IS A FINITE AUTOMATON AUGMENTED WITH A
STACK. Formally, a 7-tuple:
M = (Q, Ξ£, Ξ, Ξ΄, qβ, Zβ, F)
Q finite set of STATES
Ξ£ INPUT alphabet
Ξ STACK alphabet β may differ from Ξ£, and usually does
Ξ΄ the TRANSITION FUNCTION
Ξ΄ : Q Γ (Ξ£ βͺ {Ξ΅}) Γ Ξ β finite subsets of Q Γ Ξ*
qβ start state
Zβ the INITIAL STACK SYMBOL (bottom marker)
F accepting states
ββ READING THE TRANSITION FUNCTION βββββββββββββββββββββββββ
A MOVE DEPENDS ON THREE THINGS: the current state, the input
symbol (or Ξ΅, meaning no input is consumed), AND THE SYMBOL ON
TOP OF THE STACK.
A move DOES THREE THINGS: changes state, consumes the input
symbol (or not, if Ξ΅), and REPLACES THE TOP STACK SYMBOL WITH
A STRING.
Ξ΄(q, a, X) = { (p, Ξ³) } means: in state q, reading a,
with X on top β go to p, POP X
and PUSH Ξ³.
THE THREE STACK OPERATIONS ARE ALL SPECIAL CASES OF THAT ONE
RULE, which is worth stating because students often look for
three separate mechanisms:
Ξ³ = Ξ΅ β POP (X removed, nothing pushed)
Ξ³ = X β NO CHANGE (X removed and replaced)
Ξ³ = YX β PUSH Y (X replaced by Y on top of X)
THE OUTPUT IS A SET, so PDAs are NON-DETERMINISTIC by default.
ββ INSTANTANEOUS DESCRIPTION βββββββββββββββββββββββββββββββ
The complete configuration of a PDA is a triple
(q, w, Ξ³)
current state, REMAINING input, and the ENTIRE stack
contents with the top written leftmost.
A move is written (q, aw, XΞ²) β’ (p, w, Ξ³Ξ²).
ββ TWO MODES OF ACCEPTANCE βββββββββββββββββββββββββββββββββ
ACCEPTANCE BY FINAL STATE
L(M) = { w : (qβ, w, Zβ) β’* (p, Ξ΅, Ξ³) for some p β F }
β the input is exhausted and the machine is in an accepting
state; the stack contents are irrelevant.
ACCEPTANCE BY EMPTY STACK
N(M) = { w : (qβ, w, Zβ) β’* (p, Ξ΅, Ξ΅) }
β the input is exhausted and the stack is empty; the state
is irrelevant, and F is not used at all.
THE TWO MODES ARE EQUIVALENT IN POWER: for every PDA accepting
by final state there is one accepting by empty stack
recognising the same language, and vice versa. The
constructions add one state and one new bottom marker to
prevent the stack emptying accidentally.
THE MODE IS THEREFORE A CONVENIENCE, chosen to make a
particular machine simpler to write β and an exam answer
should always say which mode it is using.
ββ A FULLY WORKED PDA: L = { aβΏbβΏ : n β₯ 0 } ββββββββββββββββ
THE STRATEGY: push a marker for every a, pop one for every b.
IF THEY RUN OUT TOGETHER, THE COUNTS MATCHED.
States qβ (reading a's) and qβ (reading b's);
stack alphabet { A, Zβ }; acceptance by empty stack.
Ξ΄(qβ, a, Zβ) = (qβ, A Zβ) push A, keep the marker
Ξ΄(qβ, a, A) = (qβ, A A) push another A
Ξ΄(qβ, b, A) = (qβ, Ξ΅) first b: pop
Ξ΄(qβ, b, A) = (qβ, Ξ΅) keep popping
Ξ΄(qβ, Ξ΅, Zβ) = (qβ, Ξ΅) pop the marker and accept
TRACE FOR aaabbb, writing the stack top-first:
STATE REMAINING STACK ACTION
ββββββββββββββββββββββββββββββββββββββββββ
qβ aaabbb Zβ start
qβ aabbb A Zβ read a, push A
qβ abbb A A Zβ read a, push A
qβ bbb A A A Zβ read a, push A
qβ bb A A Zβ read b, pop
qβ b A Zβ read b, pop
qβ Ξ΅ Zβ read b, pop
qβ Ξ΅ (empty) Ξ΅-move, pop Zβ
ββββββββββββββββββββββββββββββββββββββββββ
ACCEPT
THE STACK HEIGHT PEAKS AT EXACTLY n = 3, WHICH IS THE POINT:
the machine has stored a count that no finite automaton
could, and it did so with only two states. THE MEMORY IS IN
THE STACK, NOT IN THE STATES.
WHY aabb IS ACCEPTED AND aab IS NOT: for aab the machine
reaches (qβ, Ξ΅, A Zβ) β input exhausted with an A still on
the stack, so the stack never empties and the string is
rejected. The unmatched a is literally still sitting there.
ββ A SECOND EXAMPLE: EVEN-LENGTH PALINDROMES βββββββββββββββ
L = { w wα΄Ώ : w β {a,b}* }.
PUSH each symbol while in qβ; at some point GUESS that the
midpoint has been reached and move to qβ by an Ξ΅-transition;
then POP and match each remaining symbol.
Ξ΄(qβ, a, X) = (qβ, aX) push
Ξ΄(qβ, b, X) = (qβ, bX) push
Ξ΄(qβ, Ξ΅, X) = (qβ, X) GUESS the midpoint
Ξ΄(qβ, a, a) = (qβ, Ξ΅) match and pop
Ξ΄(qβ, b, b) = (qβ, Ξ΅) match and pop
Ξ΄(qβ, Ξ΅, Zβ) = (qβ, Ξ΅) accept
THE Ξ΅-TRANSITION IS AN IRREDUCIBLE GUESS. The machine cannot
know where the middle is without reading the whole string
first, so it tries every possible midpoint in parallel and
accepts if any works. THIS IS WHERE NON-DETERMINISM IS DOING
REAL WORK β and, as the next section shows, it is work no
deterministic PDA can do.
The contrast worth memorising: non-determinism adds nothing to finite automata, real power to pushdown automata, and nothing again to Turing machines. The subset construction fails for PDAs because tracking all possible configurations would need a set of stacks, and there are infinitely many of those.
π Go further: Deterministic context-free languages are why compilers are fast. A DPDA runs in linear time with no backtracking, and the DCFLs are exactly the languages an LR parser can handle β so programming languages are deliberately designed to be deterministic context-free. That is a language-design constraint, not a discovery: when a proposed syntax turns out to need unbounded lookahead, committees change the syntax rather than accept a slower parser. The theory in this topic is therefore acting as a design rule on real languages, which is an unusually direct route from formal result to engineering practice. Search "deterministic context free language LR parsing language design constraint".