4.1 FIRST and FOLLOW Sets: Mathematical Formulations & Computation Algorithms
💡 Core Intuition: The 3-Second Mental Model
🍳 The Everyday Analogy: The Forward Radar and The Trailing Shadow
Imagine standing at a train terminal deciding which track an incoming express train will arrive on:
- (The Forward Radar): You look down the track through a telescope. What color headlights could possibly appear first around the bend? If you see a green light, you know instantly it is the Northern Express. is the set of all terminal characters that can appear as the very first symbol in any string derived from .
- (The Trailing Shadow): Suppose a train car is completely transparent or empty (). You look past it to see what car is coupled immediately behind it! is the set of all terminal symbols that can legally appear immediately to the right of non-terminal across all valid sentences in the language.
💻 Bridging to Computer Science: Predictive Lookahead Routing via FIRST and FOLLOW
In top-down predictive parsing, when the parser encounters a non-terminal on top of its stack and observes an incoming lookahead token , it must choose which production rule to expand without backtracking:
- If , the parser confidently expands .
- If can derive the empty string (), the non-terminal effectively disappears! The parser then consults : if , the parser applies the derivation .
🏗️ Architectural Foundations & Lookahead Mechanics
The Predictive Lookahead Routing Pipeline
How top-down parsers use FIRST and FOLLOW sets to resolve deterministic production choices
Lookahead Token (a)
Next unconsumed terminal symbol from the lexical token stream.
FIRST(α) Inspection
If a ∈ FIRST(α), select production A → α deterministically.
FOLLOW(A) Fallback
If ε ∈ FIRST(α) and a ∈ FOLLOW(A), apply reduction A → ε.
Deterministic Slot M[A, a]
Exact production rule populated in the LL(1) parsing table.
⚖️ FIRST vs FOLLOW: Conceptual Duals
FIRST vs FOLLOW: Conceptual Duals
Contrasting leading terminal sets against trailing context sets
FIRST(α)
- •The set of terminals that can begin strings derived from α.
- •Calculated for both terminals (T) and non-terminals (V).
- •Can contain the empty string symbol ε if α can derive ε.
- •Never contains the input end-marker `$` under normal circumstances.
FOLLOW(A)
- •The set of terminals that can appear immediately to the right of A.
- •Calculated STRICTLY for non-terminals (never for terminals).
- •CANNOT EVER contain ε under any circumstances.
- •Always contains the input end-marker `$` for the start symbol S.
📐 Formal Mathematical Definitions & Inductive Algorithms
🔦 The FIRST Function
For any grammar symbol or string of symbols :
Inductive Rules to Compute FIRST:
- If is a Terminal:
- If is a Production:
- If is a Production:
- Add to .
- If , also add to .
- Continue in order: for any , if for all , add to .
- If for all , then add to (meaning is completely nullable).
👥 The FOLLOW Function
For any non-terminal :
Inductive Rules to Compute FOLLOW:
- Start Symbol Rule:
- Direct Successor Rule: If there is a production of the form : (Whatever begins immediately follows ).
- Transmission / Nullable Suffix Rule:
If there is a production of the form:
- , OR
- where (i.e. ): (Since disappears or is the final symbol of the rule, whatever can trail also legally trails ).
Cardinal Rule: is NEVER an element of any set! sets consist strictly of input terminals and
$(the input end-marker).
🏭 Real-World Production Context: How Industry Builds This
In industrial compiler engines (such as recursive-descent parsers in GCC, Clang, and Roslyn):
When a recursive-descent parser encounters a syntax error while executing the parsing function for non-terminal , it initiates Panic-Mode Error Recovery:
- The parser does not crash. Instead, it enters a token-skipping loop until it encounters a token in .
- It then cleanly returns from function
parse_A(), popping from the virtual call stack and allowing the parent grammar rule to resume parsing the remainder of the file.
Automated parser tools compute and sets across the entire grammar during compilation:
- If , the generator immediately flags a First/First Conflict.
- If and , the generator flags a First/Follow Conflict.
📐 Numerical Applications & Worked Examples
Example 1: The Canonical Arithmetic Expression Grammar
Compute the complete and sets for the unambiguous arithmetic expression grammar:
Step-by-Step Analytical Solution:
Step 1: Compute FIRST Sets (Bottom-Up Evaluation)
- For :
- Leading terminals are
'('and'id'.
- Leading terminals are
- For :
- Leading terminal is
'*', plus .
- Leading terminal is
- For :
- Begins with . Since , .
- For :
- Leading terminal is
'+', plus .
- Leading terminal is
- For :
- Begins with . Since , .
Step 2: Compute FOLLOW Sets
- Start Symbol: Add
$to :
- Inspect occurrences of :
- In : Followed by
')'. Add')'to :
- In : Followed by
- Inspect occurrences of :
- In : is at the end:
- In : Adds to itself (no new tokens):
- Inspect occurrences of :
- In : Followed by . Add .
- Since , also add :
- Inspect occurrences of :
- In : is at the end:
- Inspect occurrences of :
- In : Followed by . Add .
- Since , also add :
Consolidated Sets:
| Non-Terminal | FIRST Set | FOLLOW Set |
|---|---|---|
| E | (, id | ), $ |
| E' | +, ε | ), $ |
| T | (, id | +, ), $ |
| T' | *, ε | +, ), $ |
| F | (, id | *, +, ), $ |
Example 2: Multi-Symbol Epsilon Cascades and Follow Propagation
Compute the and sets for the following grammar featuring multi-symbol epsilon cascades:
Step-by-Step Analytical Solution:
Step 1: Compute FIRST Sets
- (begins with terminal )
- For :
- Add .
- Since , add .
- Since both and derive , add .
- .
- For :
- Begins with terminal .
Step 2: Compute FOLLOW Sets
- Start Symbol: Add
$to :
- For non-terminal in :
- Followed by .
- .
- .
- For non-terminal in :
- is at the very end of .
- .
- For non-terminal in :
- Followed by terminal .
- For non-terminal in :
- Followed by . Add .
- Since , add .
- .
- For non-terminal in :
- is at the end of .
- .
Final Table of Sets:
| Non-Terminal | FIRST Set | FOLLOW Set |
|---|---|---|
| S | a | $ |
| B | c | g, f, h |
| C | b, ε | g, f, h |
| D | g, f, ε | h |
| E | g, ε | f, h |
| F | f, ε | h |
🎯 Exam & Interview Pitfall Check
Question 1: "Can the empty string symbol ε ever be a member of a FOLLOW set?"
Key Focus Points:
- Strict Rule: can NEVER belong to any set under any circumstances.
- Physical Meaning: represents the set of concrete terminal tokens that can physically appear after on the input tape. The empty string is an absence of characters, not a physical character on the input stream.
Question 2: "Can FIRST be computed for terminal symbols? Can FOLLOW be computed for terminal symbols?"
Key Focus Points:
- FIRST: Defined for both terminals and non-terminals: for any terminal , .
- FOLLOW: Defined strictly for non-terminals (). The mathematical concept of for a terminal is undefined in compiler syntax theory.
Trap 1: Forgetting to add $ to FOLLOW of the start symbol.
Answer: Fatal calculation bug. The input stream always ends with the end-marker $. The start symbol derives the entire sentence; therefore, $ is universally in . Forgetting $ corrupts all dependent FOLLOW sets.
Trap 2: Propagating ε into FOLLOW when applying Rule 2.
Answer: Follow sets never receive ε. When computing from , we take . If is nullable, we invoke Rule 3 and add , but itself is stripped.