4.6.8 · D4Theory of Computation

Exercises — Context-free grammars (CFG) — productions, derivations, parse trees

2,514 words11 min readBack to topic

Before we start, one reminder of the vocabulary the parent gave us, since every problem leans on it:

Recall The five words you must own
  • Variable (non-terminal): a placeholder still to be expanded, e.g. .
  • Terminal: a real letter of the final string, e.g. a, (, +.
  • Production: a rewrite rule ; the left side is exactly one variable.
  • Derivation: , applying one production per step.
  • Parse tree: the structural picture — who is the child of whom; its yield (leaves left-to-right) is the derived string.

Level 1 — Recognition

L1.1

Which of these is a valid context-free production? For each invalid one, say why.

Recall Solution

The single test: the left-hand side must be exactly one variable.

  • (a) valid — LHS is the single variable ; the right side may mix terminals and variables freely.
  • (b) invalid — LHS is aS, a terminal glued to a variable. That's context-sensitive, not context-free.
  • (c) valid — LHS is ; RHS (empty string) is allowed. This is an erasing rule.
  • (d) invalid — LHS AB is two variables. Not a single variable ⇒ not a CFG.

Answer: valid = (a), (c); invalid = (b), (d).

L1.2

For the grammar , classify each string: is it a sentential form (may still contain variables), a finished word in , or neither (not derivable)?

Recall Solution
  • (a) sentential form — it still contains the variable , so it is a partway string, not a finished word. It appears literally after one step: .
  • (b) finished word, in — only terminals, and it is derivable (parent's Worked Example 1 derived exactly (())).
  • (c) neither)( is all terminals so it's not a sentential-form-with-variables, but can never open with ). Every non-empty derivation starts , forcing a ( first. So it is not in .

Level 2 — Application

L2.1

Using , give a leftmost derivation of ()().

Recall Solution

Leftmost = at each step rewrite the leftmost remaining variable. Step-by-step:

  1. — start the first group.
  2. leftmost — the first group is empty ⇒ ().
  3. remaining — start a second group after it.
  4. its leftmost — second group empty ⇒ ()().
  5. final trailing — nothing left to add. Yield ()() ✓.

L2.2

Grammar . Derive aabb, then state in words.

Recall Solution

Each use of wraps one a on the left and one b on the right — a matched pair around the middle. Applying it times then gives . Language: — equal numbers of a's then b's. This is the classic language no DFA can recognise (it needs to count ).

L2.3

Grammar . Is 000111 in ? Is the empty string ?

Recall Solution

Derive 000111: Last step used . So yes, 000111 . Is in it? The only terminating rule is , which emits at least one 0 and one 1. There is no rule. So the shortest word is 01, and . Hence (note , not ).


Level 3 — Analysis

L3.1

For the ambiguous , show that a+a+a has two distinct parse trees, and explain why this is ambiguity.

Recall Solution

Tree A groups the left + first — structure : Tree B groups the right + first — structure : These are two different shapes: in Tree A the top node's children are (a+a) and a; in Tree B they are a and (a+a). See the two family-photos below.

Figure — Context-free grammars (CFG) — productions, derivations, parse trees

Because one string a+a+a yields two structurally distinct trees, is ambiguous. (For plain + the two groupings give the same numeric value, but the grammar is still ambiguous — ambiguity is about tree shape, not final value.)

L3.2

Someone claims (()) proves is ambiguous because they found "two derivations." Their derivations are: Are these two trees? Justify.

Recall Solution

No. They are the same tree, walked in a different order. Recall the parent's key fact: every parse tree ↔ exactly one leftmost derivation. To test ambiguity you must produce two distinct leftmost (or tree-distinct) derivations — not two derivations that merely differ in which variable you expanded first. Reduce both (i) and (ii) to their leftmost form: both become i.e. one identical leftmost derivation ⇒ one tree. (()) has a unique tree in . No ambiguity shown.


Level 4 — Synthesis

L4.1

Design a CFG for (twice as many b's as a's, all a's before all b's). Give the rules and derive aabbbb.

Recall Solution

Idea: one a must summon two b's, and they must stay balanced around the recursion. Wrap a on the left and bb on the right each step:

  • adds one a and two b's, keeping structure nested.
  • is the base case (), so is excluded (matches ).

Derive aabbbb ():

L4.2

Design a CFG for the language of palindromes over (strings that read the same forwards and backwards), including the empty string.

Recall Solution

A palindrome is either empty, a single letter (odd centre), or the same letter on both ends wrapping a smaller palindrome:

  • : peel a matching pair off both ends.
  • : odd-length centres.
  • : even-length centre / empty word.

Check 0110: (last step ). ✓ And 010: (using ). ✓

L4.3

Design a CFG for (either the a-block matches the b-block, or the b-block matches the c-block).

Recall Solution

"or" ⇒ two independent cases, joined by a top choice. Give two alternatives.

Case (match a,b; then any number of c's): Case (any a's; match b,c): Top rule: The single top-level choice is the logical "or". (Note: this grammar is ambiguous on strings like abc satisfying both — that's fine; the task only asked to generate , not for an unambiguous grammar.)


Level 5 — Mastery

L5.1

Prove that (the precedence-layered grammar) is unambiguous on a+a*a, by giving its unique leftmost derivation and its tree.

Recall Solution

Unique leftmost derivation: Why forced? + can appear only at the level (), and * only at the level (). To place the single + you must split at the top into ; the right operand of + is a , and only a can hold the *. So a*a is forced to sit below the + as one — grouping . No other split is legal, so exactly one tree exists.

Figure — Context-free grammars (CFG) — productions, derivations, parse trees

Because there is exactly one parse tree (one leftmost derivation), produces a+a*a unambiguously, and * binds tighter than + — precisely the intended precedence.

L5.2

Count: how many distinct parse trees does the ambiguous give for a+a+a+a (three + signs)? Explain the pattern.

Recall Solution

A tree corresponds to a full parenthesisation of a+a+a+a — i.e. a way to bracket 4 leaves so that every internal + node has two children. This count is the Catalan number for internal + operators, where . Here (three +), so Answer: 5 distinct parse trees. The five bracketings: . This is exactly why ambiguity explodes: the number of trees grows like Catalan numbers, so a compiler with an ambiguous grammar faces exponentially many interpretations. That is why real languages use layered grammars like (see Compilers — parsing).

L5.3

Give a grammar for (at least as many a's as b's). Prove your smallest and a boundary word.

Recall Solution

Idea: first generate matched pairs (the part where ), then allow extra leading a's to push above .

  • : one matched pair (keeps growing).
  • : an extra a with no b (raises over ).
  • : stop.

Because every b is produced only alongside a leading a (rule 1), and rule 2 adds a's with no b, we always have . Also all a's stay left of all b's (rule 1 wraps b to the far right, rule 2 adds a on the left).

Boundary word aab (): . ✓ Smallest word: , so (). ✓


One-line self-tests

Which grammar test decides context-freeness?
The left-hand side of every production is exactly one variable.
for ?
.
Is context-free?
No — proven not CFL by the Pumping lemma for CFLs.
How many parse trees does a+a+a+a have in ?
Five ().

Connections