MIT 18.404 — Lecture 4
Context-Free Grammars and Pushdown Automata
§ Context-Free Grammars: URLs
Recall from Lecture 12 of 6.1020 (Software Construction) that the following is a context-free grammar (CFG).
url ::= 'http://' hostname (':' port)? '/'
hostname ::= word '.' hostname | word '.' word
port ::= [0-9]+
word ::= [a-z]+
We might describe the components of this CFG like so:
The variables are , , , and .
The terminals are the digits, the lowercase letters, and the symbols .
The rules are the four lines of the grammar.
If one more formally says that a rule is , then some lines are technically multiple rules.
For example, is one such rule.
The start variable is .
The language corresponding to this CFG is the set of valid URLs.
Definition. A language is a context-free language (CFL) if it is the language of some CFG .
By replacing all variables with their productions, we can also describe our URL language in a single regular expression.
url ::= 'http://' ([a-z]+ '.')+ [a-z]+ (':' [0-9]+)? '/'
Note that this cannot be done for all CFGs.
start ::= '0' start '1' | '' // cannot be done
start ::= '0' start | '' // can be done
The problem with the former of these two CFGs is self-embedding. In fact, it turns out that any CFG without self-embedding can be reduced to a regular expression. (This fact was not discussed in lecture; proof omitted.)
§ Context-Free Grammars: PEMDAS
Consider this example of a CFG .
Take the variables .
Take the terminals .
Take the rules .
Here, denotes “or”. More formally, should contain ordered pairs, such as and , say.
Take the start variable .
Then the language of contains words such as , and , and .
Each of these words has its own parse tree that describes its derivation from variables to terminals.

Notice how the structure of the parse tree, itself, encodes the fact that comes before .
§ Context-Free Grammars: Ambiguous PEMDAS
Now consider the following CFG with the same language.
Take the variables .
Take the terminals .
Take the rules .
Take the start variable .
Then also contains words such as , and , and .
But unlike , the grammar is ambiguous, in that some words can have multiple derivations with distinct parse trees.

The ambiguity of this grammar means that this grammar does not inherently encode the fact that comes before .
§ Pushdown Automata
Informally, a pushdown automaton is just an NFA that is granted the additional ability to read and write memory to a stack.

Definition. A pushdown automaton (PDA) is a 6-tuple where:
The usual NFA components have the same meanings as before.
The set of states is .
The input alphabet (the set of atoms accepted as input) is .
The start state is .
The set of accept states is .
The stack alphabet (the set of atoms accepted by the stack) is .
The transition function has type where and .
Problem. Design a pushdown automaton that recognizes the (nonregular!) language .
Solution: The algorithm, informally, works like so:
So long as the input is , push onto the stack.
The first time the input is , transition from the start state to the state without consuming that .
So long as the input is , pop from the stack.
If at any point a is read as input, move to a permanent state.
If at any point a is read while the stack is empty, move to a permanent state.
At the end of the input string, move to an state if the stack is empty; otherwise, .
Technically, the hardware of a PDA cannot explicitly “know” whether the stack is empty or not. Here's an easy fix: as a Step 0, push onto the stack; if the top of the stack is ever , the stack must be effectively empty.
Problem. Design a pushdown automaton that recognizes the (nonregular!) language .
Solution: If we knew that had length (say), then all we would do is push the first input symbols onto the stack, then pop the stack times and compare the result of each pop against the next input symbols read.
Of course, we don't know the length of before we read it. But the nondeterminism of the NFA component of the PDA allows us to work around this in the obvious way.
§ CFLs are PDA Languages
We'll finish lecture with a theorem that says exactly what you'd expect.
Theorem. (CFL PDA) If is a context-free language, then it is recognized by some PDA.
Proof: Given any , the PDA just uses the stack as scratch work to nondeterministically try to guess the derivation of .
Initially, the stack contains the start variable of the CFG atop .
Repeat the following until or is reached. Suppose the top of the stack is .
If is a variable, then (nondeterministically) replace with one of its productions.
If is a terminal symbol, then pop from the stack, and check if matches the input.
If it does match, then proceed to the next atom in the input.
If it doesn't match, then .
If , then if the input has been entirely read, and otherwise.
Remark. Interestingly, the states of the PDA are effectively unused; they only exist to move to and .
It turns out the converse is also true. In particular,
Theorem. (CFL PDA) A language is context-free if and only if it is recognized by some PDA.
The proof of the converse is in the textbook, but we won't go over it in lecture.