Sikau

Theory of computation · Day 6 · about 35 min

Grammars and stacks

Context-free languages need memory that grows.

What finite memory can't do

Try to design a DFA for aⁿbⁿ: some a's followed by the same number of b's. After reading the a's, the machine must remember how many there were — and with k states it can only tell k counts apart. Feed it k + 1 a's and two different counts land on the same state, so it must give the same answer for strings it should treat differently. No DFA can do it.

That argument, made precise, is the pumping lemma: any long enough string in a regular language has a middle piece that can be repeated (pumped) and the result stays in the language. Pump the a's in aⁿbⁿ and the counts no longer match — so aⁿbⁿ is not regular. Balanced brackets, nested HTML and arithmetic with parentheses all have the same problem.

Context-free grammars

A context-free grammar describes a language with rewrite rules. Upper-case letters are nonterminals that still need rewriting; everything else is a terminal that appears in the final string. Start from the start symbol and keep replacing a nonterminal by one of its rule bodies until only terminals remain. Each sequence of replacements is a derivation.

const grammar = {
  start: "S",
  rules: { S: ["aSb", ""] },
};
// S → aSb → aaSbb → aabb

Almost every programming language's syntax is described by a context-free grammar — the parser you'd build for it follows the rules directly. Chomsky defined these grammars in 1956 to study human language.

The rest of this lesson

  • Generating and the stackexplain
  • Shortest stringspredict
  • Deriving aabborder
  • Machine for the jobmatch
  • Grammars and bracketswrite code
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 10 lessons of Theory of computation