Right Linear Grammar
Understand right linear grammars — the grammar form that generates regular languages — where every production places the non-terminal at the right end, mirroring the structure of a finite automaton.
Definition
A right linear grammar (also called a right regular grammar) is a grammar G = (V, T, P, S) where every production rule has one of these three forms:
| Form | Meaning |
|---|---|
| A → aB | Terminal a on the left, non-terminal B on the right |
| A → a | Just a single terminal (or any string of terminals) |
| A → ε | The empty string |
The defining feature: the non-terminal always appears at the right end of the right-hand side (if it appears at all).
Right linear grammars generate exactly the regular languages — the same languages recognised by Deterministic and Nondeterministic Finite Automata (DFA/NFA).
Example 1 — Strings of a's Ending in b
Language: L = {aⁿb | n ≥ 0} = {b, ab, aab, aaab, ...}
These are strings of zero or more a's, followed by exactly one b.
Right Linear Grammar:
S → aS: consume one 'a', then continue with S on the rightS → b: stop by producing 'b', no more non-terminals
Derivation of "aab":
The grammar "reads left to right" — each step adds one character to the left and moves the non-terminal to the right. This directly mirrors how a DFA processes input: it reads one symbol, changes state, reads the next symbol, changes state, and so on.
Equivalent NFA:
The NFA and the grammar describe exactly the same language.
Example 2 — Binary Strings Ending in 01
Language: L = { w ∈ {0,1}* | w ends with "01" } Examples: 01, 001, 101, 0101, 1001, ...
Right Linear Grammar:
- S handles any prefix of 0s and 1s
- S → 0A means "we just read a 0 — now check if the next is a 1"
- A → 1B means "we read the 1 — the string now ends in 01"
- B → ε means "done — accept"
Derivation of "1001":
Simplified equivalent grammar (same language, fewer states):
S → 01 acts as the base case when the entire suffix is just "01".
Connection to Finite Automata
Right linear grammars and finite automata (DFA/NFA) are two notations for the same thing. You can convert between them mechanically.
Grammar → NFA
For each non-terminal A, create a state named A. For each production:
- A → aB → state A transitions on input 'a' to state B
- A → a → state A transitions on input 'a' to the accepting state
- A → ε → state A is an accepting state
NFA → Grammar
For each state q, create a non-terminal Q. For each transition:
- q --a--> r → Q → aR
- q --a--> accepting → Q → a
- q is accepting → Q → ε
The start state's non-terminal becomes the start symbol S.
Why This Matters in Compilers
The lexer (scanner) in a compiler is implemented as a DFA. The tokens it recognises — identifiers, numbers, operators, keywords — are all described by regular expressions, which are equivalent to right linear grammars.
Understanding right linear grammars is the theoretical foundation for understanding how lexers work.
Right vs Left Linear — A First Comparison
There are two types of linear grammars, and both generate exactly the regular languages:
| Feature | Right Linear | Left Linear |
|---|---|---|
| Non-terminal position | At the right end: A → aB | At the left end: A → Ba |
| Derivation direction | Builds string left to right | Builds string right to left |
| Corresponds to | NFA reading input left-to-right | NFA reading input right-to-left |
| Same language class? | Yes — both generate regular languages | Yes |
Example — same language, both styles:
Language: L = {aⁿb | n ≥ 0}
Both grammars generate {b, ab, aab, aaab, ...}.
The key insight: the direction of the non-terminal in the production rule determines whether the grammar is right-linear or left-linear, but the expressive power is identical.
The next topic covers left linear grammars in detail.