7.1 Context-Free Grammars: Parse Trees, Leftmost & Rightmost Derivations
💡 Core Intuition: The Sentence Blueprint & Branching Tree
In natural language and programming languages alike, sentences are not merely linear streams of beads on a string; they possess deep nested, hierarchical structure.
Regular expressions and finite automata can count modulo a number or verify sequential prefixes, but they are powerless when syntactic structures must nest indefinitely—such as matching parentheses (( ( ) )), matching HTML tags <div><span></span></div>, or evaluating mathematical expressions with operator precedence like (3 + (4 * 5)).
To capture this recursive hierarchy, linguist Noam Chomsky introduced Context-Free Grammars (Type-2). A grammar is called context-free because any syntactic variable (non-terminal) on the left-hand side of a rule can be replaced by its right-hand expansion regardless of what symbols surround it (independent of its linguistic context).
🍳 The Everyday Analogy: The Russian Matryoshka Nesting Doll
Consider a Russian nesting doll (Matryoshka):
- You open the outer doll labeled
Doll. Inside, you find anotherDolland a small woodenToy. - You can write this rule as:
- If you repeat this replacement three times and terminate with , you get three layers of matching toys:
Toy Toy Toyfollowed byToy Toy Toy. - You do not need to inspect what is outside the doll to open the next layer. The rule applies purely from the inside out.
When you draw the parent-child relationships of how each doll revealed smaller dolls, you obtain a branching tree. The root is the largest doll, the internal branches are intermediate open dolls, and the leaves on the table are the physical toys.
💻 Bridging to Computer Science
In computer science, a Context-Free Grammar (CFG) serves as the formal architectural blueprint for programming language parsers (such as GCC, Clang, V8, and Python's AST parser):
- Lexical Tokens (Terminals ): Identifiers, numbers, keywords (
if,while), and operators (+,*). - Syntactic Categories (Variables / Non-Terminals ): Expressions, statements, blocks, function declarations.
- Production Rules (): Rewrite specifications that define valid syntactic expansion.
Every valid program is derived through a sequential rewrite process called a derivation:
- Expanding the leftmost variable at every step produces a Leftmost Derivation (LMD) (the foundation of top-down parsers like recursive descent and LL parsers).
- Expanding the rightmost variable at every step produces a Rightmost Derivation (RMD) (the reverse of bottom-up shift-reduce parsers like LR, LALR, and Yacc/Bison).
- The visual geometric representation of this derivation is the Parse Tree (Concrete Syntax Tree), where the left-to-right sequence of leaves forms the final source code string (the yield of the tree).
📑Table of Contents
🧱 The Formal Definition of a Context-Free Grammar
A Context-Free Grammar is formally defined as a 4-tuple:
The 4 Components of a Context-Free Grammar
Mathematical anatomy of the Type-2 phrase-structure grammar tuple
Variables / Non-Terminals (V)
Syntactic Categories- A finite set of placeholder symbols representing abstract syntactic structures.
- Variables can be expanded into other variables and terminals.
- Commonly denoted by uppercase letters: S, A, B, C, E, T, F.
Terminals (T)
Alphabet Symbols- A finite set of atomic, immutable symbols that form the actual language strings.
- Terminals cannot be replaced or expanded further.
- Commonly denoted by lowercase letters (a, b, c), digits (0, 1), and punctuation.
Production Rules (P)
Rewrite Mappings- A finite set of rewriting rules of the strict form: A → α.
- LHS must consist of a SINGLE non-terminal: A ∈ V.
- RHS is any finite string of variables and terminals: α ∈ (V ∪ T)*.
Start Symbol (S)
Root Variable- A distinguished non-terminal symbol from V: S ∈ V.
- All derivations in the language begin from this single starting point.
- Represents the entire program, document, or sentence.
The Defining Constraint of Type-2 Grammars
What separates a Context-Free Grammar from a Type-1 (Context-Sensitive) or Type-0 (Unrestricted) grammar is the strict structural constraint on the Left-Hand Side (LHS) of every production:
- In a Type-1 Grammar, a production has the form , where variable can only be replaced when flanked by context strings and .
- In a Type-2 CFG, there are no context strings on the LHS. Variable stands alone. Whether appears at the start of a line, inside a loop, or deeply nested in an expression, it can freely rewrite to .
🔀 Derivations & Sentential Forms
A derivation is a step-by-step sequence of production replacements that starts at the start symbol and terminates in a string composed entirely of terminals.
The Single-Step Yield Relation (⇒)
Let be a string in , where . If there exists a production rule , then we say that directly derives (or yields) :
Transitive Closure (⇒*)
- If , we say that derives in zero or more steps, denoted:
Sentential Forms vs. Sentences
- Sentential Form: Any string such that . A sentential form may contain both non-terminals and terminals.
- Sentence: A sentential form containing only terminal symbols: such that .
- Language of a Grammar : The complete set of all sentences derivable from :
A language is called a Context-Free Language (CFL) if there exists at least one Context-Free Grammar such that .
🌲 Leftmost vs. Rightmost Derivations
When a sentential form contains two or more non-terminals, the order in which we choose to expand them determines the derivation path. Two canonical derivation strategies dominate formal language theory and compiler design:
Derivation Duality: Leftmost vs Rightmost
Contrasting the expansion strategies that govern top-down and bottom-up parsing architectures
Leftmost Derivation (LMD)
- •At every single derivation step, the LEFTMOST non-terminal is chosen for replacement.
- •Generates terminal prefixes from left to right as the derivation progresses.
- •Denoted mathematically by: α ⇒_lm β.
- •Directly mirrors the execution trace of recursive-descent and LL(k) compilers.
Rightmost Derivation (RMD)
- •At every single derivation step, the RIGHTMOST non-terminal is chosen for replacement.
- •Generates terminal suffixes from right to left as the derivation progresses.
- •Denoted mathematically by: α ⇒_rm β. Also called the Canonical Derivation.
- •The reverse of an RMD forms the exact shift-reduce sequence executed by LR(k) and LALR parsers.
Concrete Walkthrough: Arithmetic Expressions
Consider the standard expression grammar :
We wish to derive the target terminal string:
Leftmost Derivation (LMD)
At every step, we underline the leftmost non-terminal and replace it:
Rightmost Derivation (RMD)
At every step, we underline the rightmost non-terminal and replace it:
Both derivations produced the exact same string , but through fundamentally different orderings of variable expansions.
🌳 Parse Trees: The Geometric Hierarchy
A Parse Tree (also known as a Derivation Tree or Concrete Syntax Tree) is an ordered, rooted, labeled tree that provides an invariant geometric representation of a derivation, filtering out the chronological order of replacement.
The Anatomical Invariants of a Parse Tree
Formal structural conditions defining a valid Type-2 derivation tree
The Start Symbol (S)
The root of the entire tree must be labeled with the grammar start symbol S ∈ V.
Syntactic Variables (Non-Terminals)
Every internal node must be a variable A ∈ V. If node A has children X₁, X₂, ..., X_k from left to right, then A → X₁ X₂ ... X_k MUST be a valid production in P.
Terminals or Epsilon (T ∪ {ε})
Every leaf node is labeled with a terminal symbol a ∈ T or the empty string ε. If a leaf is labeled ε, it must be the solitary child of its parent.
The Derived Terminal Sentence (w)
Concatenating all leaf labels from left to right yields the final string w ∈ T* generated by the parse tree.
The Master Theorem of Parse Trees
Fundamental Theorem: For any context-free grammar and any string :
- Every distinct parse tree corresponds to exactly one unique Leftmost Derivation (LMD).
- Every distinct parse tree corresponds to exactly one unique Rightmost Derivation (RMD).
- An LMD and an RMD are structurally equivalent if and only if they map to the same parse tree.
The Derivation-to-Tree Mapping Pipeline
How different derivation paths converge onto an identical parse tree geometry
LMD Sequence
Top-down prefix-first replacement order.
Canonical Parse Tree
Hierarchy of parent-child production links invariant to expansion timing.
RMD Sequence
Bottom-up canonical shift-reduce order.
🏭 Real-World Production Context: Compilers & AST Generation
In modern software engineering, raw source code strings cannot be executed directly by hardware. They must first be parsed into an Abstract Syntax Tree (AST), which is directly derived from the CFG parse tree.
Production Compiler Pipeline: From Source Code to AST
How industrial compiler frontends transform text streams into actionable execution trees
Lexer / Tokenizer
Scans raw characters via DFA and regex to emit token stream: [KEYWORD_IF, LPAREN, ID, RPAREN].
CFG Parser (Yacc / ANTLR)
Validates token stream against CFG rules via LMD (LL parser) or RMD (LR parser).
Tree Pruning & Simplification
Eliminates syntactic noise (parentheses, commas, semicolons); preserves operands and operator hierarchy.
LLVM IR / Bytecode
Traverses AST to perform type checking, register allocation, and machine code optimization.
Industrial Production Case Studies
- JavaScript V8 Engine (Google Chrome / Node.js): When JavaScript code executes, V8's parser uses an LL(k) parser to construct a concrete syntax tree from the ECMA-262 grammar specification. The parser builds a concise AST in memory, which the Ignition interpreter converts into bytecode in under a millisecond.
- TypeScript Compiler (
tsc): TypeScript specifies its formal grammar using a recursive-descent parser (pure LMD). The parser transforms source files into TypeScript AST nodes (ts.Node), allowing the type checker to traverse expressions and enforce interface contracts. - Domain-Specific Language (DSL) Parsing (Terraform & SQL):
HashiCorp's HCL (HashiCorp Configuration Language) and PostgreSQL's SQL query planner use CFG parsers (Bison / Flex) implementing LALR(1) grammars (RMD in reverse). SQL queries like
SELECT a, b FROM users WHERE id = 1are parsed into query execution plan trees using context-free derivation rules.
📐 Numerical Applications & Worked Examples
Problem 1: Systematic Derivations & Parse Tree Yield
Problem Statement:
Consider the Context-Free Grammar where:
- Productions :
Derive the string by showing:
- The complete Leftmost Derivation (LMD).
- The complete Rightmost Derivation (RMD).
- The formal yield verification of the resulting parse tree.
Step-by-Step Solution:
Step 1: Leftmost Derivation (LMD)
We systematically expand the leftmost non-terminal at every derivation step:
Let us carefully trace the target string :
- (matching 1st symbol
a) - (matching 2nd symbol
a) - (matching 3rd symbol
a) - (using , matching 4th symbol
b) - (using , matching 5th symbol
b) - (using , matching 6th symbol
a) - (using , matching 7th symbol
b) - (using , matching 8th and 9th symbols
bb) - (using , matching 9th symbol
b) - (using , matching final symbol
a)
All 10 steps replaced strictly the leftmost non-terminal. This proves .
Step 2: Rightmost Derivation (RMD)
We derive the same string by strictly replacing the rightmost non-terminal:
Step 3: Yield Verification
Counting the terminal leaves of the parse tree from left to right:
The length , and the number of terminal leaves in the parse tree is exactly 10.
Problem 2: Balanced Parentheses Language & Derivation Trees
Problem Statement:
The language of well-formed (balanced) parentheses over is generated by the CFG:
For the string :
- Construct two distinct leftmost derivations.
- Determine whether the grammar produces two distinct parse trees for .
Step-by-Step Solution:
Step 1: First Leftmost Derivation (LMD 1)
Expand using the binary split first:
Step 2: Second Leftmost Derivation (LMD 2)
Expand using the split , but decompose the right sibling:
Alternatively, using :
- In Tree 1, the root splits into , where the left child produces
()and the right child produces(). - In Tree 2, the root expands to , where the left child expands to (producing
()and ) and the right child produces().
Step 3: Conclusion
Because the string admits more than one distinct parse tree, the grammar is formally ambiguous.
Problem 3: Palindromes and Derivation Tree Depth Analysis
Problem Statement:
Consider the standard palindrome CFG over :
- Construct the parse tree for the even-length palindrome .
- Compute the exact depth of the parse tree and the total number of internal vs. leaf nodes.
Step-by-Step Solution:
Step 1: Derivation Sequence
To generate :
Step 2: Parse Tree Topology
- Level 0 (Root): Node
- Children: Leaf
1(left), Internal Node (middle), Leaf1(right).
- Children: Leaf
- Level 1 (Middle Child): Node
- Children: Leaf
0(left), Internal Node (middle), Leaf0(right).
- Children: Leaf
- Level 2 (Middle Child): Node
- Children: Single Leaf .
Step 3: Node Count & Depth Calculation
- Depth of Tree: The longest path from root to leaf is , which has 3 edges. Depth = 3.
- Internal Nodes:
- Root (Level 0)
- Middle (Level 1)
- Deepest (Level 2)
- Total internal nodes = 3.
- Leaf Nodes:
- Terminal
1(from Level 0) - Terminal
0(from Level 1) - Epsilon (from Level 2)
- Terminal
0(from Level 1) - Terminal
1(from Level 0) - Total leaf nodes = 5 ( visible terminals + empty string marker ).
- Terminal
- Total Nodes in Tree: nodes.
🎯 Exam & Interview Pitfall Check
- Does every string generated by a CFG have both an LMD and an RMD?
Yes! If a string belongs to , there exists at least one derivation tree for . By traversing that derivation tree in pre-order (visiting children left-to-right), you obtain the Leftmost Derivation. By traversing the tree visiting children right-to-left, you obtain the Rightmost Derivation. Every valid sentence has at least one LMD and at least one RMD. - If a string has two different derivations, does that mean the grammar is ambiguous?
Not necessarily! A string can have two different derivations simply because one is an LMD and the other is an RMD. That is completely normal! A grammar is ambiguous only if there are two different Leftmost derivations, or two different Rightmost derivations, or two distinct Parse Trees for the same string. - Can a CFG production have an empty string on the RHS ()?
Yes. In a context-free grammar, is a valid production (called a null or -production). However, the left-hand side must strictly be a single non-terminal (). A production like or is strictly prohibited in Type-2 grammars.
- Trap: Confusing Abstract Syntax Trees (AST) with Parse Trees (CST):
A parse tree (CST) contains every single grammar symbol, including punctuation, semicolons, and parentheses that do not hold semantic meaning. An AST discards syntax noise and retains only the operational structure (e.g. operator node+with left childaand right childb). - Trap: Assuming the Yield Includes Non-Terminals:
The yield of a parse tree is strictly the concatenation of its leaf nodes. During derivation, intermediate steps are sentential forms; but the final yield of a completed parse tree generating a sentence must consist solely of terminal symbols (and markers). - Trap: Believing LMD and RMD Can Produce Different Strings:
An LMD and RMD of the same parse tree always yield the exact same terminal string. They differ only in the chronological sequence of node expansion, not in the final sentence generated.