Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Context-free grammars and derivations

After this lesson: I can use a grammar to decide whether a string is valid.

55 min lesson2 commandsCompilers and computer architecture lab: gcc, flex, bison and RISC-V in one VM

Rules that decide which strings are valid

A context-free grammar is a set of rewriting rules. It describes which strings are valid, such as every correctly bracketed expression or every sentence of a programming language.

Unlike a regular expression, a grammar can describe nesting. That is why a compiler uses one to read your code.

By the end of this lesson

Note

I can use a grammar to decide whether a string is valid.

Key words

WordWhat it meansExample
Grammara set of rules that builds strings
Terminala symbol that stays in the final string(
Non-terminala name that still has to be rewrittenS
Ruleone way to rewrite a non-terminalS becomes (S)S
Derivationthe steps from the start symbol to a string
Nestingone thing inside another of the same kind((()))

The cells students fill in are left blank in this preview.

A grammar rewrites names into symbols

A grammar starts from one special non-terminal, the start symbol, here written S. A rule says what a non-terminal may be replaced with.

Keep replacing non-terminals until only terminals are left. The string you end with is valid. Here the grammar for balanced round brackets has two rules: S becomes (S)S, or S becomes nothing.

Worked example: deriving (()) from S

StepString so farRule used
1SStart symbol
2(S)SS becomes (S)S
3((S)S)SS becomes (S)S, on the first S inside
4(()S)SS becomes nothing
5(())SS becomes nothing
6(())S becomes nothing: valid

The cells students fill in are left blank in this preview.

To check a string, run the rules backwards

A derivation builds a string from S. To decide whether a string is valid, a parser works the other way. It finds a side-by-side pair of brackets that the rules could have made, and takes it out.

If the string shrinks to nothing, it was valid. If it gets stuck, it was not.

Shrinking a string to check brackets

Code: python
# Run the rules backwards: a pair () next to each other can be taken out.
text = "(()())"
print(text)
while "()" in text:
    text = text.replace("()", "", 1)
    print(text)
if text == "":
    print("balanced")
else:
    print("not balanced")
# Change text to "(()" and run again.

A common mistake

Warning

Many people think a grammar is a program that checks a string. It is only a description of which strings are valid. A parser is a separate program that uses the grammar to find a derivation, or to fail. Write the rules first, then the parser.

A grammar can nest and a pattern cannot

The rule S becomes (S)S puts a new S in the middle of a pair. That S can use the same rule again, as deep as you like. This is nesting.

A finite automaton cannot follow it, because it would have to remember how many brackets are open. A parser keeps that count on a stack, a pile where you add and remove only at the top.

Which tool describes which strings

StringsRegular expressionGrammar
Any a then any b: aabbbYes: a*b*Yes
Equal a then b: aabbNoYes: S becomes aSb or nothing
Balanced brackets: (()())NoYes: S becomes (S)S or nothing

The cells students fill in are left blank in this preview.

A pattern accepts a bracket it cannot match

Command
printf '(())\n(()\n' | grep -E '^\(+\)+$'

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

The lab calculator's expr rule

Command
grep -A5 "^expr" ~/compiler/calc.y

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Going further

Write a grammar for the strings a, b and c joined by plus signs, such as a+b+c. One rule must use the start symbol on both sides of the plus.

Derive a+b+c step by step in a table like the one above, and say how many rules you used.

About this lab and its source: Compilers and computer architecture lab: gcc, flex, bison and RISC-V in one VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.