Designing the FIRST and FOLLOW Sets for a Grammar
To design LL(1) parsing logic, you must compute two lookahead sets for each nonterminal in a context-free grammar: FIRST and [FOLLOW]{def="Set of terminals (and possibly ) that can appear immediately to the right of a nonterminal in some sentential form"}. These sets are constructed using production rules and (for many grammars) an iterative "fixed-point" procedure until they stop changing. Standard definitions treat ε as a special case in FIRST, and the end-marker [ ]{def="Input end marker used in parsing tables and FOLLOW sets"} as a special case in FOLLOW (added for the start symbol).2
Key idea:
- FIRST focuses on “what tokens can start what this nonterminal can generate.”
- FOLLOW focuses on “what tokens can legally follow this nonterminal in some derivation,” which is essential for resolving parsing decisions.
Learning targets (what you should be able to do)
- Compute FIRST(X) for every nonterminal .
- Compute [FOLLOW]{def="Set of terminals (and possibly ) that can appear immediately to the right of a nonterminal in some sentential form"}(A) for every nonterminal A$.
- Correctly handle ε propagation and when to stop scanning symbols in a production body.
Footnotes
-
"FIRST set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FIRST concept and ε handling in LL parsing. ↩
-
"FOLLOW set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FOLLOW computation, including $ and propagation rules. ↩ ↩2
FIRST and FOLLOW Sets (LL(1) Parsing) — Core Examples
Core definitions you will use
Let where are nonterminals, terminals, productions, and start symbol.
FIRST of a string of grammar symbols
To compute FIRST for a production body like , you need a helper notion: FIRST of a sequence. A standard rule is:
- Add to if for the first position where can derive something starting with .
- If can derive ε, then FIRST can include what starts from as well; similarly continue.
- If every symbol in the sequence can derive ε, then ε is included in FIRST of the sequence.
This “scan left-to-right until a symbol can’t derive ε” behavior is crucial to avoid over-approximations and to make your algorithm converge correctly.
FOLLOW of a nonterminal
collects terminals that can appear immediately after in some sentential form where is a terminal and is any string of symbols.
Operationally, in LL(1) computation:
- Add \,\, \text{FOLLOW}(S)$.
- For each production , everything in (except ε) goes into .
- If can derive ε (or if is empty), then goes into .
Footnotes
-
"FIRST set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FIRST concept and ε handling in LL parsing. ↩ ↩2
-
"FOLLOW set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FOLLOW computation, including $ and propagation rules. ↩ ↩2
Pro Tip: Treat ε as a “permission to continue”
When scanning a production body for FIRST/FOLLOW propagation, ε doesn’t add a terminal token. Instead, ε tells you that you should keep looking at later symbols. This prevents the common mistake of stopping too early.
Footnotes
-
"FIRST set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FIRST concept and ε handling in LL parsing. ↩
Common Pitfall: Adding ε into FOLLOW sets
In standard LL(1) construction rules, FOLLOW sets contain terminals and $ only; ε is handled indirectly via “if the remainder can derive ε” rules. Don’t place ε directly into FOLLOW(A) when adding FIRST(β).
Footnotes
-
"FOLLOW set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FOLLOW computation, including $ and propagation rules. ↩
Step-by-step algorithm to compute FIRST sets
- 1Step 1
For every terminal , set . For every nonterminal , initialize . If the grammar contains an explicit production , then include ε in (usually as part of your iterative update logic).
Footnotes
-
"FIRST set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FIRST concept and ε handling in LL parsing. ↩
-
- 2Step 2
For each production , compute what can start strings derived from the RHS: add excluding ε to . If , also add excluding ε, and so on. Keep going while the prefix symbols can derive ε.
Footnotes
-
"FIRST set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FIRST concept and ε handling in LL parsing. ↩
-
- 3Step 3
If ε is in FIRST of every symbol in the RHS (equivalently, the whole RHS can derive ε), then add ε to .
Footnotes
-
"FIRST set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FIRST concept and ε handling in LL parsing. ↩
-
- 4Step 4
Because FIRST sets only grow (monotonic growth) and are finite over , you can keep looping through productions until a full pass adds nothing new (fixed point).
- 5Step 5
Pick a few nonterminals and manually derive short strings to verify that all terminals you found in FIRST(X) can actually appear as initial tokens, and that you didn’t miss derivable terminals (a quick sanity check before using them in FOLLOW).
Step-by-step algorithm to compute FOLLOW sets
- 1Step 1
Set \text{FOLLOW}(S)=\{\}S\text{FOLLOW}(A)=\emptysetA
e S$.Footnotes
-
"FOLLOW set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FOLLOW computation, including $ and propagation rules. ↩
-
- 2Step 2
For every production , consider each occurrence of a nonterminal on the RHS and treat the symbols after it as .
Footnotes
-
"FOLLOW set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FOLLOW computation, including $ and propagation rules. ↩
-
- 3Step 3
If starts with some sequence of symbols, add every terminal in except ε to .
Footnotes
-
"FOLLOW set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FOLLOW computation, including $ and propagation rules. ↩
-
- 4Step 4
If (or if is empty), then add everything in into .
Footnotes
-
"FOLLOW set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FOLLOW computation, including $ and propagation rules. ↩
-
- 5Step 5
FOLLOW sets also grow monotonically and reach a fixed point after repeated passes over productions.
Footnotes
-
"FOLLOW set (context-free grammar) — Wikipedia" https://en.wikipedia.org/wiki/LL_parser - Defines FOLLOW computation, including $ and propagation rules. ↩
-
- 6Step 6
FOLLOW computation depends on FIRST(β), so ensure FIRST sets are computed first and are stable before running FOLLOW iterations.
Visualizing the FIRST/FOLLOW propagation
Consider a production . The update behavior is:
- From FIRST side: terminals that can begin strings from should be legal followers of .
- From ε side: if can disappear (derive ε), then whatever can follow should also follow .
Rule-to-effect mapping for LL(1) FIRST/FOLLOW design
How each grammar situation contributes to set updates.
Edge cases and correctness checks
Workflow to design FIRST/FOLLOW
Parse grammar rules
1Identify terminals/nonterminals, ε productions, and the start symbol S."
Compute FIRST sets
2Use left-to-right scanning of RHS with ε as a continuation rule; iterate to fixed point."
Compute FOLLOW sets
3Initialize FOLLOW(S) with $; propagate FIRST(β){ε} and FOLLOW(A) when β⇒*ε; iterate to fixed point."
Use results for LL(1) table checks
4FIRST/FOLLOW guide which production to place under each lookahead terminal."
FIRST & FOLLOW micro-deck
Knowledge Check
In the standard LL(1) FOLLOW update rule for a production A → α B β, what is added to FOLLOW(B) from FIRST(β)?