Theory
The Chomsky Hierarchy
Four grammar classes, four machines, one strict containment
The Chomsky hierarchy is a four-level containment ranking of formal grammars — regular, context-free, context-sensitive, and recursively enumerable — where each level is recognized by an abstract machine of strictly greater power: a finite automaton, a pushdown automaton, a linear-bounded automaton, and a Turing machine. Introduced by Noam Chomsky in 1956, it maps a precise chain of inclusions (Type 3 ⊊ Type 2 ⊊ Type 1 ⊊ Type 0) onto exactly how much memory a machine needs to decide whether a string belongs to a language — and it is the theoretical spine of every lexer, parser, and compiler ever built.
- Type 3 · RegularFinite automaton · O(n)
- Type 2 · Context-freePushdown automaton · O(n³) general
- Type 1 · Context-sensitiveLinear-bounded automaton · PSPACE
- Type 0 · Recursively enumerableTuring machine · undecidable
- IntroducedNoam Chomsky, 1956
- ContainmentType 3 ⊊ Type 2 ⊊ Type 1 ⊊ Type 0 (strict)
Interactive visualization
Press play, or step through manually. The visualization is yours to drive — try it before reading on.
Watch the 60-second explainer
A condensed visual walkthrough — narrated, captioned, under a minute.
What the Chomsky hierarchy actually is
A formal grammar is a finite set of rewrite rules that generates a (possibly infinite) set of strings — a language. Chomsky's insight in 1956 was that by restricting the shape of the rules you allow, you carve grammars into four nested classes, and each class turns out to correspond exactly to a class of abstract machine that can recognize its languages. More rule freedom means more expressive languages, which means more powerful machines with more memory. That correspondence — grammars on one side, automata on the other — is what makes the hierarchy the organizing map of theoretical computer science.
The four classes are numbered Type 0 through Type 3, counterintuitively with the most powerful class as Type 0 and the least powerful as Type 3:
- Type 3 — Regular. Rules of the form
A → aBorA → a(right-linear). Recognized by a finite automaton (DFA/NFA). No memory beyond a fixed number of states. - Type 2 — Context-free. Rules of the form
A → γ: one nonterminal on the left, any string on the right. Recognized by a pushdown automaton (PDA) — a finite automaton plus a stack. - Type 1 — Context-sensitive. Rules of the form
αAβ → αγβwith|γ| ≥ 1(non-contracting). Recognized by a linear-bounded automaton (LBA) — a Turing machine whose tape is bounded to the length of the input. - Type 0 — Recursively enumerable. Unrestricted rules
α → βwhereαcontains at least one nonterminal. Recognized by a Turing machine with unbounded tape.
Why the hierarchy matters
The practical payoff is a decision procedure for language designers: choose the weakest class that can express what you need. Weaker classes buy you faster recognition, decidability, and simpler tooling. This is exactly why real compilers are stratified. A lexer describes tokens with regular expressions (Type 3) and scans them in linear time with a DFA. A parser describes nested syntax with a context-free grammar (Type 2) and uses a stack-backed algorithm. Semantic constraints that are genuinely context-sensitive — "this variable was declared", "these types agree" — are deliberately not pushed into the grammar, because context-sensitive membership is PSPACE-complete and would make the compiler intractable; instead they live in a separate typed pass.
The hierarchy also draws the boundary of the computable. Type 0 languages are precisely those a Turing machine can semi-decide. The step from Type 1 (always halts, decidable) to Type 0 (may loop forever) is the step from the decidable to the merely recognizable — the same cliff the halting problem falls off. Understanding the hierarchy is understanding where algorithms stop existing.
How each level works, step by step
Type 3 · Regular — the finite automaton
A DFA has a finite set of states and a transition function. It reads the input left to right, one symbol per step, and accepts if it ends in an accepting state. Because it has no auxiliary storage, the only thing it "remembers" is which of its finitely many states it is in — so it can recognize patterns whose structure is bounded, like (ab)* or "an even number of zeros", but it cannot count without bound. Recognition is O(n) time and O(1) space (beyond the machine itself). Regular languages are closed under union, intersection, complement, concatenation, and Kleene star.
Type 2 · Context-free — the pushdown automaton
Add a stack and you get a PDA. The stack gives the machine unbounded but last-in-first-out memory, which is exactly what nested structure needs. The canonical witness is { aⁿbⁿ : n ≥ 0 }: push on each a, pop on each b, accept if the stack empties exactly as input ends. This is why context-free grammars parse balanced brackets, arithmetic expressions, and block-structured code. General CFG membership is O(n³) via the CYK algorithm; deterministic subclasses (LL(1), LR(1)) parse in O(n).
Type 1 · Context-sensitive — the linear-bounded automaton
An LBA is a Turing machine restricted to the portion of tape holding the input (times a constant). The stack of a PDA reads only its top; an LBA can revisit and rewrite any cell, giving it enough power to enforce cross-serial agreement. The canonical witness is { aⁿbⁿcⁿ : n ≥ 1 } — provably not context-free, but easily context-sensitive because the machine can walk the tape matching counts. Membership is decidable but PSPACE-complete; the machine always halts because a bounded tape has finitely many configurations.
Type 0 · Recursively enumerable — the Turing machine
Remove the tape bound and you have a full Turing machine. It can rewrite anywhere, use unbounded scratch space, and — crucially — run forever. A Type 0 language is one whose members the machine accepts, though it may never halt on non-members. This is semi-decidability: membership is confirmable, non-membership is not. The subset of Type 0 languages where the machine always halts is the recursive (decidable) languages, which is a proper subset — the halting problem's language is recursively enumerable but not recursive.
The four classes side by side
| Property | Type 3 · Regular | Type 2 · Context-free | Type 1 · Context-sensitive | Type 0 · Recursively enumerable |
|---|---|---|---|---|
| Machine | Finite automaton | Pushdown automaton | Linear-bounded automaton | Turing machine |
| Memory model | Finite states only | Unbounded LIFO stack | Tape bounded to input | Unbounded tape |
| Rule shape | A → aB, A → a | A → γ | αAβ → αγβ (non-contracting) | α → β (unrestricted) |
| Membership complexity | O(n) | O(n³) general, O(n) for LR(1) | PSPACE-complete | Undecidable (semi-decidable) |
| Witness language | (ab)* | aⁿbⁿ | aⁿbⁿcⁿ | halting-problem language |
| Closed under complement? | Yes | No | Yes | No |
| Real-world use | Lexers, regex, tokenizers | Parsers, expression grammars | Natural-language agreement, semantic checks | General computation |
How we prove the containments are strict
Each inclusion is proper — there is a language in the outer class that no grammar of the inner class can generate. The proofs are the famous pumping lemmas.
The pumping lemma for regular languages says: for any regular language there is a length p such that any string of length ≥ p can be split xyz with |y| ≥ 1, |xy| ≤ p, and xyⁱz in the language for all i ≥ 0. Apply it to aⁿbⁿ: the pumped segment y lies inside the run of as, so pumping breaks the a/b balance — contradiction. So aⁿbⁿ is context-free but not regular, separating Type 3 from Type 2.
The pumping lemma for context-free languages uses two pumpable segments uvwxy. Apply it to aⁿbⁿcⁿ: the two segments can straddle at most two of the three symbol runs, so pumping unbalances the third — contradiction. So aⁿbⁿcⁿ is context-sensitive but not context-free, separating Type 2 from Type 1. The final gap, Type 1 ⊊ Type 0, follows from the decidability distinction: context-sensitive membership always halts, but some recursively enumerable languages (the halting-problem language) are undecidable, so they cannot be context-sensitive.
Grammars for the classic witness languages
Here are the actual grammars, written as rewrite rules, that generate each witness — a concrete way to see the rule-shape restrictions in action.
# Type 3 (regular): (ab)* — right-linear, no counting
S → a A | ε
A → b S
# Type 2 (context-free): aⁿbⁿ — one nonterminal on the left, a stack does the counting
S → a S b | ε
# Type 1 (context-sensitive): aⁿbⁿcⁿ — context on the left, non-contracting
S → a B S c | a b c
B a → a B
B b → b b
# Type 0 (recursively enumerable): unrestricted — a rule may DELETE symbols
# left-hand side longer than right-hand side is allowed here and NOWHERE below
A B → ε
Read top to bottom, the rules gain freedom. Type 3 forces a single terminal followed by at most one nonterminal — you literally cannot write down a rule that counts. Type 2 lets the right side be any string but keeps a lone nonterminal on the left, which is exactly the constraint a stack can track. Type 1 lets you condition a rewrite on neighbors (B a → a B only fires next to an a) but forbids shrinking the sentential form. Type 0 removes even that, permitting A B → ε, which erases — and erasure is precisely what lets Type 0 grammars simulate a Turing machine that can loop forever.
Common misconceptions and pitfalls
- "Regex can match nested brackets." Classical (Type 3) regular expressions cannot — that requires unbounded counting. Modern "regex" engines with backreferences and recursion are strictly more powerful than regular languages and are not the regular expressions of the hierarchy. Backreferences alone push matching to NP-hard.
- "Recursively enumerable means decidable." No. Recursively enumerable = accepted by some Turing machine (may loop on non-members). Recursive/decidable = the machine always halts. The recursive languages are a strict subset of the recursively enumerable ones.
- "Programming languages are context-free." Their syntax is (deliberately kept) context-free, but constraints like declare-before-use and type agreement are context-sensitive and are checked semantically, not by the parser.
- "Higher type number means more powerful." It is the reverse. Type 0 is the most powerful, Type 3 the least. The numbering runs opposite to the power ordering.
- "Context-sensitive grammars allow shrinking rules." They must be non-contracting: the right side is never shorter than the left. The one exception is a single
S → εrule whenSnever appears on any right-hand side.
A brief history
Noam Chomsky, then a young linguist at MIT, published the hierarchy in his 1956 paper "Three Models for the Description of Language" and developed it further in Syntactic Structures (1957). His motivation was linguistic — he was arguing that finite-state (regular) models were too weak to describe the recursive, nested structure of human sentences, and that context-free and richer grammars were needed. Marcel-Paul Schützenberger and others soon formalized the automata correspondences. The framework turned out to matter far more for computer science than for linguistics: it became the mathematical foundation of parsing theory in the 1960s, shaped the design of compilers, and remains a core topic in every automata and computability course. It is one of the rare ideas that seeded an entire field from outside it.
Frequently asked questions
What are the four levels of the Chomsky hierarchy?
From most to least restrictive: Type 3 (regular) recognized by finite automata, Type 2 (context-free) recognized by pushdown automata, Type 1 (context-sensitive) recognized by linear-bounded automata, and Type 0 (recursively enumerable) recognized by Turing machines. Each class is a strict subset of the next, so every regular language is context-free, every context-free language is context-sensitive, and every context-sensitive language is recursively enumerable — but none of the reverse inclusions hold.
Why can't a regular expression match balanced parentheses?
Regular languages are recognized by finite automata, which have a fixed, constant number of states and no auxiliary memory. Matching balanced parentheses requires counting arbitrarily deep nesting, which needs unbounded memory. The pumping lemma for regular languages proves the language { aⁿbⁿ : n ≥ 0 } is not regular — any long enough string can be 'pumped' to break balance. A pushdown automaton solves it because its stack can count the depth.
What is the difference between context-free and context-sensitive grammars?
A context-free rule has the form A → γ: a single nonterminal on the left, replaced regardless of surroundings. A context-sensitive rule has the form αAβ → αγβ: the nonterminal A is rewritten only in the context of α and β, and the right-hand side is never shorter than the left (non-contracting). Context-sensitive grammars can express agreement constraints like aⁿbⁿcⁿ that context-free grammars provably cannot, at the cost of PSPACE-complete membership testing.
What does recursively enumerable mean?
A language is recursively enumerable (Type 0) if some Turing machine accepts exactly its strings — halting and accepting on members, but possibly running forever on non-members. This is semi-decidability: you can confirm membership but not always confirm non-membership. Recursive (decidable) languages are the strict subset where the machine always halts. The halting problem's language is recursively enumerable but not recursive.
Which grammar class do real programming languages use?
Lexers use regular languages (Type 3) to tokenize, since keywords and identifiers are describable by regular expressions and scan in linear time. Parsers use context-free grammars (Type 2), usually a deterministic subset like LR(1) or LL(1), because the nested block structure of code needs a stack. Context-sensitive constraints such as 'variables must be declared before use' or type agreement are handled by a separate semantic-analysis pass, not the grammar itself.
Is the Chomsky hierarchy strict, and how do we know?
Yes, every containment is proper. The pumping lemma for regular languages separates Type 3 from Type 2 (aⁿbⁿ is context-free but not regular). The pumping lemma for context-free languages separates Type 2 from Type 1 (aⁿbⁿcⁿ is context-sensitive but not context-free). The class separations up to Type 0 follow from the space and halting distinctions between linear-bounded automata and unrestricted Turing machines. Each witness language lives in one class but not the one below.
What is the time complexity of parsing each grammar class?
Regular language recognition runs in O(n) with a deterministic finite automaton. General context-free membership is O(n³) with the CYK algorithm (or O(n^2.37) with fast matrix multiplication); deterministic subclasses like LR(1) parse in O(n). Context-sensitive membership is PSPACE-complete. Membership in a recursively enumerable language is undecidable in general — no algorithm can decide it for every input.